| Demonstrations of execsnoop, the Linux eBPF/bcc version. |
| |
| |
| execsnoop traces new processes. For example, tracing the commands invoked when |
| running "man ls": |
| |
| # ./execsnoop |
| PCOMM PID RET ARGS |
| bash 15887 0 /usr/bin/man ls |
| preconv 15894 0 /usr/bin/preconv -e UTF-8 |
| man 15896 0 /usr/bin/tbl |
| man 15897 0 /usr/bin/nroff -mandoc -rLL=169n -rLT=169n -Tutf8 |
| man 15898 0 /usr/bin/pager -s |
| nroff 15900 0 /usr/bin/locale charmap |
| nroff 15901 0 /usr/bin/groff -mtty-char -Tutf8 -mandoc -rLL=169n -rLT=169n |
| groff 15902 0 /usr/bin/troff -mtty-char -mandoc -rLL=169n -rLT=169n -Tutf8 |
| groff 15903 0 /usr/bin/grotty |
| |
| The output shows the parent process/command name (PCOMM), the PID, the return |
| value of the exec() (RET), and the filename with arguments (ARGS). |
| |
| This works by traces the execve() system call (commonly used exec() variant), |
| and shows details of the arguments and return value. This catches new processes |
| that follow the fork->exec sequence, as well as processes that re-exec() |
| themselves. Some applications fork() but do not exec(), eg, for worker |
| processes, which won't be included in the execsnoop output. |
| |
| |
| The -x option can be used to include failed exec()s. For example: |
| |
| # ./execsnoop -x |
| PCOMM PID RET ARGS |
| supervise 9660 0 ./run |
| supervise 9661 0 ./run |
| mkdir 9662 0 /bin/mkdir -p ./main |
| run 9663 0 ./run |
| chown 9664 0 /bin/chown nobody:nobody ./main |
| run 9665 0 /bin/mkdir -p ./main |
| supervise 9667 0 ./run |
| run 9660 -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main |
| chown 9668 0 /bin/chown nobody:nobody ./main |
| run 9666 0 /bin/chmod 0777 main |
| run 9663 -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main |
| run 9669 0 /bin/mkdir -p ./main |
| run 9661 -2 /usr/local/bin/setuidgid nobody /command/multilog t ./main |
| supervise 9670 0 ./run |
| [...] |
| |
| This example shows various regular system daemon activity, including some |
| failures (trying to execute a /usr/local/bin/setuidgid, which I just noticed |
| doesn't exist). |
| |
| |
| A -T option can be used to include a time column, a -t option to include a |
| timestamp column, and a -n option to match on a name. Regular expressions |
| are allowed. |
| For example, matching commands containing "mount": |
| |
| # ./execsnoop -Ttn mount |
| TIME TIME(s) PCOMM PID PPID RET ARGS |
| 14:08:23 2.849 mount 18049 1045 0 /bin/mount -p |
| |
| The -l option can be used to only show command where one of the arguments |
| matches specified line. The limitation is that we are looking only into first 20 |
| arguments of the command. For example, matching all command where one of the argument |
| is "testpkg": |
| |
| # ./execsnoop.py -l testpkg |
| PCOMM PID PPID RET ARGS |
| service 3344535 4146419 0 /usr/sbin/service testpkg status |
| systemctl 3344535 4146419 0 /bin/systemctl status testpkg.service |
| yum 3344856 4146419 0 /usr/local/bin/yum remove testpkg |
| python 3344856 4146419 0 /usr/local/bin/python /usr/local/bin/yum remove testpkg |
| yum 3344856 4146419 0 /usr/bin/yum remove testpkg |
| yum 3345086 4146419 0 /usr/local/bin/yum install testpkg |
| python 3345086 4146419 0 /usr/local/bin/python /usr/local/bin/yum install testpkg |
| yum 3345086 4146419 0 /usr/bin/yum install testpkg |
| rpm 3345452 4146419 0 /bin/rpm -qa testpkg |
| |
| |
| The --cgroupmap option filters based on a cgroup set. It is meant to be used |
| with an externally created map. |
| |
| # ./execsnoop --cgroupmap /sys/fs/bpf/test01 |
| |
| For more details, see docs/special_filtering.md |
| |
| The -U option include UID on output: |
| |
| # ./execsnoop -U |
| |
| UID PCOMM PID PPID RET ARGS |
| 1000 ls 171318 133702 0 /bin/ls --color=auto |
| 1000 w 171322 133702 0 /usr/bin/w |
| |
| The -u options filters output based process UID. You also can use username as |
| argument, in that cause UID will be looked up using getpwnam (see man 3 getpwnam). |
| |
| # ./execsnoop -Uu 1000 |
| UID PCOMM PID PPID RET ARGS |
| 1000 ls 171335 133702 0 /bin/ls --color=auto |
| 1000 man 171340 133702 0 /usr/bin/man getpwnam |
| 1000 bzip2 171341 171340 0 /bin/bzip2 -dc |
| 1000 bzip2 171342 171340 0 /bin/bzip2 -dc |
| 1000 bzip2 171345 171340 0 /bin/bzip2 -dc |
| 1000 manpager 171355 171340 0 /usr/bin/manpager |
| 1000 less 171355 171340 0 /usr/bin/less |
| |
| USAGE message: |
| |
| # ./execsnoop -h |
| usage: execsnoop.py [-h] [-T] [-t] [-x] [--cgroupmap CGROUPMAP] |
| [--mntnsmap MNTNSMAP] [-u USER] [-q] [-n NAME] [-l LINE] |
| [-U] [--max-args MAX_ARGS] [-P PPID] |
| |
| Trace exec() syscalls |
| |
| optional arguments: |
| -h, --help show this help message and exit |
| -T, --time include time column on output (HH:MM:SS) |
| -t, --timestamp include timestamp on output |
| -x, --fails include failed exec()s |
| --cgroupmap CGROUPMAP |
| trace cgroups in this BPF map only |
| --mntnsmap MNTNSMAP trace mount namespaces in this BPF map only |
| -u USER, --uid USER trace this UID only |
| -q, --quote Add quotemarks (") around arguments. |
| -n NAME, --name NAME only print commands matching this name (regex), any |
| arg |
| -l LINE, --line LINE only print commands where arg contains this line |
| (regex) |
| -U, --print-uid print UID column |
| --max-args MAX_ARGS maximum number of arguments parsed and displayed, |
| defaults to 20 |
| -P PPID, --ppid PPID trace this parent PID only |
| |
| examples: |
| ./execsnoop # trace all exec() syscalls |
| ./execsnoop -x # include failed exec()s |
| ./execsnoop -T # include time (HH:MM:SS) |
| ./execsnoop -P 181 # only trace new processes whose parent PID is 181 |
| ./execsnoop -U # include UID |
| ./execsnoop -u 1000 # only trace UID 1000 |
| ./execsnoop -u user # get user UID and trace only them |
| ./execsnoop -t # include timestamps |
| ./execsnoop -q # add "quotemarks" around arguments |
| ./execsnoop -n main # only print command lines containing "main" |
| ./execsnoop -l tpkg # only print command where arguments contains "tpkg" |
| ./execsnoop --cgroupmap mappath # only trace cgroups in this BPF map |
| ./execsnoop --mntnsmap mappath # only trace mount namespaces in the map |