Gallopsled / pwntools

CTF framework and exploit development library
http://pwntools.com
Other
12.08k stars 1.71k forks source link

"sh" shellcraft does not pass argv0 #626

Closed kokjo closed 8 years ago

kokjo commented 8 years ago

EOM;

zachriggle commented 8 years ago

It actually works fine. It doesn't work with Busybox (Toybox for Android) since those both fail when argv[0] is NULL.

>>> context.arch='amd64'
>>> print shellcraft.sh()
    /* push '/bin///sh\x00' */
    push 0x68
    mov rax, 0x732f2f2f6e69622f
    push rax

    /* call execve('rsp', 0, 0) */
    mov rdi, rsp
    xor esi, esi
    push 0x3b
    pop rax
    cdq /* Set rdx to 0, rax is known to be positive */
    syscall

>>> write('sh.asm', shellcraft.sh())

This code is valid, and can be tested. If you build it with Binjitsu (just used since it easy easy to turn it into an ELF)...

$ asm -i sh.asm -c amd64 -f elf > sh.pwntools

...you can see that it works correctly.

$ strace -e execve ./sh.pwntools
execve("./sh.pwntools", ["./sh.pwntools"], [/* 90 vars */]) = 0
execve("/bin///sh", [0], [/* 0 vars */]) = 0

However, Busybox requires argv0 to be set, or else it doesn't know what tool to run.

TethysSvensson commented 8 years ago

I vote that we use a slightly longer shellcode that works even when the system uses busybox.

What do you think, @zachriggle? We already have that shellcode in android, right?

zachriggle commented 8 years ago

Correct, the code is slightly different for Linux and Android, due to busybox/toybox.

    ${arm.linux.execve('/bin///sh', 0, 0)}

vs.

    ${arm.linux.execve('/system/bin//sh', ['sh'], 0)}

The emitted code is MUCH larger.

$ shellcraft i386.linux.sh
6a68682f2f2f73682f62696e6a0b5889e331c999cd80
$ shellcraft i386.android.sh
68010101018134247269010131d2526a045a01e25289e268010101018134242e7269016862696e2f6874656d2f682f7379736a0b5889e389d199cd80
TethysSvensson commented 8 years ago

Could we have an argument for this?

zachriggle commented 8 years ago

This is already currently possible with the execve shellcode.

$ shellcraft i386.linux.execve "/bin/sh" "['argv0', 'argv1']" "{'env':'value'}"

I'm not opposed to having a sh argument if it really helps

TethysSvensson commented 8 years ago

I think having an explicit argument would be nice in a stressed CTF situation. It does not have to be done by 3.0.