草庐IT

缓冲区溢出原理

Zovt 2023-03-28 原文

一、实验目的

  1. 掌握缓冲区溢出原理
  2. 理解CALL指令和返回地址的概念
  3. 观察正常程序的栈空间与存在溢出问题程序的栈情况

二、实验环境

  1. 系统环境:Windows环境
  2. 软件环境:C++ollydbg.exeidaq.exe

三、实验原理

  • 通过向程序的缓冲区(堆、栈等)中写入超出其长度的数据,造成缓冲区溢出。缓冲区的溢出可以破坏程序执行流程,使程序转向执行其它命令。利用缓冲区溢出可以达到攻击主机的目的。

四、实验步骤

  1. 打开Windows7虚拟机,编写一个overrun.dsw工程文件。overrun.cpp代码如下:
#include "stdio.h"
#include "string.h"
char name[]="overrun";
int main()
{
char buffer[8];
strcpy(buffer,name);
printf("%s\n",buffer);
getchar();
return 0;
}
  • 代码中我们创建一个局部空间为8个字节的buffer字符数组,然后利用strcpy函数将含有7个字节name字符串中的数据拷贝到buffer数组中,运行程序,字符串输出正常,按下回车,显示正常。如下图所示程序正常运行:
  1. 分析当name数组中数据超过8个字节的情况,将代码段name字符串修改长度为10个字符“overrun123456”,overrun.cpp代码如下:
#include "stdio.h"
#include "string.h"
char name[]="overrun123456";
int main()
{
char buffer[8];
strcpy(buffer,name);
printf("%s\n",buffer);
getchar();
return 0;
}

  • 此时将name[ ]13个字符大小的数组复制到buffer[8]数组中,再次运行程序,字符串输出正常,按下回车,出现错误。如下图所示:
  • 此时查看问题详细信息,可以发现异常偏移:00000036说明缓冲区溢出了导致程序运行发生错误。

正常程序分析:

  • 对于上述两种情况,首先分析正常程序。使用ollydbg.exe程序,将实验程序文件overrun.exe拖入其中,如下图所示:

  • 本次实验我们需要分析main函数,所以需要判定main函数的地址以及定位调用main函数的语句。首先打开idaq.exe程序,将正常程序overrun.exe拖入其中。如下图所示:

  • 然后双击jmp_main_0,按下空格键,找到main函数的地址为00401010(数据以实际情况为准),如下图所示:

  • 在ollydbg.exe界面左上角地址栏点击右键,选择Go to,选择Expression,在弹出的搜索栏中输入已获取的main函数地址,点击ok按钮。如下图所示:跳转至main函数地址

  • 获取main函数位置之后,如下图所示我们可以知道main函数由00401005处的语句跳过来。由于缓冲区溢出与栈空间紧密相关,现在我们来分析调用main函数前后栈空间的情况,如下图所示:main函数由00401005处的语句跳转

  • 接下来定位调用main函数的call语句。在idaq.exe界面中,点击main函数地址出,按下ctrl+x组合键,显示由call_main_0跳转到当前位置,按下ok按钮跳转至call_main_0,如下图所示:

    获取调用main函数的位置00401694

  • 在ollydbg.exe中跳转至call main函数的位置00401694(数据以实际情况为准),如下图所示:

  • 接下来分析调用call main函数前后栈空间的情况。一般当程序执行call的时候,会分为两步,第一步将call语句下一条语句的地址入栈,第二步jmp跳转至call语句所在地址的位置。当call语句执行完之后程序会将下一条语句的地址出栈,告诉程序call语句执行完之后继续执行这个地址的指令,我们一般将这个地址称为返回地址。如下图所示,下一条语句的地址为00401699

  • 点击00401694处然后按下F2添加断点,按F9执行当前断点位置,再按F7单步执行进入main函数,发现下一条语句的地址00401699入栈,如下图所示:

  • 源程序中首先创建了8个字符大小的char数组,当我们进入main函数的时候,首先会给这个局部变量分配空间。按F8继续执行push ebp指令。观察栈顶情况发现EBP入栈。继续按F8执行完SUB ESP,4C后观察栈的情况,发现已经分配相应空间。如下图所示:EBP入栈

  • 按F8继续执行完
    后观察栈的情况,发现分配的局部空间被CC填充。程序为了容错性以及自身的健壮性会用CC(int 三断点)填充,如果有未知的程序跳转这边区域便不会出现崩溃的情况,如下图所示:局部空间被CC填充

  • 按F8继续执行至下一条call指令,程序可以正常跳转至00401699处执行,如下图所示:call调用的函数地址为00401005

