掌握緩沖區溢出原理
了解CALL指令和傳回位址的概念
觀察正常程式的棧空間與存在溢出問題程式的棧情況
系統環境:Windows環境
軟體環境:C++ ,ollydbg.exe,idaq.exe
通過向程式的緩沖區(堆、棧等)中寫入超出其長度的資料,造成緩沖區溢出。緩沖區的溢出可以破壞程式執行流程,使程式轉向執行其它指令。利用緩沖區溢出可以達到攻擊主機的目的。
打開Windows7虛拟機,編寫一個overrun.dsw工程檔案。overrun.cpp代碼如下:
代碼中我們建立一個局部空間為8個位元組的buffer字元數組,然後利用strcpy函數将含有7個位元組name字元串中的資料拷貝到buffer數組中,運作程式,字元串輸出正常,按下回車,顯示正常。如下圖所示程式正常運作:

分析當name數組中資料超過8個位元組的情況,将代碼段name字元串修改長度為10個字元“overrun123456”,overrun.cpp代碼如下:
此時将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都被字元串所覆寫,實驗程式跳轉至錯誤的傳回位址處沒有任何指令,故程式報錯。
整理整個分析過程可以得知,本次實驗中導緻緩沖區溢出的原因是因為代碼編寫的不規範,導緻程式運作過程中傳回位址被覆寫,進而使得程式錯誤的運作。倘若覆寫傳回位址的資料為攻擊者精心構造的資料,那麼程式就會按照被覆寫資料的引導來執行,進而達到攻擊者某些不可告人的目的。