1Demonstrations of capable, the Linux eBPF/bcc version. 2 3 4capable traces calls to the kernel cap_capable() function, which does security 5capability checks, and prints details for each call. For example: 6 7# ./capable.py 8TIME UID PID COMM CAP NAME AUDIT 922:11:23 114 2676 snmpd 12 CAP_NET_ADMIN 1 1022:11:23 0 6990 run 24 CAP_SYS_RESOURCE 1 1122:11:23 0 7003 chmod 3 CAP_FOWNER 1 1222:11:23 0 7003 chmod 4 CAP_FSETID 1 1322:11:23 0 7005 chmod 4 CAP_FSETID 1 1422:11:23 0 7005 chmod 4 CAP_FSETID 1 1522:11:23 0 7006 chown 4 CAP_FSETID 1 1622:11:23 0 7006 chown 4 CAP_FSETID 1 1722:11:23 0 6990 setuidgid 6 CAP_SETGID 1 1822:11:23 0 6990 setuidgid 6 CAP_SETGID 1 1922:11:23 0 6990 setuidgid 7 CAP_SETUID 1 2022:11:24 0 7013 run 24 CAP_SYS_RESOURCE 1 2122:11:24 0 7026 chmod 3 CAP_FOWNER 1 2222:11:24 0 7026 chmod 4 CAP_FSETID 1 2322:11:24 0 7028 chmod 4 CAP_FSETID 1 2422:11:24 0 7028 chmod 4 CAP_FSETID 1 2522:11:24 0 7029 chown 4 CAP_FSETID 1 2622:11:24 0 7029 chown 4 CAP_FSETID 1 2722:11:24 0 7013 setuidgid 6 CAP_SETGID 1 2822:11:24 0 7013 setuidgid 6 CAP_SETGID 1 2922:11:24 0 7013 setuidgid 7 CAP_SETUID 1 3022:11:25 0 7036 run 24 CAP_SYS_RESOURCE 1 3122:11:25 0 7049 chmod 3 CAP_FOWNER 1 3222:11:25 0 7049 chmod 4 CAP_FSETID 1 3322:11:25 0 7051 chmod 4 CAP_FSETID 1 3422:11:25 0 7051 chmod 4 CAP_FSETID 1 35 36Checks where AUDIT is 0 are ignored by default, which can be changed 37with -v but is more verbose. 38 39We can show the TID and INSETID columns with -x. 40Since only a recent kernel version >= 5.1 reports the INSETID bit to cap_capable(), 41the fallback value "N/A" will be displayed on older kernels. 42 43# ./capable.py -x 44TIME UID PID TID COMM CAP NAME AUDIT INSETID 4508:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 4608:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 4708:22:36 0 12869 12869 chown 0 CAP_CHOWN 1 0 4808:23:02 0 13036 13036 setuidgid 6 CAP_SETGID 1 0 4908:23:02 0 13036 13036 setuidgid 6 CAP_SETGID 1 0 5008:23:02 0 13036 13036 setuidgid 7 CAP_SETUID 1 1 5108:23:13 0 13085 13085 chmod 3 CAP_FOWNER 1 0 5208:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 5308:23:13 0 13085 13085 chmod 3 CAP_FOWNER 1 0 5408:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 5508:23:13 0 13085 13085 chmod 4 CAP_FSETID 1 0 5608:24:27 0 13522 13522 ping 13 CAP_NET_RAW 1 0 57[...] 58 59This can be useful for general debugging, and also security enforcement: 60determining a whitelist of capabilities an application needs. 61 62The output above includes various capability checks: snmpd checking 63CAP_NET_ADMIN, run checking CAP_SYS_RESOURCES, then some short-lived processes 64checking CAP_FOWNER, CAP_FSETID, etc. 65 66To see what each of these capabilities does, check the capabilities(7) man 67page and the kernel source. 68 69It is possible to include a kernel stack trace to the capable events by passing 70-K to the command: 71 72# ./capable.py -K 73TIME UID PID COMM CAP NAME AUDIT 7415:32:21 1000 10708 fetchmail 7 CAP_SETUID 1 75 cap_capable+0x1 [kernel] 76 ns_capable_common+0x7a [kernel] 77 __sys_setresuid+0xc8 [kernel] 78 do_syscall_64+0x56 [kernel] 79 entry_SYSCALL_64_after_hwframe+0x49 [kernel] 8015:32:21 1000 30047 procmail 6 CAP_SETGID 1 81 cap_capable+0x1 [kernel] 82 ns_capable_common+0x7a [kernel] 83 may_setgroups+0x2f [kernel] 84 __x64_sys_setgroups+0x18 [kernel] 85 do_syscall_64+0x56 [kernel] 86 entry_SYSCALL_64_after_hwframe+0x49 [kernel] 87 88Similarly, it is possible to include user-space stack with -U (or they can be 89used both at the same time to include user and kernel stack). 90 91Some processes can do a lot of security capability checks, generating a lot of 92ouput. In this case, the --unique option is useful to only print once the same 93set of capability, pid (or cgroup if --cgroupmap is used) and kernel/user 94stacks (if -K or -U are used). 95 96# ./capable.py -K -U --unique 97 98The --cgroupmap option filters based on a cgroup set. It is meant to be used 99with an externally created map. 100 101# ./capable.py --cgroupmap /sys/fs/bpf/test01 102 103For more details, see docs/special_filtering.md 104 105 106USAGE: 107 108# ./capable.py -h 109usage: capable.py [-h] [-v] [-p PID] [-K] [-U] [-x] [--cgroupmap CGROUPMAP] 110 [--mntnsmap MNTNSMAP] [--unique] 111 112Trace security capability checks 113 114optional arguments: 115 -h, --help show this help message and exit 116 -v, --verbose include non-audit checks 117 -p PID, --pid PID trace this PID only 118 -K, --kernel-stack output kernel stack trace 119 -U, --user-stack output user stack trace 120 -x, --extra show extra fields in TID and INSETID columns 121 --cgroupmap CGROUPMAP 122 trace cgroups in this BPF map only 123 --mntnsmap MNTNSMAP trace mount namespaces in this BPF map only 124 --unique don't repeat stacks for the same pid or cgroup 125 126examples: 127 ./capable # trace capability checks 128 ./capable -v # verbose: include non-audit checks 129 ./capable -p 181 # only trace PID 181 130 ./capable -K # add kernel stacks to trace 131 ./capable -U # add user-space stacks to trace 132 ./capable -x # extra fields: show TID and INSETID columns 133 ./capable --unique # don't repeat stacks for the same pid or cgroup 134 ./capable --cgroupmap mappath # only trace cgroups in this BPF map 135 ./capable --mntnsmap mappath # only trace mount namespaces in the map 136