為什么我的堆疊沒有溢位???
最近在學二進制,垃圾水文,笑一下就好
《網路安全技術原理與實踐》第六章緩沖區溢位攻擊攻擊-課本實驗
案例代碼
先來看書上的代碼
#include<stdio.h>
#include<string.h>
#include<windows.h>
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int main() {
char buff[] = "1234567";
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
bof(buff);
printf("SampleBOF End\n");
return 0;
}
稍微看下邏輯
MessageBox是彈出一個對話框,SampleBOF Test是內容,SampleBOF是標題;在bof函式內部,將buf賦值給temp,由于長度足夠,這個程式正常運行

如果用VS2019編譯,要注意改兩個配置,一個是字符集編碼,還有一個strcpy的安全選項,如下

_CRT_SECURE_NO_WARNINGS

OD除錯
注:不同機子編譯出的地址可能不一樣,而且不同編譯器編譯出來的資訊也不一樣,不需要和試例完全相同
在OD中打開編譯后的二進制檔案
因為帶上了除錯資訊所以我們可以看到函式符號,就和用gcc編譯加上-g引數一樣
$ gcc -g test.c -o test

簡單看一下,找下各個函式地址,玩玩動調
通過搜索字串的功能可以迅速找到main函式

直接點擊用到的字串就可以跳轉到參考的位置,就可以找到相應函式了

緩沖區溢位利用
重新編譯檔案
#include<stdio.h>
#include<string.h>
#include<windows.h>
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int sbofa() {
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
return 0;
}
int main() {
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
char buff[] = "1234567";
bof(buff);
printf("SampleBOF End\n");
return 0;
}
書本上堆疊溢位的意思應該是,沒有用到sbofa函式,想通過strcpy溢位到該函式的回傳地址,并將回傳地址填充為sbofa的地址,最終效果是會有兩個彈窗
再次在OD中打開,查找sbofa的地址,是0x00D710A0

然后更改上方的代碼為
#include<stdio.h>
#include<string.h>
#include<windows.h>
#define TEMP_BUFF_LEN 8
int bof(const char* buf) {
char temp[TEMP_BUFF_LEN];
strcpy(temp, buf);
return 0;
}
int sbofa() {
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
return 0;
}
int main() {
MessageBox(NULL, "SampleBOF Test", "SampleBOF", MB_OK);
char buff[] = "123456781234\xD7\x10\xA0"; // 小端序
bof(buff);
printf("SampleBOF End\n");
return 0;
}
但直接這樣運行顯然是有問題的,就算ASLR關閉,因為代碼被改過并重新編譯,所以sbofa的地址是變過的,不再是0xD710A0
此外默認設定下,發生堆疊溢位時,系統是會檢測到的,當時就給你中斷,掐掉了,并不能直接看到效果
所以一種思路是關閉這些保護,在看雪上看到這篇文章
https://bbs.pediy.com/thread-259665.htm
按照他的關閉這些保護(主要是檢測堆疊溢位和ASLR),然后重做上述步驟,就可以出來結果

課后習題
主要是如何讓程式正常退出吧,顯然我們改了bof的retn地址,程式被我們引到了非預期的地方,在sbofa這個函式的retn,沒有記錄main函式里回傳地址,程式是不會正常結束的
但是根據堆疊溢位原理,我們只要再進行一次溢位,有一種思路是溢位到退出函式的地址,那么程式就能“正常”退出了
我們在OD里繼續除錯,找到使得整個程式退出的函式

并如下修改sbofa函式就可以了
int sbofa() {
char temp[TEMP_BUFF_LEN];
char buffer[] = "123456781234\x8B\x11\x41";
MessageBox(NULL,
"Congratulations!You have the basic principles of buffers overflow.",
"SampleBOF",
MB_OK);
strcpy(temp, buffer);
return 0;
}
分析總結
簡單的堆疊溢位,在windows下的小實驗
emmmmm所以計算更改了原始碼,再次編譯后,函式的地址是不變的?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/355249.html
標籤:其他
上一篇:談一下執行緒之間為什么是不可見的
