2

I want to monitor systemcalls with bpftrace (https://github.com/iovisor/bpftrace/). For most systemcalls, this works without problems, but I have problems to monitor applications, where the suid bit is set.

Folowing syscalls are monitored (https://github.com/iovisor/bpftrace/blob/master/tools/setuids.bt):

  • setuid
  • setfsuid
  • setreuid
  • setresuid

For testing purposes, a copy of the sleep command is used.

$ cp /bin/sleep ~ $ sudo chown root ~/sleep $ sudo chmod +s ~/sleep 

btftrace is started with following command:

$ sudo ./bpftrace setuids.bt 

After the start of btftrace the custom sleep command is started.

$ ./sleep 1337 

I expected, that btftrace should print an information about the started process, but nothing was captured.

ps is used to verify, if the process is running with root-privileges:

$ ps aux | grep sleep root 5552 0.0 0.0 16872 1012 pts/2 S+ 10:18 0:00 ./sleep 1337 

To check if bpftrace captures the mentioned syscalls, su was started to switch to a different user:

$ su testuser 

This was captured by bpftrace and to process id and additional information is shown:

$ sudo ./bpftrace setuids.bt Attaching 7 probes... Tracing setuid(2) family syscalls. Hit Ctrl-C to end. TIME PID COMM UID SYSCALL ARGS (RET) 10:23:15 5661 su 1000 setuid uid=1001 (0) 

Why is this not detected by monitoring the mentioned syscalls?

    1 Answer 1

    3

    The tracepoints from bpftrace only captures syscalls but does not capture other functions, which are executed inside the Linux kernel.

    This is an important difference, because the suid bit is interpreted when executing the execve systemcall. execve does not use the setuid(2) family syscalls to set the userids for the process. The function, where the suid bit is interpreted can be found in exec.c in the kernel sources: https://github.com/torvalds/linux/blob/38f8ccde04a3fa317b51b05e63c3cb57e1641931/fs/exec.c#L1596

    bpftrace only supports the uid in handlers, but not euid, ruid, and fuid. When executing applications, where the suid bit is set, the uid is the same as the user, who started the application. euid, ruid and fuid are changed to the owner of the file.

    This can be verified by going to the process information in /proc/{pid}/status .

    There is a line, which starts with Uid:

    Uid: 1000 0 0 0 

    The columns are defined as uid´, euid, ruidandfuid`. This information can be found in: http://lxr.linux.no/#linux+v2.6.37/fs/proc/array.c#L186

    With bpftrace it's not possible to monitor applications where the suid bit is set, but in combination with python (or another scripting language) the information can be combined with the information from the `/proc/ filesystem.

    Example python script to monitor seuid bit applications:

    Following bpftrace-script, which prints the command name and the pid is used. This is stored as monitor.bt.

    tracepoint:syscalls:sys_exit_exec* { printf("%s;%d\n", comm, pid); } 

    Following python script executes bpftrace and reads the captured information from stdout:

    import os import subprocess import signal def get_resuid(pid): '''Return username of UID of process pid''' pid_path = '/proc/{}/status'.format(pid) if os.path.isfile(pid_path): for ln in open(pid_path): if ln.startswith('Uid:'): return [int(x) for x in ln.split()[1:5]] return None proc = subprocess.Popen( [ '/home/manfred/bin/bpftrace', '-q', '/home/manfred/monitor.bt' ], stdout=subprocess.PIPE ) while True: line = proc.stdout.readline() if not line: break comm, pid = line.decode().strip("\n").rsplit(";", maxsplit=1) pid = int(pid) uids = get_resuid(pid) if uids: print("{} -> {}".format(comm, uids)) 

    The bpfscript monitors the execution of new application which are started with execve and prints the pid. This pid is used to get the uid, euid, ... from the proc filesystem and prints this information to stdout.

    This will look like:

    sleep -> [1000, 0, 0, 0] 

    The columns are specified as uid, euid, ruid and fuid.

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.