Windows下堆棧溢出入門


二進制的學習首先從《黑手緩沖區溢出教程》一書開始,由於自己基礎差,學習起來極其慢,這兒就先簡單整理下本書第一章的一些重點知識。

一、緩沖區溢出

1. 緩沖區溢出原理

(1)緩沖區
計算機內部用於存放輸入數據的臨時空間。
(2)緩沖區溢出
緩沖區內填充數據,如果數據的長度很長,超過了緩沖區本身的容量,那么數據就會溢出存儲空間,裝不下的數據就會覆蓋在合法數據上,這就是緩沖區溢出的道理。
(3)緩沖區溢出的利用
引導溢出的數據,使計算機執行我們想要的命令。

    注:理想情況下,程序檢查每個數據的長度,並且不允許超過緩沖區的長度,但有些程序會假設數據長度總是與所分配的存儲空間相匹配,而不去檢查,從而為緩沖區溢出埋下隱患。

2. windows系統緩沖區溢出例子--報錯對話框


    #include<stdio.h>
    #include<string.h>

    char name[] = "ww0830";
    int main(){
        char output[8];
        strcpy(output,name);

        for(int i=0; i < 8 && output[i]; i++)
	        printf("\\0x%x",output[i])

        return 0; 
    }

    分析:對於上述這個打印字符串"ww0830"的十六進制的程序,核心是strcpy函數,它的目的是將name變量的值復制給output變量,只給output變量分配了8個字節的空間,因此會出現隱患:當變量name的長度大於output的長度8時,復制后就會出現溢出情況,如下圖所示:

    注:此報錯信息只能在xp以及之前的系統出現,win7之后的系統報錯的情況如下圖所示(二者報錯的具體原因都一樣,只是表現形式不同):

3. 初識堆棧

(1)堆棧
計算機為了能回頭繼續處理原來的事情,需要把原來指令的指針EIP保存在堆棧中,當要回去原來的地方時,就把保存在堆棧中的EIP恢復即可。並且各個函數的局部變量的分配也是在堆棧中。
(2)中斷
指計算機運行過程中,出現某些意外情況需主機干預時,機器能自動停止正在運行的程序並轉入處理新情況的程序,處理完畢后又返回原被暫停的程序繼續運行。
(3)堆棧規則
堆棧是一種數據結構,遵循 “先進后出,后進先出”的規則。操作系統中,存和取的動作是Push和Pop,Push放一個數據到堆棧中去,Pop取一個堆棧中的數據出來。

4. 緩沖區溢出的簡單利用

緩沖區溢出利用的步驟:
(1)找到返回點定位
(2)ShellCode的編寫
(3)把返回點覆蓋成ShellCode的地址

5. 返回點覆蓋方法

(1)NNNNNSSSSSRRRRR 型
此種方法適合於大緩沖區,"N"代表空指令,也就是0x90。在實際運行中,程序將什么也不做,而是一直沿着這些Nop運行下去,直到遇到不是Nop的指令再執行之;"S"代表ShellCode;"R"代表覆蓋的返回地址,思路就是把返回地址R覆蓋為Nop的大概位置,這樣就會跳到Nop中,然后繼續執行,直到ShellCode。
(2)RRRRRNNNNNSSSSS 型
此種方法是用大量的"R"填滿整個緩沖區,然后大量的Nop,最后是ShellCode。這里“R”往后跳到Nops中,再順着往下執行就會到ShellCode中。但在Windows下,“R”中必定會含有0,這樣,整個構造就會被截斷,只能用於Unix中。

    注:直觀理解----方法(1)原理:這種是指在buffer區放置Nop和shellcode代碼以及部分ret值,然后直到在EIP處被ret值所覆蓋掉,這個ret值就指向buffer中的Nop區域,這樣可以一直執行直到執行了shellcode,彈窗成功!(由buffer區到EIP處,然后又回到buffer區);方法(2)原理:這種就是在buffer區放置比shellcode地址高一些的某個固定地址值ret(這個固定值會指向Nop),直到覆蓋掉EIP處,那個固定地址被Nop所覆蓋,然后會一直讀取直到讀到shellcode,然后執行,彈窗!(由buffer區到EIP處,然后跳出到shellcode之前的Nop處)

6. 小知識

