ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基于VSC++6.0的缓冲区溢出验证实验

2021-10-31 18:01:22  阅读:156  来源: 互联网

标签:寄存器 程序 C++ 堆栈 VS func 6.0 缓冲区 溢出


0、概述

​ 在缓冲区溢出在一些较为古早的系统或软件中易于实现,因为这些系统或者软 件的堆栈位数较低,一些较短的数据就可以冲出堆栈,实现缓冲区溢出。所以 在较为古早的软件中验证缓冲区溢出不失为一种可行方法。本次实验采用的是VirtualC++ 6.0编译器进行。

1、实验目的

  1. 通过重现缓冲区溢出攻击来理解此漏洞

2、实验内容及步骤

  1. 实验原理

    • 堆栈的概念

      堆栈是一个在计算机中常用的抽象数据类型,堆栈的一个标志性特征就是最后一个入栈的元素总是第一个被取出(LIFO)。堆栈定义了一些操作,其中push和pop操作是最重要的两个操作,push在栈顶加入一个元素,pop则从栈顶移除一个元素,并将堆栈的大小减一。

    • 堆栈的缓冲区溢出原理

      函数调用时,返回值存放在堆栈中,局部变量也存放在堆栈中,如果局部变量中有一个字符数组,且该程序使用了又缓冲区溢出风险的函数来操纵该字符数组,就可以通过向该函数传递超长的字符串来使得该字符数组产生溢出,从而达到覆盖返回地址、执行恶意代码的目的。

  2. 实验过程

    • 设计程序

      首先需要设计一个拥有溢出风险的函数,该程序有如下功能:

      构建func()函数,有内存拷贝函数memcpy来实现字符的复制功,待复制的字符串长 度任意,这些字符将被复制到一个长为9的字符串中,如果复制的内容过长,就有可能 发生溢出,程序中的加法用来做对比。在主函数中调用了func函数,使用if语句决定 将要复制的字符的长度,对比二者,分析缓冲区溢出。

      程序stack.c:

      #include <stdio.h>
      #include <string.h>
      #include <windows.h>
      
      int func(char *szIn , int nTest)
      {
          int a = 1 , b = 2 , c = 0;
          char szBuf[8];
          memcpy(szBuf , szIn , strlen(szIn));
          c = a + b;
          return c;
      }
      
      int main()
      {
          int i = 0 , j = 0;
          printf("1 for shorter one while 2 for longer one");
          scanf("%d" , &i);
      
          if(i == 1){
              char sz_In2[] = "abcdabcdabcdabcd";
              j = func(sz_In2 , 512);
          }else if(i == 2){
              char sz_In3[] = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd";
              i = func(sz_In3 ,512);
          }else{
              char sz_In1[] = "abcd";
              j = func(sz_In1 ,512);
          }
      
          return 0;
      }
      
      
    • 保存为.c文件后,点击工具栏的“组件”,再点击其中的“编译”,进行程序的编译,中 间遇见异常报告,询问下一步操作时选择“是”选项。

    • 按F9在程序中设置断点,F5开始调试

    • 开始调试后程序运行至断点1,注意右上角的寄存器,其中各个寄存器的功能如下:

      EBP:基址指针
      ESP:堆栈指针
      EAX:累加器
      EBX:基址寄存器
      ECX:计数寄存器
      EDX:数据寄存器
      

    • 按F5进行调试,输入1,选择较短的字符串进行操作,直至程序结束,没有出现任何异常

    • 重新开启调试,在输入时转为2,对较长的字符串进行复制

      一直按F5运行程序,会发现出现了报错,不管它,继续F5,程序最终异常终止,报错依旧

      此时查看右上角的寄存器的数据,注意基址寄存器EBP的内容,正常情况下该指针永远指 向系统栈最上面一个栈帧的底部,但是这时却变成了64636261,这是ASCII码中abcd,即 复制的字符内容,说明发生了缓冲区溢出的现象,将func函数的返回值地址覆盖了。

      ASCII码表部分:

3、实验环境

​ 计算机:Windows10、VisualC++6.0

4、验证原理

​ 1、缓冲区溢出:缓冲区溢出是常见并且危害很大的系统攻击手段,通过向程 序的缓冲区写入超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆 栈,使程序转而执行其他指令,从而达到攻击的目的。

​ 2、C语言中,一些不作边界检查的字符串复制函数,如strcpy,容易造成缓 冲区溢出。

标签:寄存器,程序,C++,堆栈,VS,func,6.0,缓冲区,溢出
来源: https://www.cnblogs.com/ikiru1314/p/15490237.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有