20232409 2025-2026-1 《網(wǎng)絡(luò)與系統(tǒng)攻防技術(shù)》實驗一實驗報告
1.實驗內(nèi)容
1.1手工修改可執(zhí)行文件,改變程序執(zhí)行流程,直接跳轉(zhuǎn)到getShell函數(shù)。
1.2利用foo函數(shù)的Bof漏洞,構(gòu)造一個攻擊輸入字符串,覆蓋返回地址,觸發(fā)getShell函數(shù)。
1.3注入一個自己制作的shellcode并運行這段shellcode。
2.實驗?zāi)康?/span>
2.1掌握NOP, JNE, JE, JMP, CMP匯編指令的機器碼。
2.2掌握反匯編與十六進制編程器。
2.3能正確修改機器指令改變程序執(zhí)行流程。
2.4能正確構(gòu)造payload進行bof攻擊。
3.實驗環(huán)境
由于下載Kali系統(tǒng)所需時間過長,本次實驗在華為云上購買的20.04版本Ubuntu虛擬機上進行,并安裝了Kali工具。該虛擬機的配置信息如圖一所示:

該虛擬機為64位操作系統(tǒng),需要在其上啟用32位架構(gòu)支持,可使用命令dpkg --add-architecture i386實現(xiàn)。此后需使用命令apt install -y libc6:i386 libncurses5:i386 libstdc++6:i386安裝32位庫,如圖2所示:

