日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言实现缓冲区溢出实例

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言实现缓冲区溢出实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考書目:0day安全:軟件漏洞分析技術?
相關工具使用:OD,IDA Pro,VC++6.0,UltraEdit

最近需要做課堂演習,就選了緩沖區溢出的實踐。主要參考0day安全這本書,一面一句話很經典:?
To be the apostrophe which changed Impossible into I’m possible!

直接步入正題:

1. 反匯編修改程序

在實現緩沖區溢出之前,簡單熟悉一下反匯編重用的兩個軟件,OD和IDA,用OD修改程序代碼實例。

#include <stdio.h> #define PASSWORD "1234567" int verify(char *password) {int auth;auth = strcmp(password, PASSWORD);return auth; }int main(void){int flag = 0;char pass[1024];while(1){printf("enter the password:\t");scanf("%s", pass);flag = verify(pass);if(flag)printf("password incorrect!\n");else{printf("congratulation!\n");break;}} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

代碼就是簡單驗證輸入密碼是否正確,首先用IDA打開編譯生成的應用程序。看到這樣一個圖(好像每次打開生成的東西都不太一樣~)?

如果看不到地址可以在Options->General在Line prefixes前打鉤以及將Number of opcode bytes設置為6就可以了。這樣就可以找到代碼中相應的跳轉部分,然后用OD打開對應的EXE文件,看到下圖:?
?
找到004010D5這條命令就是對應的判斷地方了,對應的匯編命令為:

JE X1.004010E6
  • 1
  • 1

于是將JE改成JNE,再運行程序,這時發現原來正確的密碼不正確,原來錯誤密碼都可以通過!用OD還可以對程序保存,一個簡單的破解就完成了。(OD保存軟件不會的話可以網上搜一下,我當時沒搞懂還是請教的大神)

2. 緩沖區溢出漏洞修改鄰接變量

還是剛剛的類似程序,假如程序員一不小心或者因為要在其他地方使用字符串,加了個strcpy函數,驗證函數如下所示:

int verify(char *password) {int auth;char buffer[8];auth = strcmp(password, PASSWORD);strcpy(buffer, password);return auth; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
看似還是正常的一個程序卻會發生不可思議的事情,不信運行程序輸入qqqqqqqq試試,發現沒,通過驗證了!這是為什么呢?來看看棧里面數據的存放:

?
啊,原來是這樣啊,輸入qqqqqqqq,或者輸入其他8位也行(11111111不行,自己探索吧)在strcmp的時候auth確實是1,但是在進行strcpy之后,buffer里面的數據太長了,占了auth的位置,將auth從1改成了0。?
看來下次寫程序要注意點了!

3. 修改程序執行流程

是看了上面的原理圖,是不是懂了點什么!EBP和返回地址是啥?不禁心生惡意,我要是再長點,是不是把返回地址給換了???還有那個EBP啥東西???

事實上,EBP是PE文件執行時候在函數調用時函數調用前棧底指針,在函數調用時會重新生成一個比較小的棧,此新棧為調用的函數所用,因此需要將之前棧的棧底入棧。在調用新的子程序的時候,也需要將子函數的返回地址入棧,不然子函數執行完了,計算機就不知道下一步執行什么了~

搞懂了這點知識,我們就可以利用這個來修改程序的執行流程了,具體實驗可以自己做。

4 代碼植入

之前例子的緩沖區較小,正常的函數中如果使用的話,緩沖區可能是比較大的,下面用新的例子來測試緩沖區溢出中的代碼植入,完整的代碼見上傳的文件。

int verify(char *password) {int auth;char buffer[44];auth = strcmp(password, PASSWORD);strcpy(buffer, password);return auth; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

此次的實驗中由于控制臺輸入的限制性,將輸入流改為文本。實驗的目的是利用緩沖區溢出漏洞植入代碼,代碼內容為彈出一個新的窗口。

int MessageBox(HWND hWnd, // handle of owner windowLPCTSTR lpText, // address of text in message boxLPCTSTR lpCaption, // address of title of message boxUINT uType // style of message box );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

上面是MessageBox的四個參數,如果彈出標題和內容都是hellobug的串,四個參數分別為:?
NULL, “hellobug”, “hellobug”, NULL?
根據MessageBox得到應該執行的匯編代碼

Xor ebx, ebx Push ebx Push 68656C6Ch Push 6F627567h Mov eax, esp Push ebx Push eax Push eax Push ebx MOV EAX, ADDRESS CALL EAX
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最后的Address是MessageBoxA地址,對應的機器碼如下:

33 DB 53 68 6C 6C 65 68 //hell 68 67 75 62 6F //obug 8B C4 53 50 50 53 B8 ADDRESS FF D0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

因為緩沖區有44個字節,而四個字節一組,因此有11組,加上原來的auth,EBP和返回地址,一共14組,每組4個字節。新建一個這樣的文件。?
?
我在執行的過程中最后部分0018FD44就是Buff的起始地址。

接下來的問題就是buff的起始地址以及MessageBox的入口地址怎么找到呢?

首先是buff的起始地址,這個比較簡單,將該文件寫為14組1234,然后在OD里面跑一遍之后可以看到內存里面的數據,這個數據區的起始地址就是就是buff的起始地址。

然后是MessageBox的入口地址,在0Day安全這本書中有計算過程,我按照這個過程沒有實現,因此我自己找了一個方法,有興趣的同學可以按照書上的計算一下~

我的試驗工程就是新建一個工程,只允許Messagebox然后通過OD查看其入口地址

#include <stdio.h> #include <windows.h>int main(void) {LoadLibrary("user32.dll");MessageBoxA(NULL, "abc", "def", NULL);return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

寫這樣一個簡單的程序用OD打開以下就好啦?
?
找到MessageBox回車之后就進入了,從這個圖可以看出入口地址是768EFD1E?
然后整個文件就制作完成了,運行一下看看吧?

以上就是一個簡單的緩沖區溢出的實例了,不過在植入代碼這個過程中電機確定之后~~就掛了,因為一些參數沒有設置好,慢慢再深入研究吧。

總結

以上是生活随笔為你收集整理的C语言实现缓冲区溢出实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。