作業題目
本實驗的學習目標是讓學生將從課堂上學到的有關緩衝區溢位漏洞的知識進行實踐,從而獲得有關該漏洞的第一手經驗。緩衝區溢位是指程式試圖將資料寫入預先分配的固定長度緩衝區邊界之外的情況。惡意使用者可利用此漏洞改變程式的流控制,甚至執行任意程式碼。此漏洞是由於資料儲存(如緩衝區)和控制元件儲存(如返回地址)的混合造成的:資料部分的溢位會影響程式的控制流,因為溢位會改變返回地址。
本實驗將提供四臺不同的伺服器,每臺伺服器執行一個帶有緩衝區溢位漏洞的程式。實驗任務是開發一個利用漏洞的程式,並最終獲得這些伺服器上的root許可權。除了進行這些攻擊實驗之外,還將試驗幾種針對緩衝區溢位攻擊的對策。學生需要評估這些計劃是否有效,並解釋原因。
實驗步驟及結果
Task 1: Get Familiar with the Shellcode
Please modify the shellcode, so you can use it to delete a file. Please include your modified the shellcode in the lab report, as well as your screenshots.(以shellcode_32.py為例)
A)執行以下命令,測試題目給的程式碼:
可以完成。
B)建立一個檔案test.txt
修改shellcode_32.py:
重複A)中執行的命令:
成功實現刪除檔案。
Task 2: Level-1 Attack
- 搭建實驗環境
執行以下命令,執行四臺伺服器:
關閉隨機地址:
兩次執行,地址未改變(關閉成功):
- 分析exploit.py
生成一個全由NOP組成的517個bytes的content。
- NOP:空轉,不進行任何操作。
- 517:對應stack.c中的從stdin(標準輸入,通常是鍵盤)讀取517個字元。
透過修改shellcode的值,在exploit.py中填入需要執行的shellcode程式碼,
並透過修改start的值,將全是NOP的content中的部分替換為shellcode。
將content中從offset開始到offset後面4個byte的值替換為ret生成的地址:
所以,ret值要修改為shellcode執行“入口”的地址,offset值要修改為函式棧中偏移地址的值。
所以,ret = ebp + 8,offset = ebp - buffer’s address + 4。
最終,執行程式碼後會生成一個內容為content名為badfile的檔案。
將沒有修改的exploit.py放入伺服器執行:
可知,ebp = 0xffffd3b8,buffer’s address = 0xffffd348。
D)
修改exploit.py:
生成badfile,將badfile放入伺服器中執行:
成功。
Task 3: Level-2 Attack
測試伺服器2:
發現它只給出buffer的地址0xffffd2f8,沒有ebp,這意味著不能確定緩衝區的大小。
透過題目知道,bufferSize在[100,300]範圍內,所以,offset應該在[100+4,300+4]範圍內,且一定為4的倍數。
offset最大為304,則ret後面(高地址方向)都是NOP指令或shellcode程式碼,因此ret = buffer’s address + 304 + 4 (ret部分佔有空間大小)一定會指向NOP指令或shellcode指令入口處,而NOP指令會一直向下跳。
從offset=104開始一直填寫上面一部確定好的ret值到offset=304結束,則ret部分一定會得到上面的ret值。
修改程式碼exploit2.py:
執行程式碼,生成檔案badfile2,在伺服器2中執行:
成功。
Task 4: Level-3 Attack
測試伺服器3:
buffer’address = 0x00007fffffffe220
rbp = 0x00007fffffffe2d0
這是一個64位的伺服器,地址為8bytes,最高兩個位元組恆為0,這會導致一個問題,我們透過strcpy()將內容複製到stack中,但strcpy()見到0就會停止複製,比如radfile檔案中的ret=0x0000XXXXXXXXXXXX。
由結果可知,buffersize = 208 bytes,shellcode的長度是165bytes,所以,我們可以將shellcode複製到buffer中。
我們要在執行ret之前執行shellcode"/bin/ls -l; echo Hello 64; /bin/tail -n 4 /etc/passwd *"(字串之前(包含該字串)的shellcode長為133bytes),buffer_size+ebp段=208+8=216,offset(208+8)-start+1≥133,所以,0≤star≤84。
ret=buffer’address+[0,start]
offset=buffer_size+8
修改程式碼exploit3.py:
將shellcode修改為64位的shellcode
執行程式碼,生成檔案badfile3,在伺服器3中執行:
成功。
Task 5: Level-4 Attack
測試伺服器4:
buffer’address = 0x00007fffffffe290
rbp = 0x00007fffffffe2f0
buffersize = 96bytes
函式棧很小,不能將shellcode放進緩衝區,而放在ret段後面又會被截斷。但是badfile傳進目標程式時已載入資料段,因此可以將ret設定跳轉到資料段的shellcode程式碼部分執行shellcode。
ret=rbp+n,n在1184與1424之間。
修改程式碼exploit4.py:
生成badfile4,並在伺服器4中執行:
成功。
Task 6: Experimenting with the Address Randomization
開啟隨機地址:
測試伺服器1,伺服器3:
在/Labsetup/attack-code目錄下執行exploit.py程式,並另開啟一視窗進行監聽。
執行/Labsetup/attack-code目錄下的brute-force.sh程式,該程式會一直執行exploit.py程式直到獲得目標伺服器shell。
在第79943次獲得目標伺服器shell。
Task 7.b: Turn on the Non-executable Stack Protection
A.
開啟StackGuard保護,並將badfile檔案傳輸到stack-L1檔案中,在/Labsetup/serve-code目錄下直接執行stack-L1檔案:
檢測到了 stack smashing
B.
開啟Non-executable Stack(棧堆不可執行)保護
發生了segmentation fault,堆疊不能執行,但沒有阻止緩衝區溢位。