隨后需要安裝安裝Kali工具鏈,通過命令echo "deb http://http.kali.org/kali kali-rolling main contrib non-free" > /etc/apt/sources.list.d/kali.list`,wget https://archive.kali.org/archive-key.asc,apt-key add archive-key.asc添加Kali源。然后可通過命令apt install -y metasploit-framework gdb nmap python3-pip,pip3 install pwntools安裝Kali工具,如圖3所示:

安裝完成后可正式開始實驗。
4.實驗過程與分析
本實驗通過三種方法獲得shell,分別是直接修改程序的機器指令,跳轉(zhuǎn)到getShell函數(shù);利用foo函數(shù)的Bof漏洞,構(gòu)造一個攻擊輸入字符串,覆蓋返回地址,觸發(fā)getShell函數(shù);注入一個自己制作的shellcode并執(zhí)行。
4.1方法一:直接修改程序機器指令
4.1.1文件上傳與準(zhǔn)備
下載目標(biāo)文件pwn1,通過WinSCP傳入虛擬機中,并進行復(fù)制、改名,如圖4所示:

此處為了確保pwn文件具有執(zhí)行權(quán)限,需要使用命令chmod +x pwn1為它賦予執(zhí)行權(quán)限,此后再進行復(fù)制、改名操作。這樣所有復(fù)制得到的文件都將具有執(zhí)行權(quán)限。如圖5所示:

4.1.2計算返回地址
使用objdump -d pwn20232409_2 | more命令,對文件pwn20232409_2進行反匯編,并找到函數(shù)調(diào)用的相關(guān)指令。此處可以看到main中80484b5位置是跳轉(zhuǎn)到foo函數(shù)的指令。如圖6所示:

此處call 8048491的含義是這條指令將調(diào)用位于地址8048491處的foo函數(shù)。其對應(yīng)機器指令為e8 d7 ff ff ff,e8表示跳轉(zhuǎn),d7 ff ff ff表示foo函數(shù)的地址。因此我們需要修改d7 ff ff ff為getShell函數(shù)的地址,使其直接調(diào)用getShell函數(shù)。
這里d7 ff ff ff為補碼,而80484ba+d7ffffff=8048491。以此類推,為了獲得getShell的地址,則804847d-80484ba=ffffffc3。因此我們需要將命令e8 d7 ff ff ff改為e8 c3 ff ff ff。
4.1.3修改返回地址
通過命令vi pwn20232409_2進入文件,按ESC鍵后輸入:%!xxd將顯示模式切換為16進制模式。通過/d7ff全局搜索d7ff找到需修改的位置,將其修改為c3ff。再通過命令:%!xxd -r轉(zhuǎn)換16進制為原格式,存盤退出。如圖7、圖8所示:


4.1.4檢驗并執(zhí)行文件
再次對文件pwn20232409_2進行反匯編,可以看到原先調(diào)用foo函數(shù)的指令已經(jīng)調(diào)用的是getShell函數(shù)。如圖9所示:

運行修改后文件pwn20232409_2,可以進入shell。如圖10所示:

4.2方法二:Bof攻擊,改變程序執(zhí)行流
4.2.1通過反匯編,了解程序的基本功能
對文件pwn20232409_1(未修改的文件)進行反匯編,觀察foo函數(shù)存在的漏洞。經(jīng)檢查發(fā)現(xiàn),在8048497位置的“l(fā)ea -0x1c(%ebp),%eax”指令只為后續(xù)的讀入字符串預(yù)留了0x1c字節(jié)(即28字節(jié))的緩沖區(qū),因此foo函數(shù)存在緩沖區(qū)溢出漏洞。如圖11所示:

4.2.2確定輸入的位置及字符
使用gdb工具進行調(diào)試,在調(diào)試過程中往foo函數(shù)中輸入超過28字節(jié)的字符串,查看各個寄存器的值,確定需要輸入的地址數(shù)據(jù)。如圖12所示:

在調(diào)試過程中,嘗試輸入字符串1111111122222222333333334444444412345678,發(fā)現(xiàn)寄存器eip的值變?yōu)?x34333231,即得到了輸入1234字符串。于是我們可以得知1234字符串所在的位置最終會覆蓋到堆棧上的返回地址,進而CPU會嘗試運行這個位置的代碼。因此只需將這四個字符替換為getShell的內(nèi)存地址,輸給pwn文件,即可執(zhí)行g(shù)etShell函數(shù)。如圖13所示:

由原先反匯編的結(jié)果可知,此處填入的字符串應(yīng)為0x0804847d,如圖14所示:

4.2.3構(gòu)造輸入的字符串
由為無法通過鍵盤直接輸入\x7d\x84\x04\x08這樣的16進制值,所以使用命令perl生成包括這樣字符串的一個文件。隨后使用xxd命令查看文件內(nèi)容是否正確。如圖15所示:

4.2.4執(zhí)行文件
將文件input20232409通過管道符作為pwn20232409_1的輸入,可以發(fā)現(xiàn)程序可以調(diào)用getShell函數(shù),從而獲得了一個shell。如圖16所示:

4.3方法三:注入Shellcode并執(zhí)行
4.3.1環(huán)境準(zhǔn)備
為了使得實驗成功,此處需要滿足以下五個條件:關(guān)閉堆棧保護;關(guān)閉堆棧執(zhí)行保護;關(guān)閉地址隨機化;在32位操作系統(tǒng)環(huán)境下;在Linux環(huán)境中。后兩個條件在配置環(huán)境時已經(jīng)滿足,現(xiàn)需滿足前三個條件。
首先安裝execstack命令行工具,用于查詢和修改可執(zhí)行文件或共享庫的堆棧執(zhí)行權(quán)限。使用命令apt install execstack即可安裝。如圖17所示:

通過命令execstack -s pwn1,修改可執(zhí)行文件的堆棧執(zhí)行權(quán)限,將堆棧設(shè)置可執(zhí)行,使用命令execstack -q pwn1查詢文件的堆棧可執(zhí)行情況,若返回X,則說明可執(zhí)行;
通過命令more /proc/sys/kernel/randomize_va_space來控制地址空間布局隨機化(ASLR)的級別。其中返回值2表示完全開啟ASLR,即堆棧、堆、庫文件的基址都會隨機化;返回值1表示部分開啟 ASLR,即僅隨機化堆棧、堆、庫文件的基址,但mmap基址固定;返回值0表示完全關(guān)閉ASLR,即所有地址固定。
通過命令echo "0" > /proc/sys/kernel/randomize_va_space將0寫入到/proc/sys/kernel/randomize_va_space文件。用于完全關(guān)閉ASLR,使得程序每次運行時,其堆棧、堆、庫文件的地址都是固定的。如圖18所示:

4.3.2構(gòu)造輸入的payload
由于緩沖區(qū)有28字節(jié),屬于比較大的緩沖區(qū),所以此處采用nop(填充)+shellcode+retaddr(緩沖區(qū))這一構(gòu)造,將shellcode放在緩沖區(qū)的前面。
此處構(gòu)造了一個文件作為pwn20232409_1的輸入。shellcode的地址暫時使用\x4\x3\x2\x1占位,后續(xù)分析得到shellcode的地址后將其替換。如圖19所示:

打開另外一個終端,用gdb來調(diào)試pwn20232409_1這個進程,此處需要先找到進程的ID號,即PID,再根據(jù)其進行調(diào)試。如圖20所示:

通過對函數(shù)foo進行反匯編,可以發(fā)現(xiàn)可以發(fā)現(xiàn)foo的結(jié)束地址是0x080484ae,在此處設(shè)置一個斷點。如圖21所示:

當(dāng)程序運行到斷點時,我們發(fā)現(xiàn)可以發(fā)現(xiàn)esp寄存器的內(nèi)容為0xffffd54c.如圖22所示:

使用命令以16進制形式顯示從地址0xffffd54c開始的一部分?jǐn)?shù)據(jù),發(fā)現(xiàn)此處有注入的0x01020304,這就是返回地址的位置。而shellcode的地址則是0xffffd54c+4=0xffffd550。如圖23所示:

于是應(yīng)當(dāng)將原先的\x4\x3\x2\x1更換為\x50\xd5\xff\xff。新構(gòu)造的輸入文件如圖24所示:

4.3.3執(zhí)行文件
將文件input_shell_20232409_2通過管道符作為pwn20232409_1的輸入,可以發(fā)現(xiàn)程序可以調(diào)用getShell函數(shù),從而獲得了一個shell。如圖25所示:

4.3.4結(jié)合nc模擬遠(yuǎn)程攻擊
使用兩臺互相連通的Linux主機,主機1模擬一個有漏洞的網(wǎng)絡(luò)服務(wù),主機2連接主機1并發(fā)送攻擊載荷。此處的主機1與主機2均為我在華為云平臺上購買的Ubuntu虛擬機,安裝了Kali工具。其中主機一名為biyouchen,主機2名為biyouchen2。兩臺主機的內(nèi)網(wǎng)地址通過ifconfig可以查看,分別為192.168.0.120與192.168.0.58,二者位于同一個網(wǎng)段下。如圖26、27所示:


主機1模擬一個有漏洞的網(wǎng)絡(luò)服務(wù),并啟動監(jiān)聽。利用主機2發(fā)送攻擊載荷,成功獲取了shell。如圖28、29所示:


5.問題及解決
問題一:由于Kali鏡像下載時間過長,我最初嘗試使用Ubuntu24.04 64位鏡像嘗試實驗,但發(fā)現(xiàn)pwn文件無法打開。錯誤原因為:該ELF文件缺少運行時所需的動態(tài)鏈接庫,或者文件架構(gòu)與當(dāng)前系統(tǒng)不匹配。嘗試安裝鏈接庫失敗。
解決一:通過詢問AI,我得知它的錯誤原因是由于24.04版本的Ubuntu太高級無法支持安裝鏈接庫。于是我又購買了Ubuntu20.04 64位鏡像,在其上成功安裝了32位庫以及Kali工具鏈,順利繼續(xù)進行實驗。
問題二:在shellcode注入過程中,我修改了對應(yīng)輸入文件后將其作為輸入,沒有獲得shell,而是提示為段錯誤。
解決二:我仔細(xì)閱讀gitee上的教程后發(fā)現(xiàn),Linux下有兩種基本構(gòu)造攻擊buf的方法,一種是retaddr+nop+shellcode,即把shellcode放在了緩沖區(qū)的后面;另一種是nop+shellcode+retaddr,即把shellcode放在了緩沖區(qū)的前面。我最初在查找需要修改的地址與最后修改時二者沒有對應(yīng),導(dǎo)致明明使用了shellcode在緩沖區(qū)在前的方法卻將其地址修改在了后面,導(dǎo)致跳轉(zhuǎn)出錯,出現(xiàn)了段錯誤。修改了需調(diào)整的地址后,得到了shell。
6.心得體會
本次實驗我學(xué)習(xí)了逆向及Bof基礎(chǔ),學(xué)習(xí)的內(nèi)容有:掌握匯編指令的機器碼、掌握反匯編與十六進制編程器、修改機器指令改變程序執(zhí)行流程、構(gòu)造payload進行bof攻擊。通過直接修改機器指令、進行bof攻擊改變程序執(zhí)行流、注入shellcode三種方式進行了實驗。通過進行實驗,我對于課上所學(xué)的緩沖區(qū)溢出的知識有了更深的體會。
實驗初期,我因使用Ubuntu 24.04系統(tǒng)遇到了32位ELF文件兼容性問題,動態(tài)鏈接庫安裝屢屢失敗。通過咨詢AI得知高版本系統(tǒng)對舊庫支持不足后,更換為Ubuntu 20.04并配置32位環(huán)境與Kali工具鏈。這讓我深刻認(rèn)識到開發(fā)環(huán)境對底層實驗的重要性。
在實驗過程中,我通過反匯編分析機器碼,掌握了一些必要指令的十六進制編碼,成功修改返回地址跳轉(zhuǎn)到getShell函數(shù),直觀理解了程序執(zhí)行流程的控制機制。同時,我也遇到了一些問題,比如我因混淆兩種攻擊構(gòu)造方法(retaddr+nop+shellcode與nop+shellcode+retaddr),導(dǎo)致在shellcode注入中出現(xiàn)了地址跳轉(zhuǎn)的錯誤。經(jīng)反復(fù)調(diào)試并對照教程,才明確需將shellcode置于緩沖區(qū)前部并正確覆蓋返回地址。這讓我對攻擊過程理解更加深入。
總而言之,通過本次實驗,我學(xué)習(xí)了匯編指令與反匯編技術(shù),體驗了獲取shell的諸多方法。我相信本次的實驗會對我未來在網(wǎng)絡(luò)與系統(tǒng)攻防技術(shù)的學(xué)習(xí)有所幫助。
參考資料

浙公網(wǎng)安備 33010602011771號