diff options
author | VG <vg@devys.org> | 2016-02-25 00:08:03 +0100 |
---|---|---|
committer | VG <vg@devys.org> | 2016-02-25 00:08:03 +0100 |
commit | 06bec13226e2eb8c7bcfeaea2bd22b63fe5f1dd8 (patch) | |
tree | 41b0fadf46acde60d2e5e73717a58f2c95856f5e | |
download | runwithcaps-06bec13226e2eb8c7bcfeaea2bd22b63fe5f1dd8.tar.gz runwithcaps-06bec13226e2eb8c7bcfeaea2bd22b63fe5f1dd8.tar.bz2 runwithcaps-06bec13226e2eb8c7bcfeaea2bd22b63fe5f1dd8.zip |
first commit
-rwxr-xr-x | run_with_only_cap_net_bind_service.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/run_with_only_cap_net_bind_service.py b/run_with_only_cap_net_bind_service.py new file mode 100755 index 0000000..9b4d6cc --- /dev/null +++ b/run_with_only_cap_net_bind_service.py @@ -0,0 +1,135 @@ +#!/usr/bin/python3 + +# resources for cffi: +# http://eli.thegreenplace.net/2013/03/09/python-ffi-with-ctypes-and-cffi + +import cffi +import os +import time +import pwd + +pid = os.getpid() +print('pid:', pid) + +ffi = cffi.FFI() + +libc = ffi.dlopen('libc.so.6') +libcap = ffi.dlopen('libcap.so.2') +#libc.printf(ctypes.c_char_p(b"test\n")) + +ffi.cdef(''' +typedef struct _cap_struct *cap_t; +typedef int cap_value_t; +typedef enum { + CAP_EFFECTIVE=0, + CAP_PERMITTED=1, + CAP_INHERITABLE=2 +} cap_flag_t; + +typedef enum { + CAP_CLEAR=0, + CAP_SET=1 +} cap_flag_value_t; + +int prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5); +cap_t cap_get_proc(void); +int cap_set_flag(cap_t cap_p, cap_flag_t flag, int ncap, + const cap_value_t *caps, cap_flag_value_t value); +cap_t cap_init(void); +int cap_free(void *obj_d); +int cap_set_proc(cap_t cap_p); +''') + +PR_SET_KEEPCAPS = 8 +PR_SET_NAME = 15 +CAP_EFFECTIVE = 0 +CAP_PERMITTED = 1 +CAP_INHERITABLE = 2 +CAP_CLEAR = 0 +CAP_SET = 1 + +# generated list with command line below: +# sed -n 's/^#define \(CAP_.*\) \+\([0-9]\+\).*$/\1 = \2/p' /usr/include/linux/capability.h +CAP_CHOWN = 0 +CAP_DAC_OVERRIDE = 1 +CAP_DAC_READ_SEARCH = 2 +CAP_FOWNER = 3 +CAP_FSETID = 4 +CAP_KILL = 5 +CAP_SETGID = 6 +CAP_SETUID = 7 +CAP_SETPCAP = 8 +CAP_LINUX_IMMUTABLE = 9 +CAP_NET_BIND_SERVICE = 10 +CAP_NET_BROADCAST = 11 +CAP_NET_ADMIN = 12 +CAP_NET_RAW = 13 +CAP_IPC_LOCK = 14 +CAP_IPC_OWNER = 15 +CAP_SYS_MODULE = 16 +CAP_SYS_RAWIO = 17 +CAP_SYS_CHROOT = 18 +CAP_SYS_PTRACE = 19 +CAP_SYS_PACCT = 20 +CAP_SYS_ADMIN = 21 +CAP_SYS_BOOT = 22 +CAP_SYS_NICE = 23 +CAP_SYS_RESOURCE = 24 +CAP_SYS_TIME = 25 +CAP_SYS_TTY_CONFIG = 26 +CAP_MKNOD = 27 +CAP_LEASE = 28 +CAP_AUDIT_WRITE = 29 +CAP_AUDIT_CONTROL = 30 +CAP_SETFCAP = 31 +CAP_MAC_OVERRIDE = 32 +CAP_MAC_ADMIN = 33 +CAP_SYSLOG = 34 +CAP_WAKE_ALARM = 35 +CAP_BLOCK_SUSPEND = 36 + + +uid, gid = 1000, 1000 + + +print("before droping caps") +os.system("cat /proc/{}/status | grep Cap".format(pid)) + +cap_values = (CAP_NET_BIND_SERVICE, ) +cap_values_temp = (CAP_NET_BIND_SERVICE, CAP_SETUID, CAP_SETGID) +ccap_values = ffi.new('cap_value_t[]', cap_values) +ccap_values_temp = ffi.new('cap_value_t[]', cap_values_temp) +#caps = libcap.cap_get_proc() +caps = libcap.cap_init() +print('len cap_values:', len(cap_values)) +libcap.cap_set_flag(caps, CAP_PERMITTED, len(cap_values), ccap_values, CAP_SET) +libcap.cap_set_flag(caps, CAP_PERMITTED, len(cap_values_temp), ccap_values_temp, CAP_SET) +libcap.cap_set_flag(caps, CAP_EFFECTIVE, len(cap_values_temp), ccap_values_temp, CAP_SET) +libcap.cap_set_proc(caps) +libcap.cap_free(caps) + +print("after dropping caps") +os.system("cat /proc/{}/status | grep Cap".format(pid)) + +print('result:', libc.prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) +#print('result:', libc.prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0)) + +os.setgroups(os.getgrouplist(pwd.getpwuid(uid)[0], gid)) +os.setgid(gid) +os.setuid(uid) + +print("after setgid/setuid/setgroups") +os.system("cat /proc/{}/status | grep Cap".format(pid)) + +#caps = libcap.cap_get_proc() +caps = libcap.cap_init() +libcap.cap_set_flag(caps, CAP_PERMITTED, len(cap_values), ccap_values, CAP_SET) +libcap.cap_set_flag(caps, CAP_EFFECTIVE, len(cap_values), ccap_values, CAP_SET) +libcap.cap_set_proc(caps) +libcap.cap_free(caps) + +print("after regaining capabilities") +os.system("cat /proc/{}/status | grep Cap".format(pid)) + +time.sleep(9999) |