## 一.實驗環(huán)境:
```
操作系統(tǒng) Windows XP SP3
開發(fā)環(huán)境 VC++ 6.0
調試器 Ollydbg
```
## 二.實驗代碼:
```
#include <stdio.h>
#include<string.h>
#define PASSWORD "1234567"
int verify_password (char *password)
{
int authenticated;
char buffer[8];
authenticated=strcmp(password,PASSWORD);
strcpy(buffer,password);
return authenticated;
}
main()
{
int valid_flag=0;
char password[1024];
while(1)
{
printf("please input password: ");
scanf("%s",password);
valid_flag = verify_password(password);
if(valid_flag)
{
printf("incorrect password!nn");
}
else
{
printf("Congratulation! You have passed the verification!n");
break;
}
}
}
```
## 三.溢出原理
程序未對輸入的密碼進行長度檢測,,接收密碼的緩沖區(qū)只有8,而輸入的密碼最長可以輸入1024,。判斷密碼是否正確的變量authenticated存儲在棧中,,當輸入的密碼長度大于8時,,輸入的字符串將沖破緩沖區(qū),淹沒authenticated所處的位置,。當密碼錯誤時authenticated的值是1,,正確的時候authenticated的值是0.這就意味著我們可以構造一個合適的輸入字符串來改變判斷結果。
## 四.實戰(zhàn)調試
我們的重點不是逆向工程,,而是漏洞分析,,故此不再詳訴諸如尋找main函數(shù)等逆向知識。
1.在jmp mai下斷點,,方便后續(xù)反復調試
![圖片描述](/upload/attach/201811/201811281016_RSU94EXGY2ANDNK.png)
2.單步步入main函數(shù)分析程序
![圖片描述](/upload/attach/201811/201811281017_J23FBFCJTGBB57B.png)
3.分析main函數(shù)邏輯,,可以看出主要問題出在密碼比對函數(shù)00401005
3.1輸出引導字符串后,要求用戶輸入密碼,。
![圖片描述](/upload/attach/201811/201811281017_9GPNXMB4X9DGTHS.png)
3.2通過00401005處的函數(shù)進行密碼比對
![圖片描述](/upload/attach/201811/201811281018_XXU7U29EPD6884H.png)
3.3判斷比對結果是不是0,,如果是0則輸出成功字符串,如果是1則輸出失敗字符串,。
![圖片描述](/upload/attach/201811/201811281018_8E4XWEYCR9399GM.png)
4.單步執(zhí)行程序,,隨便輸入一個密碼,然后單步步入00401005函數(shù),,分析這個函數(shù)的內容,。
![圖片描述](/upload/attach/201811/201811281018_KR39VDTCXVPQNB9.png)
4.1可以看出這個00401005是個跳轉,直接單步進入函數(shù)真實位置,。
![圖片描述](/upload/attach/201811/201811281018_MDE763Y9E9US7A8.png)
4.2進入到函數(shù)內部后可以看到真正的密碼是1234567,,如果我們是在逆向破解這個程序,那么到了這一步,,就已經(jīng)算是成功了,。但是我們的目的是分析漏洞,所以我們現(xiàn)在進一步分析這個函數(shù),。
![圖片描述](/upload/attach/201811/201811281019_KZ8WYXPAS5VBT92.png)
4.2.1可以看出,,在strcmp之后,ebp-4的位置上就有了密碼比對的結果
4.2.1.1strcmp比對密碼,,將比對結果存入ebp-4的位置上
![圖片描述](/upload/attach/201811/201811281019_D4KJNBPM4SHJYVC.png)
4.2.1.2棧中的密碼比對結果
![圖片描述](/upload/attach/201811/201811281019_CEPWYM3SUZQR85S.png)
4.2.2如果是正常的程序,,這個時候就應該返回了,但是因為是實驗代碼,,所以下面還有一個strcpy的拷貝函數(shù),,將輸入的密碼字符串拷貝入一個長度為8的緩沖區(qū)中。
![圖片描述](/upload/attach/201811/201811281019_JEUJVBG2UAXBGUW.png)
4.2.3當執(zhí)行完strcpy的時候我們看一下堆棧區(qū),可以看到字符串緩沖區(qū)的位置就在密碼字符串比對結果旁邊,,并且strcpy沒有對拷貝入的字符串進行長度判斷,。因此我們可以判斷,我們在構造一個合適的字符串傳入的情況下,,是可以覆蓋密碼字符串比對結果的,。這也意味著我們可以傳入一個合適的字符串來沖破密碼驗證。
![圖片描述](/upload/attach/201811/201811281020_FBYCZBNZTXJSPXB.png)
5.我們重新加載這個程序,,并且傳入一個特定的字符串“qqqqqqqq”
![圖片描述](/upload/attach/201811/201811281020_PHZM85HZWD9Y95G.png)
6.運行到密碼比對函數(shù)進行分析
6.1可以看出strcmp函數(shù)沒有任何問題的執(zhí)行成功并且返回了1,代表密碼錯誤,。并且把存儲在eax中的返回值存儲到ebp-4的位置上,。
6.1.1函數(shù)執(zhí)行
![圖片描述](/upload/attach/201811/201811281020_M8GBB2SETAADX47.png)
6.1.2返回值存儲在eax中
![圖片描述](/upload/attach/201811/201811281020_GF6P7K8ZE3U5KK7.png)
6.1.3 eax中的值mov到了ebp-4的位置上
![圖片描述](/upload/attach/201811/201811281020_JFTRC4N2YQ65636.png)
6.2下面到了引起溢出錯誤的strcpy函數(shù),詳細分析該函數(shù)溢出的過程,。
6.2.1首先記錄一下strcpy沒有執(zhí)行前堆棧的情況
![圖片描述](/upload/attach/201811/201811281021_843XH6HCP65AQS6.png)
6.2.2 執(zhí)行strcpy函數(shù)
![圖片描述](/upload/attach/201811/201811281021_CUN3HG8CABXJW98.png)
6.2.3 可以看到,,堆棧中原本保存著密碼比對結果的位置ebp-4,由于傳入字符串超長,,已經(jīng)被覆蓋成了0,。這樣一來,原本比對失敗的結果就變成了比對成功,。
![圖片描述](/upload/attach/201811/201811281021_W7S2DVTN48WKWHS.png)
7.運行至返回,,成功輸出密碼比對成功的信息
![圖片描述](/upload/attach/201811/201811281021_K78ETMGTJZ8E9CN.png)
7.1控制臺成功信息
![圖片描述](/upload/attach/201811/201811281022_2SXAPW82MUSS7HU.png)
8.那么是任何長于1234567的字符串都可以成功覆蓋比對結果嗎,嘗試一下,,輸入9個q,,可以看到,對比結果的位置上并沒有被覆蓋成00,,而是71,,而只有對比結果等于0才可以成功驗證。這說明不是任意長度字符串都可以,。
![圖片描述](/upload/attach/201811/201811281022_ZWAU98TSFPEPZFK.png)
9.那么有什么結果可以覆蓋成整好是0呢,,那么答案是長度為8的字符串,長度為8的字符串實際長度為9,,因為還有用來標記字符串結束的00,,我們就是要使用結尾處的00來覆蓋對比結果,使其數(shù)值為0,。
![圖片描述](/upload/attach/201811/201811281022_76KK6WHB964G6JP.png)
參考材料:《0day安全:軟件漏洞分析技術》