| Demonstrations of capable, the Linux eBPF/bcc version. | |
| capable traces calls to the kernel cap_capable() function, which does security | |
| capability checks, and prints details for each call. For example: | |
| # ./capable.py | |
| TIME UID PID COMM CAP NAME AUDIT INSETID | |
| 22:11:23 114 2676 snmpd 12 CAP_NET_ADMIN 1 N/A | |
| 22:11:23 0 6990 run 24 CAP_SYS_RESOURCE 1 N/A | |
| 22:11:23 0 7003 chmod 3 CAP_FOWNER 1 N/A | |
| 22:11:23 0 7003 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:23 0 7005 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:23 0 7005 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:23 0 7006 chown 4 CAP_FSETID 1 N/A | |
| 22:11:23 0 7006 chown 4 CAP_FSETID 1 N/A | |
| 22:11:23 0 6990 setuidgid 6 CAP_SETGID 1 N/A | |
| 22:11:23 0 6990 setuidgid 6 CAP_SETGID 1 N/A | |
| 22:11:23 0 6990 setuidgid 7 CAP_SETUID 1 N/A | |
| 22:11:24 0 7013 run 24 CAP_SYS_RESOURCE 1 N/A | |
| 22:11:24 0 7026 chmod 3 CAP_FOWNER 1 N/A | |
| 22:11:24 0 7026 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:24 0 7028 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:24 0 7028 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:24 0 7029 chown 4 CAP_FSETID 1 N/A | |
| 22:11:24 0 7029 chown 4 CAP_FSETID 1 N/A | |
| 22:11:24 0 7013 setuidgid 6 CAP_SETGID 1 N/A | |
| 22:11:24 0 7013 setuidgid 6 CAP_SETGID 1 N/A | |
| 22:11:24 0 7013 setuidgid 7 CAP_SETUID 1 N/A | |
| 22:11:25 0 7036 run 24 CAP_SYS_RESOURCE 1 N/A | |
| 22:11:25 0 7049 chmod 3 CAP_FOWNER 1 N/A | |
| 22:11:25 0 7049 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:25 0 7051 chmod 4 CAP_FSETID 1 N/A | |
| 22:11:25 0 7051 chmod 4 CAP_FSETID 1 N/A | |
| A recent kernel version >= 5.1 also reports the INSETID bit to cap_capable(): | |
| # ./capable.py | |
| TIME UID PID TID COMM CAP NAME AUDIT INSETID | |
| 08:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 | |
| 08:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 | |
| 08:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 | |
| 08:23:02 0 13036 13036 setuidgid 6 CAP_SETGID 1 0 | |
| 08:23:02 0 13036 13036 setuidgid 6 CAP_SETGID 1 0 | |
| 08:23:02 0 13036 13036 setuidgid 7 CAP_SETUID 1 1 | |
| 08:23:13 0 13085 13085 chmod 3 CAP_FOWNER 1 0 | |
| 08:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 | |
| 08:23:13 0 13085 13085 chmod 3 CAP_FOWNER 1 0 | |
| 08:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 | |
| 08:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 | |
| 08:24:27 0 13522 13522 ping 13 CAP_NET_RAW 1 0 | |
| [...] | |
| This can be useful for general debugging, and also security enforcement: | |
| determining a whitelist of capabilities an application needs. | |
| The output above includes various capability checks: snmpd checking | |
| CAP_NET_ADMIN, run checking CAP_SYS_RESOURCES, then some short-lived processes | |
| checking CAP_FOWNER, CAP_FSETID, etc. | |
| To see what each of these capabilities does, check the capabilities(7) man | |
| page and the kernel source. | |
| It is possible to include a kernel stack trace to the capable events by passing | |
| -K to the command: | |
| # ./capable.py -K | |
| TIME UID PID COMM CAP NAME AUDIT | |
| 15:32:21 1000 10708 fetchmail 7 CAP_SETUID 1 | |
| cap_capable+0x1 [kernel] | |
| ns_capable_common+0x7a [kernel] | |
| __sys_setresuid+0xc8 [kernel] | |
| do_syscall_64+0x56 [kernel] | |
| entry_SYSCALL_64_after_hwframe+0x49 [kernel] | |
| 15:32:21 1000 30047 procmail 6 CAP_SETGID 1 | |
| cap_capable+0x1 [kernel] | |
| ns_capable_common+0x7a [kernel] | |
| may_setgroups+0x2f [kernel] | |
| __x64_sys_setgroups+0x18 [kernel] | |
| do_syscall_64+0x56 [kernel] | |
| entry_SYSCALL_64_after_hwframe+0x49 [kernel] | |
| Similarly, it is possible to include user-space stack with -U (or they can be | |
| used both at the same time to include user and kernel stack). | |
| USAGE: | |
| # ./capable.py -h | |
| usage: capable.py [-h] [-v] [-p PID] [-K] [-U] | |
| Trace security capability checks | |
| optional arguments: | |
| -h, --help show this help message and exit | |
| -v, --verbose include non-audit checks | |
| -p PID, --pid PID trace this PID only | |
| -K, --kernel-stack output kernel stack trace | |
| -U, --user-stack output user stack trace | |
| examples: | |
| ./capable # trace capability checks | |
| ./capable -v # verbose: include non-audit checks | |
| ./capable -p 181 # only trace PID 181 | |
| ./capable -K # add kernel stacks to trace | |
| ./capable -U # add user-space stacks to trace |