(1)ESP:棧指針(Extended stack pointer),用於指向棧的棧頂(下一個壓入棧的活動記錄的頂部)。
(2)EBP:擴展基址指針寄存器(extended base pointer) 其內存放一個指針,該指針指向系統棧最上面一個棧幀的底部。
(3)EIP: 用來存儲CPU要讀取指令的地址,CPU通過EIP寄存器讀取即將要執行的指令。
(4)Windows 通過動態鏈接庫(dll)來提供系統函數。
(5)Windows下堆棧的分配是從高地址往低地址分配的。
(6)二進制漏洞:二進制文件(如PE文件、ELF文件等)中存在的漏洞。

二、漏洞認識及利用

1. 漏洞認識及利用的一般步驟

(1)查看漏洞公告
① 首先要注意是什么程序、它的什么版本有漏洞。找出有問題的的版本,就安裝上相應的版本,寫出對它的溢出攻擊程序;
② 給出大概的問題分析,查看有問題的是某個PE文件(如punylib.dll)。在安裝目錄的子目錄下發現它;
③ 給出漏洞的解決辦法或補丁下載。
(2)查看漏洞分析報告
漏洞公告是不會給我們說如何利用漏洞的。所以除了查看漏洞公告,我們還要查找其他人或安全組織的相關漏洞分析報告。
(3)寫漏洞利用程序(如緩沖區溢出漏洞)(標准緩沖區堆棧溢出利用的標准方法)
要成功利用緩沖區溢出需要的三個條件:
① 有問題程序返回點的精確位置――我們可以把它覆蓋成任意地址;
② ShellCode――一個提供給我們想要的功能的代碼;
③ JMP ESP的地址――把返回點覆蓋JMP ESP的地址,這樣可跳入ShellCode。

2. 通用的JMP ESP地址

中文版Win2000、XP、Win2003的JMP ESP通用跳轉地址(lion給出的0x7ffa4512)

3. 精確定位有問題程序返回點的方法

(1)先用大字段的字符串覆蓋buffer區,使出現read或者write錯誤,當出現write錯誤時,意味着覆蓋的過多,導致一些參量地址被覆蓋;
(2)再采用二分法,直到錯誤類型改為read類型,接下來定位返回點的位置;
(3)使用緩沖區字符串的填入方法:
① buffer[i] = "A" + i % 10 取余數,字符串會在 A-J (0x41-0x50)之間循環;
② buffer[i] = "A" + i / 10 取整除的數, 字符串會以 AAAAAAAAAABBBBBBBBBBCC...這種形式存在,每10個后出現下一個字母。
這樣結合兩種就可以定位到程序返回點的位置。比如:① 報錯 4A494847,② 報錯 5A5A5A5A,那么返回點的位置就是:(0x5A-0x41)*10+(0x47-0x41) = 256 那么從第257個字段開始的位置為返回點位置。

4. 小知識

(1)EAX : "累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
(2)EBX : "基地址"(base)寄存器, 在內存尋址時存放基地址。
(3)ECX : "計數器"(counter), 是重復(REP)前綴指令和LOOP指令的內定計數器。
(4)EDX : 用來放整數除法產生的余數。
(5)EBP : "基址指針"(BASE POINTER), 它最經常被用作高級語言函數調用的"框架指針"(frame pointer)。

三、總結

本書的第一章利用幾天時間看完了,主要講的是windows下緩沖區溢出漏洞的原理、利用方法以及漏洞利用返回點的定位等。通過幾天的學習,自己對於二進制漏洞的基本知識有了初步認識,並且知道了什么是緩沖區漏洞,簡單認識了匯編語言、基本指令、幾個基本寄存器等。這算是給二進制學習打了個頭,有了個直觀的認識。但是在學習的過程發現一些問題:
(1)第一次接觸二進制,第一次接觸這本書,發現書中的知識點多而且雜,看了一遍之后發現並沒有記住多少,后續學習需要反復看,經常回頭復習;
(2)文章中給到很多漏洞實例,例如Foxmaiil,Printer,IIS等的早期漏洞,只看書本上講的理論認識不夠充分,確實需要實踐來發現問題,目前因為一些設備原因無法實踐,后期有條件了都需要動手操作,復現漏洞;
(3)自己底子差,對於很多不理解的知識需要多百度,多花時間去學習。
學習二進制知識有幾天時間了,希望在后面的日子里自己能腳踏實地,一步一個腳印,不氣餒,不浮躁,爭取學到肚子里......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM