从零开始学Win32平台缓冲区溢出(Part1)

简介: 原文:Stack Based Buffer Overflow in Win 32 Platform: The Basics 译者:鸢尾 来源:从零开始学Win32平台缓冲区溢出(Part1)缓冲区溢出是一个常见的且大家经常耳闻的软件安全漏洞,缓冲区溢出即是数据被过多的写入内存或者缓冲区,当一个缓冲区内的数据写满后,如果继续写入数据,数据就会溢出到其他缓冲区中,这将会覆盖或者说是破坏已存储的数据。

原文:Stack Based Buffer Overflow in Win 32 Platform: The Basics

译者:鸢尾

来源:从零开始学Win32平台缓冲区溢出(Part1)

缓冲区溢出是一个常见的且大家经常耳闻的软件安全漏洞,缓冲区溢出即是数据被过多的写入内存或者缓冲区,当一个缓冲区内的数据写满后,如果继续写入数据,数据就会溢出到其他缓冲区中,这将会覆盖或者说是破坏已存储的数据。

为了利用缓冲区溢出,你需要了解堆栈,CPU寄存器,内存分配等基础知识。由于缓冲区溢出本身就是一个非常庞大的话题,在这篇文章中我们会试着去理解基于堆栈的缓冲区溢出的基础知识,希望你能够喜欢。

创建C程序

首先,我们会创建一个简单的C程序并介绍一些基本知识,比如程序在内存中是如何运行的,函数调用是如何发生的,什么是返回地址等等。这就让我们从最基本的知识开始吧。

在程序中,堆栈就是用来存储临时数据的一块连续的内存。堆栈的原理即是后进先出,其有两个函数 ,PUSH是将数据放入堆栈中,POP是将数据从堆栈中取出来。在基于英特尔的系统中,从下往上他的内存地址逐渐增加,在英特尔32位架构下最大为4个字节的数据。

基本上程序的堆栈包含以下几类数据:

函数参数
调用函数的地址
返回地址
局部变量

在了解开始之前,我们需要安装会用到的工具。

虚拟机中配置完成的Windows XP Service Pack 2
Immunity Debugger
Dev C ++

首先,我们会看看函数是如何被调用,返回地址等等东西。从这一阶段开始,我们已经编写好一个简单的C程序,在这段代码中我们定义了一个函数。EXE文件以及源码会在文章最后打包分享给大家。让我们看一看程序的源代码,这样我们能理解一些基本概念。

从上面的截图我们可以看到,我们在这个简单的C程序中定义了一些局部变量。接着我们使用变量调用函数,然后定义一个函数打印出“Function is called”,最后返回值为1,返回主程序。

在程序编译完成之后,我们使用Immunity Debugger工具打开程序。

点击文件菜单或者拖动这个EXE文件到Immunity Debugger工具,之后我们将在屏幕上看到以下信息。

我们在屏幕上看到四个部分,每一个部分都代表着不同类型的CPU信息。

1.信息中含有各种寄存器以及它们的值。
2.我们可以看到程序的内存转储,我们可以看到什么类型的数据被写到内存中。
3.我们也可以根据需求编辑这些值。
4.最重要的是:它显示了程序堆栈的状态

如果我们仔细观察屏幕,可以在窗口的右下角看到一个暂停按钮。这意味着用Debugger打开程序,Debugger可以对程序运行进行暂停,所以我们可以手动先启动程序。

0×01

现在,我们就开始对程序进行分析吧

第一步就是确定主函数,以及我们在程序中定义的其他函数。如果我们的鼠标在第一个区域进行滚动,可以看到以文件名命名的主函数的ASCII以及其他函数的汇编代码,在本例中EXE文件名为First.exe。

截图中,我们有标识一些数字,这些数字是为了方便我们在接下来的内容中更好的表述而设立的。

这是主函数的汇编代码,我们可以在截图中看到“First.xxxxx”“Main Function”。在本例中, First.xxx是我们加载到Debugger中的EXE文件名。在左边我们看到的是每一个汇编指令的内存地址,00401290这个内存地址本例中表示程序启动,004012DA则表示程序结束。图中蓝色的一行是调用我们在C程序中定义的函数。

在我们仔细观察主函数的调用时发现,主函数内存地址的后面8位中调用了一个“First.004012D3”

