iT邦幫忙

2024 iThome 鐵人賽

DAY 14
0
Security

Pwn2Noooo! 執行即 Crash 的 PWNer 養成遊戲系列 第 14

[Day14] Pwnable.tw 基礎題實戰(一)

  • 分享至 

  • xImage
  •  

在之前的幾篇文章中,我們從程式有後門函式到需要自己寫 Shellcode,再到後來學習了 NX 保護機制,也因此學會了使用 ROP 去繞過,最後也說明延遲綁定帶來的風險,導致有了 RELRO 保護機制的產生,可以說對於 Stack 的攻擊有一定的基礎了。

因此接下來的幾篇文章我們將不使用自己編譯的程式,而是使用 pwnable.tw 的題目實際練習。

通常一題題目會拆成前一篇是分析後一篇才是攻擊。


今天題目是 pwnable.tw 的第一題 start

由於我們之前都是已經確定好架構了,但這次沒有,我們需要先使用 file 這個指令確認,可以發現他是 x86,如同之前說明的他是使用 32 bits 的暫存器,並且由 Stack 傳參數。

接下來,由於不是我們自己編譯的,因此我們要先確認一下保護記憶體機置,使用 checksec 這個指令。
https://ithelp.ithome.com.tw/upload/images/20231011/20163074XwWs1NkpoH.png
可以看出沒有設任何保護機制

執行起來會發現
https://ithelp.ithome.com.tw/upload/images/20231011/20163074ULl6uNwFvG.png
輸入太長會觸發 segmentation fault

我們再用 IDA 打開
https://ithelp.ithome.com.tw/upload/images/20231011/20163074QXTiwBNdeQ.png
我們可以發現,首先他將 esp 值 push 進去,接下來 push exit 函數的位置,作為 return address。

接著透過 XOR 將 register 值歸零後,又 push 值進去,因此整支程式的記憶體配值如下
https://ithelp.ithome.com.tw/upload/images/20231011/20163074TSN9vx4ryr.png

接下來我們可以看到

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。
https://ithelp.ithome.com.tw/upload/images/20231011/201630748OMdRFSjnu.png
將 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。

明天的文章將會接續說明


上一篇
[Day13] 漏洞介紹 - Format Strings
下一篇
[Day15] Pwnable.tw 基礎題實戰(二)
系列文
Pwn2Noooo! 執行即 Crash 的 PWNer 養成遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言