tetragon
109 строк · 4.0 Кб
1# In this demo we will show hot to capture a change in capabilities with FGS.
2# A change in capabilities can be done in 2 ways: (1) The normal path in Linux
3# kernel using the approriate system calls and (2) via an exploit.
4#
5# In this demo we will show the first way. As the easy path is to remove
6# capabilities (instead of adding) we will start a process with CAP_SETUID
7# enabled, we will remove that during the execution and then we will capture
8# this change using the following CRD.
9#
10# ** Preparation **
11# We will add CAP_SETUID to the python executable. Next, from a python program we
12# will remove that.
13# Commands:
14# $ getcap -r /usr/bin/ 2> /dev/null | grep python3 # check the capabilities of python3 binary
15# $ which python3 # check the executable path
16# /usr/bin/python3
17# $ ls -la /usr/bin/python3 # check if the executable path is a symlink as we cannot apply capabilities in symlinks
18# lrwxrwxrwx 1 root root 9 Mar 13 2020 /usr/bin/python3 -> python3.8
19# $ sudo setcap 'cap_setuid+ep' /usr/bin/python3.8 # add CAP_SETUID in effective and permitted sets of caps for python3.8 binary
20# $ getcap -r /usr/bin/ 2> /dev/null | grep python3 # check the capabilities of python3 binary
21# /usr/bin/python3.8 = cap_setuid+ep
22# $ sudo apt-get install -y python3-prctl # we will need this packet to change the caps from python3
23#
24# ** Execution **
25# We will use 2 terminals. Terminal 1 will run FGS and terminal 2 the demo
26# code. First thing is replace {{.Pid}} in this CRD with the PID of terminal 2.
27#
28# In terminal 1:
29# $ sudo ./tetragon --btf /sys/kernel/btf/vmlinux --bpf-lib ./bpf/objs/ --export-filename events.json --tracing-policy examples/tracingpolicy/match_capability_changes.yaml --enable-process-cred
30# $ # <wait for events> (i.e. run the commands in terminal 2)
31# $ # kill tetragon
32# $ grep kprobe events.json | grep \"__x64_sys_write\" | grep strange | jq . # get the write kprobe events
33#
34# In terminal 2:
35# $ /usr/bin/python3.8 -c "import os; import prctl; f = open('./strange.txt', 'w'); prctl.cap_effective.setuid = False; f.write('testdata'); f.close();"
36#
37# Because of the transition from having CAP_SETUID to removing CAP_SETUID, we will
38# see a single kprobe event that does not contain CAP_SETUID in the effective
39# set of its caps. On the other hand, it will contain CAP_SETUID in the permitted
40# set of its caps. Initially we added CAP_SETUID both in effective and permitted
41# sets of caps. In our python program we removed CAP_SETUID only for effective set
42# of caps. We can check the appropriate process_exec event thta we had CAP_SETUID
43# at the beginning.
44#
45# ** Cleanup **
46# We have to remove CAP_SETUID from python executable.
47# $ sudo setcap -r /usr/bin/python3.8 # remove all capabilities from python
48# $ getcap -r /usr/bin/ 2> /dev/null | grep python3 # check the capabilities of python3 binary
49#
50# This CRD will also capture the changes when we enable a capability.
51#
52apiVersion: cilium.io/v1alpha153kind: TracingPolicy54metadata:55name: "fd-install"56spec:57kprobes:58- call: "fd_install"59syscall: false60return: false61args:62- index: 063type: int64- index: 165type: "file"66selectors:67- matchPIDs:68- operator: In69followForks: true70isNamespacePID: false71values:72- {{.Pid}}73matchArgs:74- index: 175operator: "Postfix"76values:77- "strange.txt"78matchActions:79- action: FollowFD80argFd: 081argName: 182- call: "sys_write"83syscall: true84args:85- index: 086type: "fd"87- index: 188type: "char_buf"89returnCopy: true90- index: 291type: "size_t"92selectors:93- matchPIDs:94- operator: In95followForks: true96isNamespacePID: false97values:98- {{.Pid}}99matchCapabilityChanges:100- type: Effective101operator: In102isNamespaceCapability: false103values:104- "CAP_SETUID"105matchArgs:106- index: 0107operator: "Postfix"108values:109- "strange.txt"110