在之前的幾篇文章中,我們從程式有後門函式到需要自己寫 Shellcode,再到後來學習了 NX 保護機制,也因此學會了使用 ROP 去繞過,最後也說明延遲綁定帶來的風險,導致有了 RELRO 保護機制的產生,可以說對於 Stack 的攻擊有一定的基礎了。
因此接下來的幾篇文章我們將不使用自己編譯的程式,而是使用 pwnable.tw 的題目實際練習。
通常一題題目會拆成前一篇是分析後一篇才是攻擊。
今天題目是 pwnable.tw 的第一題 start。
由於我們之前都是已經確定好架構了,但這次沒有,我們需要先使用 file
這個指令確認,可以發現他是 x86,如同之前說明的他是使用 32 bits 的暫存器,並且由 Stack 傳參數。
接下來,由於不是我們自己編譯的,因此我們要先確認一下保護記憶體機置,使用 checksec
這個指令。
可以看出沒有設任何保護機制
執行起來會發現
輸入太長會觸發 segmentation fault
我們再用 IDA 打開
我們可以發現,首先他將 esp 值 push 進去,接下來 push exit 函數的位置,作為 return address。
接著透過 XOR 將 register 值歸零後,又 push 值進去,因此整支程式的記憶體配值如下
接下來我們可以看到
0x8048087 <_start+39>: mov ecx,esp
0x8048089 <_start+41>: mov dl,0x14
0x804808b <_start+43>: mov bl,0x1
0x804808d <_start+45>: mov al,0x4
0x804808f <_start+47>: int 0x80
從 0x08048087 開始是個 system call,可以看到他把 eax 設為 0x04,0x04 為 write。
將 esp(stack 頂端)的值給 ecx,edx 設為 0x14,因此得知會從 esp 往下輸出 20 bytes 的內容,也就是 Ler's start the CTF:
接下來
0x8048091 <_start+49>: xor ebx,ebx
0x8048093 <_start+51>: mov dl,0x3c
0x8048095 <_start+53>: mov al,0x3
0x8048097 <_start+55>: int 0x80
這個 system call 是 read,然而他將 edx 設為 0x3c,ecx 還是之前位置,因此
-------------- <-- ecx, esp
| Let' |
--------------
| s st |
--------------
| art |
--------------
| the |
--------------
| CTF: |
--------------
| retaddr | (exit address)
--------------
| saved esp |
--------------
很明顯的只要輸入超過 20 就可以覆蓋掉saved esp 與 return address。
已經找到有問題的地方了,接下來我們繼續往下看要怎麼構造 payload。
0x8048099 <_start+57>: add esp,0x14
0x804809c <_start+60>: ret
最後兩行是這個,我們可以看到他把 esp 往下移 0x14
-------------- <-- ecx
| Let' |
--------------
| s st |
--------------
| art |
--------------
| the |
--------------
| CTF: |
-------------- <-- esp
| retaddr | (exit address)
--------------
| saved esp |
--------------
並且執行 ret 把 esp 值 pop 出來給 eip,讓他順利的執行 exit。
現在我們希望能自己寫一個 shellcode 進去讓他執行。我們希望讓他能讓 eip 直接跳到我們寫的程式碼去執行,但我們不知道 eip 的位置不能動他,因此為了達到這個目的,最簡單的方法就是修改 esp 值,讓他在 ret 的時候能 pop 出我們 shellcode 的位置給 eip。
我們發現到程式在調用 write 時給的 buffer 過大,給了 60 個 bytes,因此輸入超過 20 個 bytes 可以覆蓋 return address。
-------------- <-- ecx // 輸入起始點
| Let' |
--------------
| s st |
--------------
| art |
--------------
| the |
--------------
| CTF: |
--------------
| retaddr | (exit address)
--------------
| saved esp |
--------------
現在我們希望能自己寫一個 shellcode 進去讓他執行。我們希望讓他能讓 eip 直接跳到我們寫的程式碼去執行,但我們不知道 eip 的位置不能動他,因此為了達到這個目的,最簡單的方法就是修改 esp 值,讓他在 ret 的時候能 pop 出我們 shellcode 的位置給 eip。
明天的文章將會接續說明