1 #!/bin/bash 2 # 3 # Run through a series of tests to try out the various capability 4 # manipulations posible through exec. 5 # 6 # [Run this as root in a root-enabled process tree.] 7 8 try_capsh () { 9 echo "TEST: ./capsh $*" 10 ./capsh "$@" 11 if [ $? -ne 0 ]; then 12 echo FAILED 13 return 1 14 else 15 echo PASSED 16 return 0 17 fi 18 } 19 20 fail_capsh () { 21 echo -n "EXPECT FAILURE: " 22 try_capsh "$@" 23 if [ $? -eq 1 ]; then 24 echo "[WHICH MEANS A PASS!]" 25 return 0 26 else 27 echo "Undesired result - aborting" 28 echo "PROBLEM TEST: $*" 29 exit 1 30 fi 31 } 32 33 pass_capsh () { 34 echo -n "EXPECT SUCCESS: " 35 try_capsh "$@" 36 if [ $? -eq 0 ]; then 37 return 0 38 else 39 echo "Undesired result - aborting" 40 echo "PROBLEM TEST: $*" 41 exit 1 42 fi 43 } 44 45 pass_capsh --print 46 47 48 # Make a local non-setuid-0 version of capsh and call it privileged 49 cp ./capsh ./privileged && chmod -s ./privileged 50 if [ $? -ne 0 ]; then 51 echo "Failed to copy capsh for capability manipulation" 52 exit 1 53 fi 54 55 # Give it the forced capability it could need 56 ./setcap all=ep ./privileged 57 if [ $? -ne 0 ]; then 58 echo "Failed to set all capabilities on file" 59 exit 1 60 fi 61 ./setcap cap_setuid,cap_setgid=ep ./privileged 62 if [ $? -ne 0 ]; then 63 echo "Failed to set limited capabilities on privileged file" 64 exit 1 65 fi 66 67 # Explore keep_caps support 68 pass_capsh --keep=0 --keep=1 --keep=0 --keep=1 --print 69 70 rm -f tcapsh 71 cp capsh tcapsh 72 chown root.root tcapsh 73 chmod u+s tcapsh 74 ls -l tcapsh 75 76 # leverage keep caps maintain capabilities accross a change of uid 77 # from setuid root to capable luser (as per wireshark/dumpcap 0.99.7) 78 pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --caps=\"cap_net_raw,cap_net_admin=pie\" --print" 79 80 # This fails, on 2.6.24, but shouldn't 81 pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --forkfor=10 --caps= --print --killit=9 --print" 82 83 # only continue with these if --secbits is supported 84 ./capsh --secbits=0x2f > /dev/null 2>&1 85 if [ $? -ne 0 ]; then 86 echo "unable to test securebits manipulation - assume not supported (PASS)" 87 rm -f tcapsh 88 rm -f privileged 89 exit 0 90 fi 91 92 # nobody's uid. Static compilation of the capsh binary can disable pwd 93 # info discovery. 94 nouid=$(/usr/bin/id nobody -u) 95 96 pass_capsh --secbits=42 --print 97 fail_capsh --secbits=32 --keep=1 --keep=0 --print 98 pass_capsh --secbits=10 --keep=0 --keep=1 --print 99 fail_capsh --secbits=47 -- -c "./tcapsh --uid=$nouid" 100 101 rm -f tcapsh 102 103 # Suppress uid=0 privilege 104 fail_capsh --secbits=47 --print -- -c "./capsh --uid=$nouid" 105 106 # suppress uid=0 privilege and test this privileged 107 pass_capsh --secbits=0x2f --print -- -c "./privileged --uid=$nouid" 108 109 # observe that the bounding set can be used to suppress this forced capability 110 fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --uid=$nouid" 111 112 # change the way the capability is obtained (make it inheritable) 113 ./setcap cap_setuid,cap_setgid=ei ./privileged 114 115 # Note, the bounding set (edited with --drop) only limits p 116 # capabilities, not i's. 117 pass_capsh --secbits=47 --inh=cap_setuid,cap_setgid --drop=cap_setuid \ 118 --uid=500 --print -- -c "./privileged --uid=$nouid" 119 120 rm -f ./privileged 121 122 # test that we do not support capabilities on setuid shell-scripts 123 cat > hack.sh <<EOF 124 #!/bin/bash 125 /usr/bin/id 126 mypid=\$\$ 127 caps=\$(./getpcaps \$mypid 2>&1 | /usr/bin/cut -d: -f2) 128 if [ "\$caps" != " =" ]; then 129 echo "Shell script got [\$caps] - you should upgrade your kernel" 130 exit 1 131 else 132 ls -l \$0 133 echo "Good, no capabilities [\$caps] for this setuid-0 shell script" 134 fi 135 exit 0 136 EOF 137 chmod +xs hack.sh 138 ./capsh --uid=500 --inh=none --print -- ./hack.sh 139 status=$? 140 rm -f ./hack.sh 141 if [ $status -ne 0 ]; then 142 echo "shell scripts can have capabilities (bug)" 143 exit 1 144 fi 145 146 # Max lockdown 147 pass_capsh --keep=1 --uid=$nouid --caps=cap_setpcap=ep \ 148 --drop=all --secbits=0x2f --caps= --print 149 150 # Verify we can chroot 151 pass_capsh --chroot=$(/bin/pwd) 152 pass_capsh --chroot=$(/bin/pwd) == 153 fail_capsh --chroot=$(/bin/pwd) -- -c "echo oops" 154