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) | 
