15

If I:

[user@notebook ~] sudo echo 123456uu
123456uu
[user@notebook ~] 

Then I can see that in the logs:

[root@notebook /var/log] grep 123456uu *
auth.log:Jan  9 17:01:51 notebook sudo: user : TTY=pts/3 ; PWD=/home/user ; USER=root ; COMMAND=/bin/echo 123456uu
[root@notebook /var/log] 

but if I:

[user@notebook ~] sudo su -
[root@notebook ~] echo 1234567zz
1234567zz
[root@notebook ~] 

I cannot see it in the logs:

[root@notebook /var/log] grep 1234567zz *
[root@notebook /var/log] echo $?
1
[root@notebook /var/log] 

My question: How can I turn the logging on for the commands within the "sudo su -"?

OS is an Ubuntu 12.04 but the question is in general.

UPDATE#1:

[user@notebook ~] sudo su -
[sudo] password for user: 
[root@notebook ~] echo zizizi
zizizi
[root@notebook ~] cd /var/log
[root@notebook /var/log] grep -iIR 'zizizi' *
[root@notebook /var/log] grep 'COMMAND=/bin/su -' *
auth.log:Jan 10 15:42:42 notebook sudo: user : TTY=pts/1 ; PWD=/home/user ; USER=root ; COMMAND=/bin/su -
[root@notebook /var/log]
  • 1
    If someone malicious (or even just untrustworthy) has access to sudo su -, they also have the ability to remove all the log entries you could make of their actions. If you want 100% certainty in your logging, you need to restrict sudo heavily and disallow sudo su entirely. – Wildcard Apr 09 '16 at 00:05

11 Answers11

21

Since you are on Ubuntu 12.04, have a look at the I/O logging abilities activated via the log_input and log_output options.

log_input

    If set, sudo will run the command in a pseudo tty and log all user input. If the standard input is not connected to the user's tty, due to I/O redirection or because the command is part of a pipeline, that input is also captured and stored in a separate log file.

    Input is logged to the directory specified by the iolog_dir option (/var/log/sudo-io by default) using a unique session ID that is included in the normal sudo log line, prefixed with TSID=. The iolog_file option may be used to control the format of the session ID.

    Note that user input may contain sensitive information such as passwords (even if they are not echoed to the screen), which will be stored in the log file unencrypted. In most cases, logging the command output via log_output is all that is required.

log_output

    If set, sudo will run the command in a pseudo tty and log all output that is sent to the screen, similar to the script(1) command. If the standard output or standard error is not connected to the user's tty, due to I/O redirection or because the command is part of a pipeline, that output is also captured and stored in separate log files.

    Output is logged to the directory specified by the iolog_dir option (/var/log/sudo-io by default) using a unique session ID that is included in the normal sudo log line, prefixed with TSID=. The iolog_file option may be used to control the format of the session ID.

    Output logs may be viewed with the sudoreplay(8) utility, which can also be used to list or search the available logs.

IMPLEMENTATION: Sudo version at least: 1.7.4p4 needed.

/etc/sudoers modifcation: All you need to do is to add two tags to all required sudoers entries (where "su" specified, either with command or alias). LOG_INPUT and LOG_OUTPUT.

Example:

%admins         ALL=(ALL) NOPASSWD: LOG_INPUT: LOG_OUTPUT: ALL

Add the following default log dir structure to sudoers:

Defaults iolog_dir=/var/log/sudo-io/%{user}
Mark Wagner
  • 1,911
13

Your grep when doing sudo su - fails because you're not running echo 1234567zz, you're running su -, which launches a shell. The shell is then running your echo.

