[NSYSU 資安社課] Pwn Basic #1
經歷大約一學期的 CTF 洗禮,總算是對這分面稍微有些概念 : D
原本已經這個部落格的定位應該要是技術向,殊不知都被我拿來發廢文…
作為第一篇 writeup,決定拿社課的習題練練手,一方面是讓我自己在這方面的學習上可以邊寫邊延伸思考。另外就是可以給非資安背景的朋友簡單認識一下 Pwn ,否則每次被問到我也不曉得怎麼解釋(抹臉)
hmmm 不會解釋資安… 應該是我的問題才對Orz
“Pwn” 有人唸 Costco、有人唸 IKEA,總之我都唸"胖“或是”碰"。常見做法就是針對程式內的漏洞進行攻擊(提權),有種 “player has been owned.” 的意思。
也有人說是Penetration(滲透) + Own(佔有)的組合,總之就大概是這種感覺~ 在CTF領域,Pwn 基礎題通常是給你讀取的無權限文字檔,希望你透過程式漏洞拿到 root 權限拿 flag。
以我來說,平常剛拿到題目比較會用到的幾個指令。
ls -al
瞭解目錄下的檔案以及執行權限file
確認檔案類型以及位元數checksec
查看該ELF檔開啟了哪些保護機制
那接下來就開始解題囉!ovo
0x01: Password
首先,來看一下這題提供的檔案。
password
password.c
flag.txt
第一個檔案 password
用 file
指令可以查看關於password的檔案類型。
|
|
可以發現是屬於 Linux 底下的 ELF 執行檔,也是 CTF 內最常見的檔案類型,不過用 MacOS 的 Safari 載下來都會莫名被加上.dms
,當時第一次看到還在思考檔案是不是壞了XD(用 file
查看是沒有問題),另外社課提供的 Pwn 基礎題以 32-bits
為主,比起 64-bits 相對單純方便教學。
再來就是直接執行看看… 咦?不能執行?
用 ls
發現這個檔案並沒有執行權限,可以用 chmod
改檔案權限。對其他細節有興趣的可以瞭解一下 鳥哥私房菜 - Linux的檔案權限與目錄配置。
$ ls -al
-rw-r-xr-x@ [other information] password
$ chmod +x ./password
$ ls -al
-rwxr-xr-x@ [other information] password
修改完執行權限後可以先run一下看看程式大概要幹嘛。
在Pwn基礎題通常會刻意把一些防禦機制關掉,可以拿 checksec
指令看看該執行檔開了哪些保護,以password這題來說。
$ checksec ./password
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
第一次見到這些保護機制看不懂很正常,簡單講就是
RELRO
暫時還不會用到,主要適用於防範 lazy Binding 所造成的延伸問題- Stack 的
canary
關閉能夠讓你的輸入超過指定長度蓋到一些奇怪的位址,簡單講就是能 Buffer Overflow NX
開啟表示不讓你塞些邪惡的command在程式內執行,之後也會有這部分的練習PIE
關閉讓你分析執行檔時看到的會是"絕對位址",若開啟就只看得到位址偏移量不容易拿來利用
P.S. 另外還有一個沒出現在
checksec
的ASLR
,主要是對於每次執行 stack 、heap … etc. 的位址隨機化,避免攻擊者可以定位記憶體位址
之後根據社課這部分內容應該會再講詳細點,剛開始大概有個認知就行了。
然後,社課的基礎題還順便附了該執行程式的原始碼,╭(⊙Д⊙)╯佛心講師╭(⊙Д⊙)╯
|
|
這段 code 對於有寫過程式的各位應該都不困難。
題意要求輸入 name
,然後會拿變數 password
和 “password” 進行比較,判斷式成立就能執行 shell()
,可以發現當中並沒有任何要求輸入變數password
,只有在最後會輸出 “QQ password
",若第一次接觸 Pwn 的看到這奇怪的判斷式應該會滿頭問號。
不過,我們可以先隨便輸入一些東西觀察看看,像是變數 name
大小為 8 bytes,輸入 “12345678”,會得到下面結果。
$ What's your name? 12345678
$ Hello 12345678
QQ
Segmentation fault
然而,如果輸入超過 8 bytes “1234567890”,會得到下列結果。
$ What's your name? 1234567890
$ Hello 1234567890
QQ 90
Segmentation fault
嗯嗯?明明沒有對變數 password
輸入參數,但變數內容好像被偷改了XD
沒錯!這題主要想表達的事情是:
gets()
這輸入函式是不安全的,因為它不會限制使用者的輸入長度。因此若在沒有 canary 的情況下很容易遭受 Buffer Overflow 攻擊!
以這題來說我們可以用反組譯指令 objdump
瞭解一下程式架構
$ objdump -d -M intel ./password
Stack內容的部分畫成圖大概長得像這樣
我們這次輸入改成 “aaaaaaaahaha” , “haha” 就會蓋到變數 password
的值了。
聰明的你應該知道怎麼做了吧 (。・ω・。)
沒有錯的啦!將上面的 “haha” 改成 “password” 就能啟動 shell()
拿到 root 權限了!
話說回來,往後能夠透過手動輸入就破解的 Pwn 題並不常見,因此這類型的題目通常會搭配 Python 套件 pwntool
進行 exploit。
↓↓↓ 以這題來說用pwntool可以這樣寫 ↓↓↓
|
|
光是第一題就寫了落落長…
打 Pwn 一開始抓不到感覺還蠻正常,所以我希望能用step by step的方式解釋詳細一點,順便幫自己補充平常不太會深入的知識。
0x02: BOF
這題給的檔案有
bof
bof.c
flag.txt
同樣 flag 沒有讀取權限,我們一樣來看看 bof
執行檔有開了哪些保護。
Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
唔嗯… 可以發現和上一題形式上十分類似,再來看看bof.c
原始碼的內容
|
|
整體結構看起來和上一題沒什麼差別,也都是針對 gets()
的危險漏洞,只是這次… 完全沒辦法執行 shell()
!!!
這題主要想表達的事情是:
gets()
不限輸入長度的漏洞進行 Buffer Overflow。而且要把
vuln()
原本要回到 main()
的 return address 改成 shell()
的 address。嗯… 蛤!? ・ ࡇ ・
我相信有學過 OS 的同學大概都不陌生,只是懂歸懂,但要怎麼做呢?
一樣先拿 objdump
一樣來看看裡頭長什麼樣子。
$ objdump -d -M intel ./bof
|
|
重點在 line 18 的 ebp-0x30
,必須要掌握變數所在的相對位置,我們把 stack frame 畫成圖大概就是下面這樣 ↓↓↓
也就是說,這題希望我們除了把str[48]
填滿
還要利用Buffer Overflow的方式把shell()
的address蓋到return上。
再來就是要知道line 1 shell()
的function address
假如我們通通用"a"進行覆蓋,預期結果將會長這樣:)
既然知道要怎麼蓋return address,剩下的就是寫payload了。
|
|
這樣就能拿到root權限讀flag,當然如果懶得開檔案寫code,也是有一行流寫法XD
$ (python -c "print('a'*48 + 'a'*4 + '\xeb\x84\x04\x08')"; cat) | ./bof
大概就是這麼一回事了~
寫的比預期還要久,而且原本想一篇講個三題,結果第一題介紹太久了QQ
就醬,希望我還能繼續把題目補完(逃