最后,我们可以看到函数加载到内存中,并通过printf函数打印出“Function is called”。这个函数是将数据放入EBP寄存器中,即为入栈。在本例中,函数开始的内存地址为“004012DE”, 函数结束的内存地址为“004012FE”,这两个地址都可以在上面截图中看到。

0×02

这是最重要的一部分,我们将了解如何定义程序的断点。断点可以帮助我们在某一个位置冻结程序,让我们可以分析寄存器状态,栈,指针等信息。当然也允许我们对某些变化的值进行修改。所以就让我们在调用函数之前创建一个断点吧,设置断点我们可以选中某行并点击一下或者按下F2。

如上图所示,创建一个断点之后,这一行会被高亮显示。接着我们启动程序,我们可以使用F9快捷键。我们可以在屏幕上看到有些数字变化了。

在上图中,我们发现堆栈以及寄存器的值变化了,另一个有趣的事是存储断点的EIP寄存器的值。

目前,我们有两个选择

逐条指令跟踪:当我们在创建一个断点之后想执行下一条指令,我们可以使用逐条指令跟踪,键盘快捷键进入F7。

多条指令跟踪:有时候我们不需要获取详细的函数调用细节,在这种情况下我们可以使用多条指令跟踪,键盘快捷键进入F8。

0×03

好了,我接下来需要执行下一条指令,我们按下键盘快捷键F7,对堆栈进行分析。

如上图所示,在4号窗口中没有什么亮点。在1号窗口中我们可以看到断点下一条指令被执行,在2号窗口中我们看到下一条指令在EIP寄存器中分配的内存地址。

继续按下F7快捷键,我们可以看到如下这张图

我们可以看到下一个指令被执行,以及屏幕上许多数据的变化。

在1号窗口中可以看到,控制器已在前面给出的地址调用函数。仔细观察4号窗口,在堆栈的顶部,我们看到内存地址004012D4,这个内存地址是主程序的返回地址,这意味着函数执行完成后,通过这个地址计数器会跳转到主程序,也就是说程序执行完毕。

在本文我们学到的知识

分析堆栈
创建断点
分析函数调用以及寄存器状态

注:原作者未有提及第一节会将什么内容,所以就让他保持点神秘感吧。

文章中涉及源码链接:http://pan.baidu.com/s/1c0dafPQ 密码:mr5l

参考文献

http://debugger.immunityinc.com/ID_register.py

https://www.owasp.org/index.php/Buffer_Overflows

http://en.wikipedia.org/wiki/Buffer_overflow

http://en.wikipedia.org/wiki/Stack_buffer_overflow

http://www.bloodshed.net/dev/devcpp.html

译者注:此乃基础教程,求轻喷。Ps.我就知道你们会说AV画质的

相关文章
|
4月前
|
缓存 C# Windows
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
|
NoSQL Shell
[PWN][进阶篇]使用GDB附加调试64位程序(下)
[PWN][进阶篇]使用GDB附加调试64位程序
220 0
[PWN][进阶篇]使用GDB附加调试64位程序(下)
|
NoSQL
[PWN][进阶篇]使用GDB附加调试64位程序(上)
[PWN][进阶篇]使用GDB附加调试64位程序
429 0
[PWN][进阶篇]使用GDB附加调试64位程序(上)
|
开发者 Windows
Windows Phone 7中用好Silverlig“.NET研究”ht开发利器
  除了Windows Phone 7的UI可以用Silverlight框架来设计,还可以用Silverlight创建Windows Phone 7的应用程序。本文为一个国外.NET平台开发者为Windows Phone 7创建的Silverlight应用程序。
872 0
|
.NET API C#
艾伟_转载:Windows Mobile开发,Native C++ PK .NET Compact Framework
缘由 经常听到一些刚刚接触Windows Embedded CE和Windows Mobile开发的人会提出一些疑问。进行Windows Mobile开发,到底使用什么语言呢?C++还是C#?Java行不行?下面就我自己的想法讲述一下Native C++ 和 .NET Compact Framework的异同和选择。
1342 0
|
Android开发 开发者 Windows
微“.NET研究”软“重启”Windows Phone 7 设计的经过
微软集团副总裁、Windows Phone 项目主管 Joe Belfiore 在位于雷蒙德的微软总部拿着三星的 Windows Phone 7 原型机。   微软员工将 2008 年 11 月称为“重启(The Reset)”。
1110 0