Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
缓冲区溢出漏洞的原理及其利用实战
- 温馨提示:
- 本文章的图片十分重要,一定要认真的阅读。
- 可以把该图片下载下来,这样的话图片会非常清晰(右键->另存为)。
1. 实验环境
- 操作场景
- windows xp sp2
- 实验工具:
- IDA Pro
- OllyDbg
2. 缓冲区溢出漏洞原理
- 在这里我们通过一个实验来进行原理讲解
- 实验过程大致如下:
- 分别创建含有缓冲区溢出隐患的程序,和没有隐患的程序
- 判断main函数的地址
- 定位调用main函数的语句
- 分析call语句对于栈空间的影响
- 分析正常程序与存在溢出问题的程序对于栈空间的影响
- 缓冲区溢出漏洞总结
2.1 首先我们先来编写一个简单的存在缓冲区溢出漏洞的程序
-
注意:这个程序我使用的是VC++6.0进行编写的并且在windows XP下执行。而如果你使用的是新版本的Visual Studio,由于微软加入了GS机制来防止缓冲区溢出情况的出现,那么本实验就有可能无法实现
-
我们先新建一个win32控制台应用程序工程
- 如下图
- 如下图
-
编写一个 不存在溢出 的程序
- 代码如下:
#include "stdio.h"
#include "string.h"
//十个字节
char name[]="qianyishen";
int main(){
//申请了11个字节的空间
char buffer[11];
//将变量name中的内容复制到buffer数组中(由于buffer申请的空间 > 10字节,所以不会发生溢出)
strcpy(buffer,name);
printf("%s\n",buffer);
//加上这行代码可以使程序执行完printf之后停止,我们回车才可以继续执行,以便我们查看执行结果
getchar();
return 0;
}
-
运行一下看看:
- 注意:在编译之前我们要先确定使用的是win32 debug版本,而不是win32 release版本
- 运行结果
- 成功运行
- 注意:在编译之前我们要先确定使用的是win32 debug版本,而不是win32 release版本
-
那么如果变量name中的数据超过11个字节会怎么样?接下来让我们实验一下
- 编写一个 存在溢出 的程序
#include "stdio.h"
#include "string.h"
//20个字节,我们将数据量加一倍
char name[]="qianyishenqianyishen";
int main(){
//申请了11个字节的空间
char buffer[11];
//将变量name中的内容复制到buffer数组中(由于buffer申请的空间 < 20字节,所以会发生溢出)
strcpy(buffer,name);
printf("%s\n",buffer);
//加上这行代码可以使程序执行完printf之后停止,我们回车才可以继续执行,以便我们查看执行结果
getchar();
return 0;
}
-
运行一下看看
- 运行结果
- 我们发现在双击exe程序后,字符可以正常的显示,但是按下回车键之后,发生了报错
2.2 接下来我们研究一下存在溢出的程序出错的原因
- 我们先来研究一下正常的程序有什么特点
-
打开OD(即软件:OllyDbg),并将 无溢出的正常程序 拖入其中
-
而此时OD向我们展示的代码是系统自动生成的,与我们本次的实验没有关系,我们 首先需要做的是定位main函数的位置,
-
那我们应该如何去寻找main函数的位置呢?
- 根据经验直接在OD中寻找
- 使用工具IDA帮助定位main函数的位置(在这里使用的是这个方法)
-
使用IDA来定位main函数的位置:
-
由于缓冲区溢出是与栈的空间紧密相关的,因此现在我们还应当分析一下调用这个main函数前后栈空间的一些情况,所以在这里我们还需要定位一下究竟是哪条语句调用或者说是call main函数,同样,我们仍然使用IDA来帮助我们进行定位
-
在我们定位完call main函数的位置之后,为了便于之后内容的讲解,我们在这里要说明一下 call语句的原理
- 当我们的程序要执行call的时候,它会分为两步走:
- 第一步:是会将call下面这条语句的地址入栈(在这里该地址为:00401699)
- 第二步:就是jmp到这个call语句所指地址的位置
- 对于我们的这个程序来说,call下面的这个语句,它的地址是
- 当我们的程序要执行call的时候,它会分为两步走:
-