-1

I need to logging all terminal commands in Linux. I have found correctly working library in C, but it works only when I run LD_PRELOAD=/usr/local/bin/bashpreload.so /bin/bash:

# ldd /bin/bash
    linux-vdso.so.1 =>  (0x00007ffef59f8000)
    /usr/local/bin/bashpreload.so (0x00007fe691323000)
    libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fe691102000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fe690efe000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fe690b6a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe691524000)

If I log in again in the system after this, I will not see the lib with ldd:

[root@XXX ~]# LD_PRELOAD=/usr/local/bin/bashpreload.so /bin/bash
[root@XXX ~]# ldd /bin/bash
    linux-vdso.so.1 =>  (0x00007ffe481f6000)
    /usr/local/bin/bashpreload.so (0x00007f3f1b808000)
    libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f3f1b5e7000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f3f1b3e3000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f3f1b04f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3f1ba09000)
[root@XXX ~]# exit
[root@XXX ~]# logout
Connection to XXX closed.
[sahaquiel@sahaquiel-PC ~]$ ssh root@XXX
root@XXX's password: 
Last login: Tue Dec 19 11:28:22 2017 from YYY
[root@XXX ~]# ldd /bin/bash
    linux-vdso.so.1 =>  (0x00007ffca2f98000)
    libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f19a13ff000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f19a11fb000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f19a0e67000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f19a1620000)

And one more trouble: if I use this library, my current PID is changing:

Last login: Tue Dec 19 11:28:54 2017 from YYY
[root@XXX ~]# echo "Library is not uploaded"
Library is not uploaded
[root@XXX ~]# echo $$
4639
[root@XXX ~]# LD_PRELOAD=/usr/local/bin/bashpreload.so /bin/bash
[root@XXX ~]# echo $$
4654
[root@212-24-57-104 ~]# ps awwufx | grep -B5 [4]654
root      1706  0.0  0.0  66256  1192 ?        Ss   10:54   0:00 /usr/sbin/sshd
root      4517  0.0  0.0 104636  4644 ?        Ss   11:27   0:00  \_ sshd: root@pts/1 
root      4519  0.0  0.0 108320  1872 pts/1    Ss+  11:27   0:00  |   \_ -bash
root      4637  0.0  0.0 104636  4624 ?        Ss   11:30   0:00  \_ sshd: root@pts/0 
root      4639  0.0  0.0 108320  1872 pts/0    Ss   11:30   0:00  |   \_ -bash
root      4654  0.0  0.0 110376  1956 pts/0    S    11:31   0:00  |       \_ /bin/bash

So, I need two things:

  1. Find the way to do LD_PRELOAD quietly for each logging in user;
  2. Know why after this I'm working in the child /bin/bash process.

Thanks!

Pavel
  • 7,436
  • 2
  • 29
  • 42
Viktor Khilin
  • 1,760
  • 9
  • 21
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. – jww Dec 19 '17 at 13:38

3 Answers3

2

This is a classic XY problem. You need to log user actions, have decided on a solution, and are asking questions about that solution.

Even though the solution won't work.

Because using an LD_PRELOAD library is not a reliable way to log user commands.

  1. The user can just unset the LD_PRELOAD environment variable. And no, marking it readonly doesn't work. Because it's just a variable in the memory of a process the user controls.
  2. You're setting LD_PRELOAD to a 64-bit shared object. Every 32-bit program will now fail to run.
  3. However your preloaded library logs data, it does so with the user's permissions/access rights. Thus the user can spoof the data recorded.

If you need to log user's actions, use a system designed to do that securely: auditing.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Auditing not the best solution for my case, I'm exploring alternatives today. Thanks for your advice, the reason 32-bit programs will fail is critical for me. – Viktor Khilin Dec 19 '17 at 12:37
  • "You're setting LD_PRELOAD to a 64-bit shared object. Every 32-bit program will now fail to run" is not true. If the ELF class is different, it'll be simply ignored; nothing untoward will happen except for a diagnostic message and 32-bit programs will still run fine. – P.P Jan 02 '18 at 11:30
  • @usr *If the ELF class is different, it'll be simply ignored* **WRONG**. Try `file /usr/bin/bash`. You'll see `/usr/bin/bash: ELF 64-bit LSB...`. Then `export LD_PRELOAD=/lib/libc.so`, a **32-bit** shared object. After that, enter `/usr/bin/bash` to try running another copy of `bash`. You get `ld.so.1: bash: fatal: wrong ELF class: ELFCLASS32` as the 32-bit shared object specified to be loaded by `LD_PRELOAD` is wrong. – Andrew Henle Jan 04 '18 at 14:39
  • @AndrewHenle Using a 32-bit library as you said produces "ERROR: ld.so: object '/lib/i386-linux-gnu/libc.so.6' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.". Like I said it's ignored (/lib/i386-linux-gnu/libc.so.6 is the 32-bit libc on my system). – P.P Jan 04 '18 at 14:59
1
  1. Find the way to do LD_PRELOAD quietly for each logging in user

You need to set somewhere common for all users such as /etc/profile or /etc/environment. See How to set environment variable for everyone under my linux system? for more options/details.

  1. Know why after this I'm working in the child /bin/bash process.

That's straight-forward - whenever you create a process, its PID is different from its parent :) When you run /bin/bash, you obviously creates another shell and that's why $$ is different. This has nothing to do with LD_PRELOAD. If you run /bin/bash without LD_PRELOAD, you'll observe exactly the same behaviour.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • Thanks, I still don't understand clearly how LD_PRELOAD works, have to read more. Solution with /etc/profile sounds good, but can you explain me, how can execute library adding in shell-script? adding `LD_PRELOAD /usr/local/bin/mylib.so /bin/bash` will be enough? UPD. It doesn't work :( I can't use `export`, because I need this lib only for /bin/bash – Viktor Khilin Dec 19 '17 at 09:46
  • `LD_PRELOAD=/usr/local/bin/bashpreload.so` is how you'd set in /etc/profile. But be very careful - depending on what the LD_PRELOAD library does, this may affect users seriously and is possibly a security vulnerability. See https://unix.stackexchange.com/q/117467/192153 for shell specific options. If you want it only for bash you can look at `bashrc` file. – P.P Dec 19 '17 at 09:58
0

If someone will needs the same as me: You can add environment variable before user log in via SSH in /etc/security/pam_env.conf, syntax like:

LD_PRELOAD     DEFAULT=        OVERRIDE="/usr/local/bin/bashpreload.so"
Viktor Khilin
  • 1,760
  • 9
  • 21