This is deliberate, and logging every single command run would flood your syslog with useless info (there are usually tons of programs that get run behind the scenes that you don't normally see).

If you change your grep to grep 'COMMAND=/bin/su -' * you'll see it.


sudo su - is also a useless use of su. sudo -i does the same thing.

phemmer
  • 71,831
  • but how can I log the "sudo su -"? – newuser999 Jan 09 '14 at 18:12
  • 1
    It is logged. Did you try the grep 'COMMAND=/bin/su -' * (or without wildcard: grep 'COMMAND=/bin/su -' /var/log/auth.log)? – phemmer Jan 09 '14 at 19:40
  • I updated the question. what else do I have to prove that when using "sudo su -" the commands aren't logged?? – newuser999 Jan 10 '14 at 14:45
  • 4
    The command (sudo -) is logged, and your updated output shows this. That's all we are talking about here. The other commands, such as the echo after you switch users with sudo -, are not sudo commands, and hence (as per my answer) are not logged in auth.log. Only individual commands explicitly prefaced with sudo will be logged. So sudo echo is logged, but just plain echo is not, regardless of the fact that you have switched to the superuser. – goldilocks Jan 10 '14 at 15:20
13

In increasing complexity, here's three ways of logging the commands issued within the "sudo su -":

  1. Rely on bash command history
  2. Install an execve logging wrapper
  3. Use SELinux's auditd

As to which is suitable, it really depends on what you're trying to accomplish with the logging.

1) Bash Command History

You would want to configure the history facitlity to ensure keeping sufficient lines, not overwriting from different sessions, not ignoring commands, and appropriate timestamps. (See HIST* variables in the bash manual). Easily subverted by editing the history file, manipulating environment or running another shell.

2) execve wrapper

Snoopy Logger is one. Add a check in /etc/profile that the logger library is in the process's memory map (/proc/<pid>/maps), and if not, set LD_PRELOAD and restart (with exec $SHELL --login "$@"). Alternately you may add an entry to /etc/ld.so.preload with $LIB/snoopy.so or equivalent path(s) to your 32/64-bit versions of snoopy.so.

Though more difficult, the LD_PRELOAD environment variable version of the above could still be subverted by manipulating execution environment so that the snoopy code no longer runs.

Syslog should be sent off-box for contents to be trustworthy.

3) auditd

Slightly more straightforward to configure than the execve wrapper, but harder to extract the information from. This is the answer the question you're likely really asking: "Is there a way to log what effect the user has had on a system after they issue sudo su -". Syslog should be sent off-box for contents to be trustworthy.

This Serverfault answer appears to be a fairly comprehensive configuration for use with auditd.

There are some other suggestions to a similar question on serverfault.

R Perrin
  • 3,049
  • 20
  • 11
10

Why?

Because it's sudo that is doing the logging; it logs sudo commmands. In the first case, sudo echo is logged. In the second case, sudo su is logged (look for it in /var/log/auth.log).

su is "switch user", by default to root. Anything you do after that does not pass through sudo. It is the much the same as if you'd logged in as root; the login itself is logged, but not each and every command.

goldilocks
  • 87,661
  • 30
  • 204
  • 262
7

As others have said, sudo can't do this.

Instead, use auditd. If you want to log everything done by root (including e.g. things done by crontab), use this:

sudo auditctl -a exit,always -F euid=0

ETA: Note that logging everything will impact performance, so you'll probably want to limit it a bit. See man auditctl for examples.

If you only want to log syscalls where the original login uid is not root, use this instead:

sudo auditctl -a exit,always -F euid=0 -F auid!=0

The logs will usually end up in /var/log/audit/audit.log. You can search them with ausearch.

There's more information in the man pages for auditctl, audit.rules and ausearch.

Jenny D
  • 13,172
  • 2
    Oh, in order for the audit logs to be trusted, they should be sent to a separate server. Any logs residing on the machine where an untrusted user has root can't be trusted. – Jenny D Jan 15 '14 at 09:51
  • even then you can't trust what does or doesn't come out of a compromised server. – Matt Jan 15 '14 at 10:12
  • But you will have a trace up until the time that it's compromised. – Jenny D Jan 15 '14 at 10:13
  • 2
    Which in op's case is technically as soon as they have run sudo su - so you're back at square one – Matt Jan 15 '14 at 10:29
  • Untrusted is not the same as compromised. It doesn't get compromised until they actually do something nefarious, in which cse the audit log on the remote server will show you what was done and by whom - including who it was that disabled auditd. And even apart from that, a remote log will help when someone's deleted the local log by mistake or to protect themselves from blame for a mistake. – Jenny D Jan 15 '14 at 10:33
  • using the first auditctl command slows down the root terminal as hell, any ideas :D – newuser999 Jan 15 '14 at 11:50
  • That's because every syscall in every program run by root will be logged by auditd. man auditctl, man syscall should help you figure out what syscalls you do want to log. – Jenny D Jan 15 '14 at 12:02
  • I'm not saying remote logging is bad, just pointing out that you can't expect something with root access to be audited. – Matt Jan 16 '14 at 08:07
