#!/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() libcap = ffi.dlopen('libcap.so.2') 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; 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); ''') 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_.*\)\s\+\([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)) os.system("cp /bin/sleep /tmp/sleep") os.system("setcap cap_net_bind_service=ei /tmp/sleep") cap_values = (CAP_NET_BIND_SERVICE, ) cap_values_temp = (CAP_SETUID, CAP_SETGID,) ccap_values = ffi.new('cap_value_t[]', cap_values) ccap_values_temp = ffi.new('cap_value_t[]', cap_values_temp) print('len cap_values:', len(cap_values)) caps = libcap.cap_init() libcap.cap_set_flag(caps, CAP_INHERITABLE, 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)) 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)) os.execve("/tmp/sleep", ["/tmp/sleep", "9999"], {})