有關堆疊溢位的相關知識
最近學校講到了堆疊溢位,并有一道很基礎的題,在此可以記錄一下,感興趣的人可以了解了解.
/
堆疊溢位:
/
首先談到堆疊溢位,要先說windows系統典型漏洞分析,
/
堆疊溢位也是其中的一種,
/
要了解堆疊溢位,要先了解:
1.主角:堆疊 與 堆疊幀
堆疊(音:zhan四聲)是一種特殊的線性計算機內部存盤結構,服從先進后出的一種特殊線性結構,如同彈夾里的子彈,先放入的子彈,在最下面,堆疊的結構使其只能在堆疊的頂端進行增加資料和洗掉資料的操作,壓入資料稱為(push),彈出資料稱為(pop).
/
2.記憶體結構
在win32環境下,由高級語言生成的可執行檔案,即PE檔案,(Portable Executable)檔案,在運行可執行檔案時,系統會將其加載到記憶體,并映射出4GB的虛擬存盤空間,然后繼續運行,形成所謂的行程空間,(教材原話)
/
在win32中將行程使用的記憶體按功能可以分為4個區域,如下圖:
/
| 名稱 | 作用 | |
|---|---|---|
| 堆疊區(stack) | 用于動態存盤函式之間的呼叫關系 | 低地址 |
| 堆區 | 該記憶體區域由行程利用相關函式和運算子動態申請 | |
| 代碼區 | 存放程式匯編之后的機械代碼和只讀程式,計算機運行程式,會在該區域讀取命令并執行, | |
| 資料區 | 用于存盤全域變數和靜態變數 | 高地址 |
/
其在計算機記憶體中的結構也如下圖:
| 堆疊區 | ↑堆疊增長方向 |
| 堆區 | ↓堆增長方向 |
| 代碼區 | |
| 資料區 |
代碼實作
/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void attack()
{
printf("TRY IT!.\n"); //attack函式
}
void func() //func函式
{
char password[6] = "ABCDEF";
char str[6];
FILE *fp;
if(!(fp=fopen("D:\\password.txt","r"))) //打開D盤的password.txt檔案
exit(0);
fscanf(fp,"%s",str); //將str的內容寫入fp
str[5]='\0';
if(strcmp(str,password)==0) //判斷str是否與password相同
printf("OK.\n");
else
printf("NO.\n");
}
int main()
{
func(); //運行func函式
return 0;
}
/
用軟體IDA實作堆疊溢位實驗(步驟)
/
在D盤的password.txt中輸入一定量的字串,運行程式,AAAAA…與指定的password并不相同,所以回傳了“NO”,
現在打開IDA.
1.打開

得到如下:
/
/
現在展示的IDA適用靜態除錯,左邊可以清晰地看到函式體,這是IDA比較清晰簡便的一個優點,
2.尋找函式名稱

點擊左側的函式名可以進入,右側也可以查看十六進制視圖:
IDA快捷鍵,按F5可以查看偽代碼,偽代碼可以讓人較為清晰地了解函式的部分構造,但不是能運行的代碼,在這里,用滑鼠左鍵雙擊左側函式名稱中的func(),再按F5可以進入func函式查看偽代碼:
3. F5查看偽代碼


在上圖中點擊各個變數,可以查看堆疊,
4.查看堆疊

查看到str,password,fp在堆疊中的位置
/
注意到最下面有一個"r"
/
這里"r"指的是return adress,這里簡述為ret,ret指的是回傳地址,ret在匯編中也有涉及,
這里的ret主要功能是回傳下一個函式的地址,用于在一個函式運行完后跳轉到下一個函式,堆疊溢位攻擊在這里運行的原理是,通過文本中讀入過量的資料,從而,是資料在堆疊上溢位,使其覆寫正常的資料,從而引起漏洞與例外,
/
如果,溢位的資料覆寫了ret地址,那么函式可以跳轉到一個指定的函式,即上文的“attack”函式,
/
所以在這里開始,找到attack函式的地址:

然后,只要將attack()的地址,輸入到文本的末尾即可,但是,要滿足其剛好能將ret的地址覆寫,使函式跳轉例外,從而跳轉到指定的攻擊函式,
/
那么,來計算一下,在文本中輸入多少個字符會剛剛覆寫到“r”,處:
/
這里查看到這個資訊: [esp+10h] [ebp-18h] (如下圖)
/
5.分析怎么實作堆疊溢位

由于記憶體堆疊區的地址由高地址向低地址增長,當4個位元組壓入堆疊幀時,即為 ESP=ESP-4, 有4個位元組彈出堆疊幀時, ESP=ESP+4.
ESP(extended stack point)是擴展堆疊指標暫存器,其存放地址指向這個堆疊幀的堆疊頂
/
EBP(extended base point)是擴展基址指標暫存器,其存放地址指向這個堆疊幀的堆疊底,
/
ESP與EBP之間是當前堆疊幀的空間,
上圖意為,從前堆疊底到str存放的位置還有18個位元組,即[ebp-18h]的含義,
其實從IDA中也能清晰看出來:

上圖中,可以看到變數str,password,fp存放在堆疊中的位置,可以看到上圖用紅色框框選的,有18個位元組,也就是上文的[ebp-18h],下面藍色框有10個位元組,即到r為止,
/
資料從上方加入,那我們只要在文本前加入(10+18)=28個位元組,就可以剛剛覆寫到r處,r是運行完后要跳轉的函式地址,那我們在28個直接之后加入,攻擊函式attack()的地址即可,
/

將D盤的password.txt檔案拖入軟體“HxD”中,一種文本編輯軟體,notepad++也可,
輸入28個字母,之后將attack()的地址加入,即"00 40 13 50",但這里是小端序,
這里講一講:
6.小端序和大端序
位元組序即為多位元組物件存盤在記憶體中的位元組順序,有兩種不同的存盤方案:大端法和小端法,現代的處理器大多為雙端法,大小端都支持,可以配置稱大端法或者小端法,
/
大端序:(Big-endian):高位位元組存入低地址,低位位元組存入高地址
小端序:(Little-endian):低位位元組存入低地址,高位位元組存入高地址
7.繼續,運行結果,原理
一般x86位的CPU都為小端序:所以在編輯時將地址反著寫,寫作"50 13 40 00",
然后,點擊“保存”檔案,
/
再打開編譯器,運行:
/

運行結果出現了TRY IT!,明顯這是attack()函式的內容,已經完成了堆疊溢位,使函式運行出了指定的內容,這就是用IDA實作的簡單的堆疊溢位攻擊實驗,
/
通過堆疊上資料的溢位,覆寫了,正確的r回傳地址,從而使函式跳轉出現失誤,或指向性的跳轉,可以加以利用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/167949.html
標籤:其他
