1.實驗內容
1.1本週學習內容
1.1.1緩衝區溢位的定義和原因
定義:寫入緩衝區的資料量超過該緩衝區能容納的最大限度,造成溢位的資料改寫了與該緩衝區相鄰的原始資料的情形。
原因:(直接)由於程式碼語言的設計問題、程式設計師的安全意識問題,程式沒有嚴格的記憶體越界檢查;(根本)馮諾依曼體系的安全缺陷,儲存中資料和指令沒有嚴格分離。
1.1.2緩衝區溢位攻擊的歷史
紅色程式碼、衝擊波病毒、震盪波病毒、心臟出血、烏克蘭斷網、勒索病毒。
1.1.3緩衝區溢位基礎知識
編譯器和聯結器:根據高階語言編寫的程式,生成可執行程式程式碼,有gcc、javac。
偵錯程式:在執行時除錯與分析程式行為的工具,有gdb、jdb、pdb。
暫存器分類:通用暫存器、段暫存器、控制暫存器、其他暫存器。
EBP棧底指標(在高地址)、ESP棧頂指標(在低地址)、EIP指令指標暫存器(指向下一條將要執行的指令的地址)
堆:程式動態分配的資料和變數。
棧:環境變數/引數和個數以及主函式和呼叫棧中函式的臨時儲存資訊。
彙編指令:push、pop、mov、sub等。
核心態與使用者態。
1.2實驗內容簡述
名為pwn1的linux可執行檔案,在正常情況下執行會呼叫foo函式,該函式會簡單回顯使用者輸入的字串。該程式同時包含另一個程式碼片段getShell,會返回一個可用Shell。正常情況下這個程式碼不會被執行,本次實驗使用三種方法嘗試呼叫getshell函式:
修改可執行檔案內容,改變程式中的一個函式呼叫指令,直接跳轉到getShell函式。
利用foo函式的緩衝區溢位漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式。
注入一個自己製作的shellcode(一段用於獲取一個互動式的shell的機器指令)並執行這段shellcode。
2.實驗過程
2.1修改程式機器指令的方法
下載目標檔案pwn1,正常執行,可以回顯輸入字串。
使用“objdump -d pwn1 | more”命令,反彙編並找到函式呼叫的相關指令。可以看到main中80484b5位置是跳轉到foo函式的指令。
跳轉指令中,e8是跳轉的意思,d7ffffff為補碼,表示當前地址+(-41),所以要呼叫getShell函式,需要改變後面四個位元組。根據計算,應該是-61,即-0x3d,補碼為c3ffffff。
按照計算結果需將該條指令改為e8c3ffffff。開啟vi後修改過程為:用“:%!xxd”指令將顯示模式切換為16進位制模式;用“/d7ff”定位修改位置,將d7修改為c3;用“:%!xxd -r”指令轉換16進製為原格式;“:wq”儲存退出。
執行修改後檔案,可以進入shell。 成功獲取shell,即成功呼叫了getShell函式
2.2BOF攻擊的方法
首先進行反彙編,可以發現在foo函式中,8048497位置的指令為“lea -0x1c(%ebp),%eax”,即只為後續的讀入字串預留了0x1c=28位元組的緩衝區。call呼叫foo時,原本會在堆疊上壓上返回地址80484ba,我需要透過修改,讓返回地址的值被覆蓋為getShell函式的地址804847d。(圖片在2.1中已給出)
使用gdb,輸入超過28位元組的字串,再檢視各個暫存器的值,發現eip的值是0x35353535,即5555的ascii碼。在輸入另一個特定的過長字串,檢視eip的值為0x34333231,即4321的ascii碼。這就確定了應該如何設定攻擊字串,即將第33至第36個字元設定為804847d按位元組的倒序。不能透過鍵盤直接輸入,所以先利用perl軟體生成包括這樣字串的一個檔案。用“xxd input”命令檢視檔案內容,可以發現內容正確。將input的輸入,透過管道符“|”,作為pwn的輸入。然後可以發現程式呼叫了getShell函式,可以獲取shell了。
2.3注入shellcode的方法
找到一段用於攻擊的shellcode:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\。這段shellcode是啟動一個新的/bin/sh shell的機器碼,用於後續的攻擊操作。做準備工作,設定堆疊可執行,關閉地址隨機化,並進行確認。
4.5 結合nc模擬遠端攻擊
本例中是在同一臺主機上做的實驗;該實驗最好在互相連通的兩臺Linux上做,將ip地址替換為主機1的IP即可。
主機1,模擬一個有漏洞的網路服務:
5.3. 增加shellcode的構造難度。
shellcode中需要猜測返回地址的位置,需要猜測shellcode注入後的記憶體位置。這些都極度依賴一個事實:應用的程式碼段、堆疊段每次都被OS放置到固定的記憶體地址。ALSR,地址隨機化就是讓OS每次都用不同的地址載入應用。這樣透過預先反彙編或除錯得到的那些地址就都不正確了。