异常程序分析::

  • 接下来分析溢出程序调用strcoy前后栈的情况,在工具软件安装包中打开ollydbg.exe和idaq.exe程序,分别将实验程序overrun.exe拖入其中,此处步骤和上面步骤同理省略…

  • 进入idaq.exe界面调转到00401694

  • 发现返回地址和EBP都被字符串覆盖

    结论:通过实验发现返回地址和EBP都被字符串所覆盖,实验程序跳转至错误的返回地址处没有任何指令,故程序报错。
    整理整个分析过程可以得知,本次实验中导致缓冲区溢出的原因是因为代码编写的不规范,导致程序运行过程中返回地址被覆盖,从而使得程序错误的运行。倘若覆盖返回地址的数据为攻击者精心构造的数据,那么程序就会按照被覆盖数据的引导来执行,从而达到攻击者某些不可告人的目的。

有关缓冲区溢出原理的更多相关文章

  1. ruby - 如何模拟 Fixnum 变量的整数溢出? - 2

    我目前正在将一种算法从Java转换为Ruby,但由于Ruby中缺少整数溢出,我遇到了一些障碍。假设我的值为2663860877,它大于最大整数2147483648。在Java中,它环绕,我应该得到-1631106419。我找到了这段代码,但它似乎不起作用:defforce_overflow(i)ifi2147483647i&0xffffffffelseiendend并且'ing变量不会像您期望的那样强制它为负。 最佳答案 假设32位整数具有二进制补码负数,这应该可行:defforce_overflow_signed(i)force_

  2. 【Unity游戏破解】外挂原理分析 - 2

    文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cppdumper例子2-森林whoishe后记认识unity打包目录结构dll一般很大,因为里面是所有的游戏功能编译成的二进制码游戏逆向流程开发人员代码被编译打包到GameAssembly.dll中使用il2ppDumper工具,并借助游戏名_Data\il2cpp_data\Metadata\global-metadata.dat

  3. Unity 血条及“掉血”缓冲效果 - 2

     视频教程:https://www.bilibili.com/video/BV1WJ411778C/?spm_id_from=333.999.0.0&vd_source=4a4c35da6aef7094d5990c213c39aa09使用素材(推荐使用GitZipforgithub下载):https://github.com/zheyuanzhou/Youtube-Unity-Tutorial/tree/master/EP45_Health%20Bar/Sprites效果如下图所示:首先在场景中创建一个新的Canvas,并命名为HeathBar,并创建三个Image作为前者的子物体,分别命名为

  4. Slowloris DoS攻击的原理与简单实现 - 2

    前言    Slowloris攻击是我在李华峰老师的书——《MetasploitWeb 渗透测试实战》里面看的,感觉既简单又使用,现在这种攻击是很容易被防护的啦。不过我也不敢真刀实战的去试,只是拿个靶机玩玩罢了。         废话还是写在结语里面吧。(划掉)结语可以不看(划掉)Slowloris攻击的原理        Slowloris是一种资源消耗类DoS攻击,它利用部分HTTP请求进行操作。也叫做慢速攻击,这里的慢速并不是说发动攻击慢,而是访问一条链接的速度慢。Slowloris攻击的功能是打开与目标Web服务器的连接,然后尽可能长时间的保持这些连接打开。如果由多台电脑同时发起Slo

  5. ruby - 如何创建与帧缓冲区通信的 Ruby 应用程序? - 2

    我有一个RaspberryPiTFT7"触摸屏显示器,我想创建一个简单的应用程序来显示和输出系统数据(即CPU使用率、温度等)。我注意到目前常见的实现方法是使用pygame库输出到显示器连接到的帧缓冲区/dev/fb1。我想执行相同的操作,但使用Ruby,因为我更熟悉这门语言。有人可以为我指明正确的方向,让我知道如何开始吗?我查看了ruby​​game和gosu库,它们似乎能够做我想做的事情,即绘制屏幕,​​但我找不到任何关于如何将输出定向到的信息帧缓冲区本身。 最佳答案 rubycorelib有一个IO您应该能够使用该类将输出定向

  6. [蓝桥杯单片机]学习笔记——串口通信的基本原理与应用 - 2

    目录一、原理部分1、什么是串行通信(1)并行通信与串行通信(2)串行通信的制式(3)串行通信的主要方式  2、配置串口(1)SCON和PCON:串行口1的控制寄存器(2)SBUF:串行口数据缓冲寄存器 (3)AUXR:辅助寄存器​编辑(4)ES、PS:与串行口1中断相关的寄存器(5)波特率设置  3、串口框架编写二、程序案例一、原理部分1、什么是串行通信(1)并行通信与串行通信微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。并行通信:数据的各位同时发送与接收,每个数据位使用一条导线,这种方式传输快,但是需要多条导线进行信号传输。串行通信:数据一位一

  7. ruby - # Ruby 中识别方法约定的基本原理/历史是什么? - 2

    例如,我一直看到称为String#split的方法,但从未见过String.split,这似乎更合乎逻辑。或者甚至可能是String::split,因为您可以认为#split位于String的命名空间中。当假定/隐含类(#split)时,我什至单独看到了该方法。我知道这是ri中识别方法的方式。哪个先出现?例如,这是为了区分方法和字段吗?我还听说这有助于区分实例方法和类方法。但这从哪里开始呢? 最佳答案 不同之处在于您如何访问这些方法。类方法使用::分隔符来表示消息可以发送到类/模块对象,而实例方法使用#分隔符表示消息可以发送到实例对

  8. H264压缩原理 - 2

    1、为什么压缩的原始数据一般采用YUV格式(1)利用人对图片感觉的生理特性,对于亮度信息比较敏感,对于色度信息不太敏感,所以视频编码是将Y分量和UV分量分开来编码,并且可以减少UV分量.2、视频压缩原理(1)空间冗余:图像相邻像素之间的相关性,比如一帧图片被划分成多个16x16的块之后,相邻的块之间有很多明显的相似性。(2)时间冗余:时间相差较近的两张图片变化较小。(3)视觉冗余:我们的眼睛对某些细节不太敏感,对图像中的高频信息的敏感度小于低频信息,可以去除一些高频信息。(4)编码冗余:一幅图片中不同像素出现的概率是不同的,对于出现次数较多的像素,用少的位数来编码,对于出现次数较少的像素,用多

  9. Python——程序的运行原理 - 2

    Python程序运行原理Python是一种脚本语言,编辑完成的程序,也称源代码,可以直接运行。从计算机的角度看,Python程序的运行过程包含两个步骤:解释器将源代码翻译成字节码(即中间码),然后由虚拟机解释执行。Python程序文件的扩展名通常为.py。在执行时,首先由Python解释器将.py文件中的源代码翻译成中间码,这个中间码是一个扩展名为.pyc的文件,再由Python虚拟机(PythonVirtualMachine,PVM)逐条将中间码翻译成机器指令执行。需要说明的是,pyc文件保存在Python安装目录的pycache文件夹下,如果Python无法在用户的计算机上写人字节码,字节

  10. ruby - 从 emacs 缓冲区运行 ruby - 2

    如何从缓冲区运行一段ruby​​代码,而不实际将缓冲区保存在文件中?一个场景是a)切换到暂存缓冲区b)M-xruby模式c)输入ruby代码d)“编译”缓冲区并在另一个缓冲区中打印结果。我不想将缓冲区内容保存在文件中,然后“编译”该文件2011年1月9日更新哪些是ruby​​-mode和inf-ruby的最新版本,我可以从哪里获得它们?我用的是ubuntunatty版的ruby模式和elpa版的emacs23.2的inf-ruby。在干净的emacs配置上,以下配置(见下文)失败:can'tconvertnilintoStringfrom(irb):1:in`eval'from(irb

随机推荐