dedecms织梦内容管理系统  
 
首页 | 方舟产品 | 系统优化 | 硬件系统 | 软件系统 | 网络系统 | 无盘网络 | 软件下载 | 杀毒防黑 | 专题 | 会员中心 | 方舟论坛
  当前位置:方舟系统站>系统优化>win 2k优化>文章内容
缓冲区溢出知识
来源: 作者: 发布时间:2007-04-04  

        这篇文章应该属入门级。虽然比较简单,但对于Windows系统下的缓冲区溢出具有一定的通用性。例如,堆栈溢出地址的确定,跳转指令的查找和使用,溢出执行代码的编写,等等。只要发现Windows系统下存在缓冲区溢出漏洞的程序,基本上都可通过这些步骤进行攻击测试。但正如ipxodi所指出的,由于Windows下动态链接库的版本更新较快,一定要根据编程者的实际平台进行调试。在发布此类安全漏洞公告或溢出攻击程序时,源代码、系统平台和动态链接库的版本号都应该尽量列清楚。否则别人调试起来可能会头疼得很厉害。

调试、测试环境

Microsoft Visual C++ 6.0
Microsoft Windows 2000 Server (中文版,内部版本号:2195)

调试、测试过程

首先,写一个存在缓冲区溢出漏洞的应用程序。该程序可读取文件的内容,这样我们就能通过修改被读取文件的内容来使程序溢出。;-) 在Visual C++开发环境中创建一个新的控制台应用程序,选择”An Application that supports MFC”并单击”Finish”。(注:其实并不一定非是MFC应用程序不可,只不过是我自己的习惯而已。;-)))向这个应用程序中添加一些必要的代码,如下:

CWinApp theApp;

using namespace std;

void overflow(char* buff);

void overflow(char* buff)
{
CFile file;
CFileException er;
if(!file.Open(_T("overflow.txt"),CFile::modeRead,&er))
{
er.ReportError();
return;
}

int x = file.GetLength();
file.Read(buff,x);
}

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
{
char buff;
overflow(buff);
}
return nRetCode;
}

        

现在先来分析一下上面这段C++代码,找一找哪里有漏洞。这是一个MFC控制台应用程序,”main”函数与其它程序会有些不同,但工作机制基本一致。我们主要分析该函数中”else”那段代码。首先是第一行”char buff”,定义了一个10字符长的本地变量。我们都知道,本地变量的内存空间是在堆栈里分配的。(如果你连这个都不知道,建议不要继续往下看了。:))然后是将buff变量作为参数调用overflow函数。好了,现在让我们分析overflow函数。首先是一个Cfile对象,然后是一个CfileException对象。接下来会试图以读权限打开当前目录下的文件”overflow.txt”。如果打开成功,则将该文件中的所有内容读取到buff数组变量中。发现了问题没有?buff变量只有10字符长。如果读取的文件内容长度是100时会发生什么问题呢?对了,“缓冲区溢出”!而且是在堆栈中发生的缓冲区溢出。在后面的测试中就能看到,我们利用这个漏洞能做些什么!;)现在让我们创建文本文件”overflow.txt”,并将它放到这个应用程序的project目录下。

在进行下一步前,先让我们探讨一下关于Windows NT/2000的内存结构。NT/2000的每一个进程都在启动时分配了4GB(0xFFFFFFFF)的虚拟内存。其中的某些部份实际上是由所有进程共享的,例如核心和设备驱动程序区域。但它们都会被映射到每个进程的虚拟地址空间里。实际上没有进程分配到4GB的物理内存,而是仅当需要时才分配物理内存。因此每一个进程都有各自的4GB虚拟内存,编址范围从0x00000000到0xFFFFFFFF。其中,0x00000000-0x0000FFFF是为NULL指针分配而保留的。访问该区域内存将导致“非法访问”错误。0x00010000-0x7FFEFFFF是用户进程空间。EXE文件的映像被加载到其中(起始地址0x00400000),DLL(动态链接库)也被加载到这部份空间。如果DLL或EXE的代码被装入到该范围的某些地址,就能够被执行。访问该区域中没有代码装入的地址将导致“非法访问”错误。0x7FFF0000-0x7FFFFFFF是保留区域,对此区域的任何访问都将导致“非法访问”错误。0x80000000-0xFFFFFFFF仅供操作系统使用。用于加载设备驱动程序和其它核心级代码。从用户级应用程序(ring 3)访问此区域将导致“非法访问”错误。

现在回到”overflow.txt”文件。现在我们将向这个文本文件中不断添加字符,直到弹出应用程序非法访问的系统对话框。在这里,填充什么字符是很重要的(原因待会就知道了)。我选择小写字母”a”来填充文本文件。我们已经知道缓冲区只有10字符长,那么先填充11个字符。(注意:以debug方式编译应用程序,否则结果可能会有所不同。)咦?没反应。我们继续填充字符……直到填充了18个字符应用程序才崩溃。但这个崩溃对我们的用处还不大。继续填充!当字符串长度为24时,运行程序并观察弹出的对话框信息:“”0x61616161”指令引用的”0x61616161”内存。该内存不能为”written”。”我想大家都应该知道”0x61”所代表的ASCII码是什么吧?;)如果你的机器安装了Visual C++,单击“取消”按钮就能够调试该应用程序。进入调试环境后,选择”view”菜单――”debug windows”――”registers”,可打开寄存器窗口。如果你对汇编一窍不通,建议先去找本汇编的书看看。在寄存器窗口里会看到EAX、EBS和EIP等寄存器的内容。EIP当然是最重要的了。EIP的内容就是程序下一步所要执行指令的地址。我们注意到ESP寄存器的值未被破坏,而且似乎离我们的buff变量不远。下一步我们需要找出ESP的值是从如何处理得到的。

共4页: 上一页 1 [2] [3] [4] 下一页
 
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·Windows 2000 优化完全手册
·Windows 2000终极优化
·轻松设置让Win2000达到最佳性能
·Windows 2000 优化完全手册
·windows 2000 STOP 0x000000D1故
·防止电脑死机的25个方法
·Win 2000/XP蓝屏解决实用技
·Win2000设置技巧
·优化Win 2000的NTFS系统
·Windows 2000操作系统二十
·Win 2000的五则超酷技巧
·WinXP之后如何安装Win2000
  相关文章
·Windows 2000进程分析
·最少的服务最小的权限等于最大的
·通过修改Windows 2000注册表抵抗
·让win2k自动关机的实现方法
·Windows 2000 server需禁用
·Windown 2000应用技巧
·如何释放C盘空间
·Windows 2000 微软最
·定制的Windows 2000的位置条
·Windows 2000中快速安装五笔输入
·为什么要使用NTFS系统
·在Windows 2000中防Ping攻击
  主题推广
方舟网络 版权所有|关于本站|隐私保护|