實驗代碼
https://github.com/TouwaErioH/security/tree/master/stack%20overflow
實驗目的
Buffer over flow 漏洞利用實踐
實驗內容
編寫exploits攻擊漏洞程序
實驗結果
獲取具有root權限的shell
實驗環境
Windows10
Oracle VM VirtualBox
Ubuntu16.04 i386
Sudo apt-get prelink
Exploits 攻擊程序。Vulnerables 目標程序
准備
Vulnerable 文件夾 編譯,安裝 Make Sudo make install
安裝到了根目錄 /tmp 文件夾。
Exploits 編譯 Make
先關閉地址隨機化 sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
七、實驗步驟
1.vul[1-6]的簡單描述
1.1 vul 1
查看Vul1 源代碼可知其中存在strcpy函數,當各種保護機制未開啟時,容易利用strcpy實現緩沖區溢出。Vul 1 沒有做邊界的檢查,直接拷貝argv[1]數組到buf數組,當argv[1]數組大小大於buf數組時,超出的字節會覆蓋掉foo函數的ebp,返回地址等內容,當函數返回時讀取返回地址,只要修改返回地址為shellcode的起始地址,就可以執行shellcode,進而獲得shell。
2.shellcode(構造過程)
原理是運行/bin/sh 來得到shell,構造過程是將具有運行/bin/sh的C代碼轉換成有相同功能的機器碼。注意代碼中用到 0 的地方改成用 xor eax,eax,這樣可以避免復制字符串時遇到/0 中斷。
下面的shellcode長度為45字節(不含/0)
/*
* Aleph One shellcode.
*/
static const char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
3.exploit[1-6]攻擊方式描述(攻擊原理,payload構造方式,攻擊過程描述)
3.1 exploit1
查看exploit1,框架已經搭建好,只需要替換其中的”hi there”為設計的payload
Payload由三部分組成,shellcode(獲取shell的機器碼),目標地址(返回地址設置為shellcode),nop(填充,使得能返回到shellcode)
下面是shellcode。執行exec(“/bin/sh”)的機器碼。執行/bin/sh 可以獲得root權限
如圖,payload要覆蓋調buf數組,長度要大於256,所以需要填充nop
以vul1為例介紹如何獲得地址
安裝git-peda
其含有漏洞的代碼如下。由源碼可見Buf256字節,向上覆蓋foo的返回地址還需要覆蓋ebp(4字節),ret(4字節),所以payload需要256+8=264字節
Exploits.c先填充shellcode,再填充nop,最后填充地址
Shellcode 45字節(除最后的\0)
先填充shellcode再填充nop是因為內存中數組地址從低到高,棧方向從高到低,覆蓋掉返回地址后返回到shellcode地址。
45+(256-45)*NOP覆蓋到buf,+4nop覆蓋ebp,最后四字節覆蓋ret
修改exploits1.c
修改exploits1.c后重新make生成生成新的exploit可執行文件
這里最后覆蓋的地址0xbffffc4c獲取方法見下。一開始隨便填都可以。
在vul目錄下,調試vul1 可執行文件。
含有strcpy的函數為bar(第一句直接調用),foo調用,先找到foo調用bar的地址
找到調用bar位置為0x080484fc
換到exploitmulu,調試
gdb –e exploit1 –s /tmp/vul1 執行exploit1,從指定文件vul1讀取符號表
- catch exec 在exploit執行exec的位置設斷點
- r
- b *0x80484fc
- c
- ni
- find 0xd231c931
報錯"/home/erio/Desktop/proj1/exploits/exploit1" is not a core dump: File format not recognized
檢查源文件meiwent。發現是輸入的時候直接copy的,可能有干擾。手打gdb -e exploit1 -s /tmp/vul1就沒問題了
Run
執行到exec剛剛知道bar的地址是 0x080484fc,在這里設置斷點,c運行
此時暫停到foo調用bar的位置,因為strcpy就在bar第一句,只執行一步就可以得到地址。
使用ni 進入bar函數內部
現在在strcpy內部
Payload中最開始是shellcode,shellicode前4字節為 0x895e1feb (注意小端)
Find 0x895e1feb
找到地址在0xbffff1c4c,所以剛剛的payload最后四字節填 0xbfff1c4c。因為payload最后四字節溢出覆蓋掉了foo的返回地址(不是bar的),strcpy是直接填了foo中buf。然后bar結束,棧回收只是esp,ebp改變,shellcode其實還在內存中,foo返回時eip跳到shellcode起始處,然后把shellcode的字符串當成機器碼執行,eip++。
正確修改payload最后四位為0xbffff1c4c后,執行exploit1,效果如下,得到了root權限
另
還可以參考:
https://blog.csdn.net/qq_36779888/article/details/89682728