一.實驗內容
(一)本週學習內容
本週學習了緩衝區溢位的相關原理,包括簡單的彙編程式碼、緩衝區溢位本質、堆疊的工作原理、Shellcode的編寫等等。
(二)實驗涉及知識點
(1)Linux基本操作:
①熟悉Linux環境:能夠在Linux系統中進行基本的檔案操作、目錄導航,如cd等。
②常用指令理解:如管道(|)、輸入、輸出重定向(>)、提升命令許可權(sudo)等。
(2)緩衝區溢位原理:
①緩衝區溢位原理:本質是陣列的生長方向與棧的生長方向相反,且陣列呼叫沒有進行越界檢查。
②返回地址覆蓋:掌握如何透過緩衝區溢位覆蓋棧上的返回地址,以控制程式的執行路徑。
③堆疊原理:理解堆疊的工作原理,包括資料的壓棧和出棧過程。
④返回地址位置:明確在函式呼叫過程中,返回地址是如何被儲存在堆疊上的。
(3)程式彙編與反彙編:
①組合語言基礎:能看懂簡單的彙編程式碼,如指令呼叫call、資料移動mov等。
②EIP與指令地址:理解EIP(指令指標暫存器)的作用,以及EIP如何操作才能變成call需要的地址。
③objdump工具:會使用objdump工具對程式進行反彙編,以檢視其彙編程式碼。
(4)程式編輯與除錯:
①gdb偵錯程式:會使用gdb進行程式的除錯,如設定斷點、檢視暫存器值、記憶體地址等。
②vi編輯器:掌握vi文字編輯器的使用方法,用於修改程式碼或編寫指令碼。
(5)Shellcode相關知識:
①Shellcode編寫:瞭解如何編寫或獲取一段用於執行特定操作的機器碼Shellcode。
②Shellcode注入:掌握將Shellcode注入到目標程式中的方法,以實現特定的攻擊效果。
③堆疊可執行設定:瞭解如何設定堆疊為可執行狀態,以便注入的Shellcode能夠執行。
④地址隨機化關閉:掌握如何關閉地址隨機化技術,以穩定地找到目標程式的地址空間。
二.實驗過程
(一)任務一:手工修改可執行檔案,改變程式執行流程,直接跳轉到getShell函式。
(1)下載並解壓縮pwn1檔案,透過Xftp傳輸到Kali虛擬機器上
(2)修改主機名(檔名也全程要注意有學號痕跡!)
在命令列頁面使用sudo hostnamectl set-hostname 新的主機名
命令將主機名修改為自己的姓名拼音
再重啟即可(可手動可用命令sudo reboot
)
(3)反彙編檢視pwn1檔案的彙編程式碼,瞭解這一部分彙編程式碼的意義以及做的事情(非必須)
反彙編需要進入檔案所在資料夾,在該資料夾下進入命令列終端,命令為objdump -d 可執行檔案 | more
·~往下查詢目標函式,看到main函式第四行“e8 d7ffffff call 804891
·~具體原理:當main函式執行到call
·~所以此處若需直接改動跳轉地址,需計算EIP相對於
(4)備份pwn檔案並修改備份檔案
所需命令如下:
cp pwn1 複製後的檔名
//cp是複製檔案命令
vi pwn20222318
//vi+檔名進行修改
//開啟檔案後顯示亂碼
:%!xxd
//將檔案顯示模式切換為16進位制模式
/e8 d7
//‘/’為檢索命令。此處可換成/d7ff
按i
進入插入模式,修改“d7”為“c3”,按Esc
退出插入模式
再用:%!xxd -r
命令轉換回原格式,最後:wq
儲存並退出(如果沒用root賬號登入需要在後面加一個!,如:wq!表示強制執行)
再用反彙編命令objdump -d pwn20222318 | more
檢視,修改成功
(5)執行pwn檔案,檢驗是否成功
此時直接執行檔案可以直接跳轉ShellCode.
其中chmod +x ./可執行檔案
是提升檔案許可權的指令,因為我註冊的是普通使用者,做什麼操作都要提升許可權(比如還要用sudo命令)
./pwn
就能執行pwn了
可以看到出現Shell提示符$,任務一完成。
(二)任務二:利用foo函式的Bof漏洞,構造一個攻擊輸入字串,覆蓋返回地址,觸發getShell函式。
(1)反彙編瞭解程式結構
由上圖可見foo函式只預留了56位元組的緩衝區(0x38=3*16+8=56)【自己的理解:其中sub
是不借位減法指令,在上一行將棧底指標的值賦給棧頂指標,進行整個棧幀的清空、初始化,下一行就對棧頂指標進行操作,為棧中的區域性變數預留空間。】,而只要我們輸入足夠長的字串,超出部分就會溢位,從而覆蓋到返回地址。棧的結構參考如下:
故接下來我們需要看輸入字元才能覆蓋到返回地址RET(在除錯過程中體現為EIP的值),以及具體是哪幾個字元的位置可以覆蓋到RET
(2)確認輸入字串哪幾個字元會覆蓋到返回地址
此處需要用到編譯、斷點功能,顧需要下載編譯器gdb。使用sudo apt-get update && sudo apt-get upgrade
升級下載服務包,再用sudo apt-get install gdb
下載gdb。
下載完之後用gdb --version
檢視是否下載完成,如上圖。
複製一份pwn檔案,之後進行編譯。使用字串“8個1,8個2,8個3,8個4,8個5”作為輸入,使用如圖命令檢視各暫存器的值。
可以看到EBP=0x34343434,0x34是ASCII碼中的4,又EIP=0x35353535,是ASCII碼中的5,可以確定最終覆蓋在RET上的數字為5555(前四個)
(3)確認存放順序是小端還是大端,從而確認如何輸入才能將Shell的地址正確覆蓋在返回地址上
這次使用字串“8個1,8個2,8個3,8個4,12345678”作為輸入。
可以看到,EIP=0x34333231,即4321,確認為倒序。故等下輸入返回地址的時候也需要是倒序。
再用斷點驗證一下猜想(指導裡這麼寫的,但是我沒太看懂這一步有什麼用?)
結合反彙編檔案中的getshell地址0804847d,故最終應輸入“8個1,8個2,8個3,8個4,\x7d\x84\x04\x08......”
(4)構造輸入字串
因為我們沒法透過鍵盤輸入\x7d\x84\x04\x08這樣的16進位制值,所以先生成包括這樣字串的一個檔案。\x0a表示回車,如果沒有的話,在程式執行時就需要手工按一下Enter鍵。
xxd是使用十六進位制檢視input檔案的命令,驗證輸入無誤之後可將input檔案作為pwn的輸入。
可以看見執行pwn檔案後出現了命令列,輸入指令,可以正常執行,任務二完成。
(三)任務三:注入一個自己製作的shellcode並執行這段shellcode。
(1)做準備工作,為pwn檔案放行
下載execstack:在自己的物理機上下載。網址:
下載完之後用Xftp傳到虛擬機器上,用sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb
命令解壓縮即可
接著就是輸入下圖指令(-s設定堆疊可執行,-q查詢檔案的堆疊是否可執行,echo “0” 關閉地址隨機化)
(2)構造要注入的Payload
注:本環節需要開啟兩個終端,一個用於監聽程序執行,一個用於執行程序
開啟終端後點選檔案一欄內的“新建標籤頁”即可
在參考資料內找到一段用於攻擊的Shellcode:\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
開啟一個終端注入這個攻擊buf
再開啟另一個終端,先用ps -ef | grep pwn20222318-3
檢視程序號
可以看見./pwn20222318-3的程序號為47056(因人而異)
再使用gdb除錯該程序
透過設定斷點,來檢視注入buf的記憶體地址
ret完,就跳到我們覆蓋的retaddr那個地方了,在另外一個終端中按下回車,繼續執行。
然後完善Shellcode,將分析所得結果填入,以input_shellcode檔案作為輸出執行。
Shellcode成功執行了,任務三結束。
另:有一個有趣的現象,此時另一個終端也出現了Shellcode的神秘命令列。
三.問題及解決方案
-
問題1:Xftp無法連線上Kali虛擬機器,無法傳輸pwn檔案
-
問題1解決方案:使用
sudo vi /etc/ssh/sshd_config
命令修改ssh配置檔案,將#TcpForwarding yes這一行以及以下四行的“#”都刪去,然後將Gateway改成yes,再用sudo systemctl restart sshd
重啟ssh服務,再與Xftp建立連線即可。 -
問題2:用/e8d7命令找對應機器碼的時候沒找到
-
問題2解決方案:在檔案內e8 d7不是連著的,中間有空格,故檢索命令中間加個空格就行了。
-
問題3:執行./pwn檔案時許可權不夠
-
問題3解決方案:使用
chmod +x ./pwn
提升許可權 -
問題4:關閉地址隨機化的時候許可權不夠,sudo語句不能解決問題
-
問題4解決方案:使用
sudo echo "0" > /proc/sys/kernel/randomize_va_space
命令時,實際上sudo
只提升了echo
命令的許可權,而沒有提升重定向運算子 > 的許可權。因此,這個命令會因為許可權不足而失敗,故使用sudo sh -c '需要提升許可權的命令'
命令進行操作 -
問題5:任務三不知道怎麼分析出的堆疊地址
-
問題5解決方案:待解決
四.學習感悟、思考等
這次實驗真的很考驗實踐能力了,很多知識都不僅僅是從課堂上學的,要自己去查每一行程式碼什麼意思,從而去從底層理解緩衝區溢位的原理。這是以前從來沒有過的視角,理解起來確實有一點挑戰。計算機底層的世界有些晦澀,但也歡迎求知者去探索。我從這次實驗學到了很多,也改進了我的學習方法。從以前的只會運用課堂知識去做實驗,到現在的主動去網上找大量資料去補全自己的知識網路,我在慢慢習慣大三的學習節奏。希望我能繼續克服萬難,學好網路攻防!