2

sudo su - will be in ~/.bash_history if your shell is bash.

echo 1234567zz will be in /root/.bash_history if root's shell is bash.

Explanation of this was already posted by goldilocks.

YoMismo
  • 4,015
2

Do you you want su to log because you feel it is a security flaw ? Have you thought about this command ? sudo bash just as bad imho.

If you are worried about what people can do with sudo, then you will need to restrict it's use. You can restrict the commands they can execute too. Restrict access to /bin/su if it worries you.

X Tian
  • 10,463
1

What about this:

export HISTTIMEFORMAT="%d/%m/%y %T "
export PROMPT_COMMAND='builtin history 1 >> /var/log/sudo.log'
sudo -E su
unset PROMPT_COMMAND

or

export HISTTIMEFORMAT="%d/%m/%y %T "
export PROMPT_COMMAND='builtin history 1 >> /var/log/sudo.log' 
sudo -E su --preserve-environment -
unset PROMPT_COMMAND

or long one-liner:

HISTTIMEFORMAT="%d/%m/%y %T " PROMPT_COMMAND='builtin history 1 >> /var/log/sudo.log' sudo -E su

sudo -E preserves environment PROMPT_COMMAND is executed before each prompt

Costa
  • 552
  • the first one doesn't gives me a console AND if I put the second one in /root/.bashrc then I have to hit CTRL+C if I want to get the root console after a "sudo su -" :D any chances to fix this (or to add "date" function to it?). Many Thanks! – newuser999 Jan 16 '14 at 09:49
  • I afraid you misused it. Edited it to make more explicit. – Costa Jan 16 '14 at 13:25
1

If this helps, you can use "NOEXEC" option of sudoers.

You need to define it as

USER_NAME         ALL=(ALL) NOEXEC : ALL

This will prevent shell escapes and user won't be able to use sudo -i or sudo -s or sudo su -

This comes with a downside, however, Any shell escape will be disabled. for ex- executing script from within a script will also be denied.

Archemar
  • 31,554
ankidaemon
  • 1,571
  • 1
  • 11
  • 8
0

Let's not make this complicated: Whenever sudo is called, it reports this fact in some file in /var/log (on your system is auth.log, on my OS X box it's system.log). sudo reports its commandline arguments, but it has no knowledge of what might happen inside an interactive command like su.

This doesn't mean there's no record of what happens in a root subshell: Shell commands are saved in the shell's history. On my system, root's history saving is enabled by default, so all I'd have to do is look in ~root/.sh_history for a record of what was done (unless someone tampered with it, of course, but they could equally well tamper with /var/log).

I think this is the best solution for you. If not, go to town with auditd, as @Jenny suggested.

PS. If root's history is not already enabled, enabling it depends on which shell it uses. For bash, set HISTORY and HISTFILESIZE to a large enough number (default is 500, my manual says). If you wish you can specify where the history is saved by setting HISTFILE to a path (default $HOME/.sh_history)

alexis
  • 5,759
0

You might want to create a typescript of your session using script(1):

$ sudo su -
# script -t /tmp/my_typescript 2> /tmp/my_typescript.timing
Script started, file is /tmp/my_typescript
# echo foobar
foobar
# echo hello world
hello world
# exit
exit
Script done, file is /tmp/my_typescript

Now you can grep (note that the # prompts are actually recorded in /tmp/my_typescript):

$ grep echo /tmp/my_typescript
# echo foobar
# echo hello world

Alternatively, you can even watch the whole session again with scriptreplay(1):

$ scriptreplay -t /tmp/my_typescript.timing /tmp/my_typescript

The file /tmp/my_typescript.timing contains information when each command has been invoked. There are further tools like ttyrec or shelr that have even more bells and whistles.

tkrennwa
  • 3,525
  • 1
  • 15
  • 17