一、實驗目的
- 掌握緩沖區溢出原理
- 理解CALL指令和返回地址的概念
- 觀察正常程序的棧空間與存在溢出問題程序的棧情況
二、實驗環境
- 系統環境:Windows環境
- 軟件環境:C++ ,ollydbg.exe,idaq.exe
三、實驗原理
- 通過向程序的緩沖區(堆、棧等)中寫入超出其長度的數據,造成緩沖區溢出。緩沖區的溢出可以破壞程序執行流程,使程序轉向執行其它命令。利用緩沖區溢出可以達到攻擊主機的目的。
四、實驗步驟
- 打開Windows7虛擬機,編寫一個overrun.dsw工程文件。overrun.cpp代碼如下:
#include "stdio.h"
#include "string.h"
char name[]="overrun";
int main()
{
char buffer[8];
strcpy(buffer,name);
printf("%s\n",buffer);
getchar();
return 0;
}
- 代碼中我們創建一個局部空間為8個字節的buffer字符數組,然后利用strcpy函數將含有7個字節name字符串中的數據拷貝到buffer數組中,運行程序,字符串輸出正常,按下回車,顯示正常。如下圖所示程序正常運行:
- 分析當name數組中數據超過8個字節的情況,將代碼段name字符串修改長度為10個字符“overrun123456”,overrun.cpp代碼如下:
#include "stdio.h"
#include "string.h"
char name[]="overrun123456";
int main()
{
char buffer[8];
strcpy(buffer,name);
printf("%s\n",buffer);
getchar();
return 0;
}
- 此時將name[ ]13個字符大小的數組復制到buffer[8]數組中,再次運行程序,字符串輸出正常,按下回車,出現錯誤。如下圖所示:
- 此時查看問題詳細信息,可以發現異常偏移:00000036說明緩沖區溢出了導致程序運行發生錯誤。
正常程序分析:
-
對於上述兩種情況,首先分析正常程序。使用ollydbg.exe程序,將實驗程序文件overrun.exe拖入其中,如下圖所示:
-
本次實驗我們需要分析main函數,所以需要判定main函數的地址以及定位調用main函數的語句。首先打開idaq.exe程序,將正常程序overrun.exe拖入其中。如下圖所示:
-
然后雙擊jmp_main_0,按下空格鍵,找到main函數的地址為00401010(數據以實際情況為准),如下圖所示:
-
在ollydbg.exe界面左上角地址欄點擊右鍵,選擇Go to,選擇Expression,在彈出的搜索欄中輸入已獲取的main函數地址,點擊ok按鈕。如下圖所示:跳轉至main函數地址
-
獲取main函數位置之后,如下圖所示我們可以知道main函數由00401005處的語句跳過來。由於緩沖區溢出與棧空間緊密相關,現在我們來分析調用main函數前后棧空間的情況,如下圖所示:main函數由00401005處的語句跳轉
-
接下來定位調用main函數的call語句。在idaq.exe界面中,點擊main函數地址出,按下ctrl+x組合鍵,顯示由call_main_0跳轉到當前位置,按下ok按鈕跳轉至call_main_0,如下圖所示:
獲取調用main函數的位置00401694
-
在ollydbg.exe中跳轉至call main函數的位置00401694(數據以實際情況為准),如下圖所示:
-
接下來分析調用call main函數前后棧空間的情況。一般當程序執行call的時候,會分為兩步,第一步將call語句下一條語句的地址入棧,第二步jmp跳轉至call語句所在地址的位置。當call語句執行完之后程序會將下一條語句的地址出棧,告訴程序call語句執行完之后繼續執行這個地址的指令,我們一般將這個地址稱為返回地址。如下圖所示,下一條語句的地址為00401699
-
點擊00401694處然后按下F2添加斷點,按F9執行當前斷點位置,再按F7單步執行進入main函數,發現下一條語句的地址00401699入棧,如下圖所示:
-
源程序中首先創建了8個字符大小的char數組,當我們進入main函數的時候,首先會給這個局部變量分配空間。按F8繼續執行push ebp指令。觀察棧頂情況發現EBP入棧。繼續按F8執行完SUB ESP,4C后觀察棧的情況,發現已經分配相應空間。如下圖所示:EBP入棧
-
按F8繼續執行完
后觀察棧的情況,發現分配的局部空間被CC填充。程序為了容錯性以及自身的健壯性會用CC(int 三斷點)填充,如果有未知的程序跳轉這邊區域便不會出現崩潰的情況,如下圖所示:局部空間被CC填充
-
按F8繼續執行至下一條call指令,程序可以正常跳轉至00401699處執行,如下圖所示:call調用的函數地址為00401005
異常程序分析::
-
接下來分析溢出程序調用strcoy前后棧的情況,在工具軟件安裝包中打開ollydbg.exe和idaq.exe程序,分別將實驗程序overrun.exe拖入其中,此處步驟和上面步驟同理省略…
-
進入idaq.exe界面調轉到00401694
-
發現返回地址和EBP都被字符串覆蓋
結論:通過實驗發現返回地址和EBP都被字符串所覆蓋,實驗程序跳轉至錯誤的返回地址處沒有任何指令,故程序報錯。
整理整個分析過程可以得知,本次實驗中導致緩沖區溢出的原因是因為代碼編寫的不規范,導致程序運行過程中返回地址被覆蓋,從而使得程序錯誤的運行。倘若覆蓋返回地址的數據為攻擊者精心構造的數據,那么程序就會按照被覆蓋數據的引導來執行,從而達到攻擊者某些不可告人的目的。