实验二 堆栈缓冲区溢出实验

一、 实验目的
 了解堆栈缓冲区溢出原理
 掌握vc++6.0使用方法
 熟悉堆栈缓冲区溢出防范常用的方法
二、 实验原理

  1. 堆栈的概念
    堆栈是一个在计算机科学中经常使用的抽象数据类型。堆栈中的物体具有一个特性:最后一个放入堆栈中的物体总是被最先拿出来,这个特性通常称为后进先处(LIFO)队列。堆栈中定义了一些操作,两个最重要的是PUSH和POP。PUSH操作在堆栈的顶部加入一个元素。POP操作相反,在堆栈顶部移去一个元素,并将堆栈的大小减一。
  2. 堆栈缓冲区溢出原理
    函数调用时,返回地址存放在堆栈中,局部变量也存放在堆栈中;如果局部变量中有一个字符数组,并且该程序使用了危险的函数来操纵该字符数组,那么就可以通过向该程序传递超长的字符串来使得该字符数组“溢出”,从而达到覆盖返回地址、执行恶意代码的目的。
  3. 防范措施:
    引入新的安全的函数,取代旧的、有缺陷的函数。较新的c库中都带有 strncpy ,fgets , sscanf 等函数。
    插入保护码,这些保护码被称为“金丝雀”。某些程序包可以与编译器配套使用,在返回地址与局部变量之间插入一些保护码,导致入侵者在覆盖返回地址的时候,首先覆盖了保护代码。程序运行时会检测这些保护码,如果这些代码被改变,程序就会马上终止。检测保护码的代码是编译器加进去的,程序员无需为此操心。
    真正有威胁的攻击来自shell2 code,但shell2code通常要求在堆栈中植入一段代 码并执行,这就需要堆栈是可执行的。一些操作系统 (如新版的Solaris)可以将堆栈设置为不可执行的。Intel 的 Itanium 处理器采用了一种与众不同的途径来避免基于堆栈的缓冲区溢出攻击,即为返回地址设置了一个寄存器,使返回地址不再放到堆栈中,所以无论如何溢出,也不会影响返回地址的值。
    三、 实验环境
  4. 操作系统
    操作机:Windows_7
    操作机默认用户名:administrator,密码:123456
  5. 实验工具
    Microsoft Visual C++ 6.0
    Microsoft Visual C++,(简称Visual C++、MSVC、VC++或VC)是Microsoft公司推出的以C++语言为基础的开发Windows环境程序,面向对象的可视化集成编程系统。它不但具有程序框架自动生成、灵活方便的类管理、代码编写和界面设计集成交互操作、可开发多种程序等优点,而且通过的设置就可使其生成的程序框架支持数据库接口、OLE2.0,WinSock网络。
    四、 实验步骤及内容
    1.1打开目录D:\2、网络攻防\2、网络入侵\30系统漏洞攻击\2.堆栈缓冲区溢出实验\工具包,解压vc安装包,安装vc6。
    堆栈缓冲区溢出实验_堆栈缓冲区
    堆栈缓冲区溢出实验_堆栈缓冲区_02

1.2默认安装完成,桌面出现VC+ +6.0的图标
堆栈缓冲区溢出实验_堆栈缓冲区_03
堆栈缓冲区溢出实验_堆栈缓冲区_04
2.1打开实验所用c程序

2.2新建文本文件,源码的拷贝程序如下:

#include#include "string.h"
#includeint fun(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临近变量覆盖,按2为返回值覆盖!");
    scanf("%d", &i);

    if (i== 1){
        char sz_In2[] = "1234567890s";
        j = fun(sz_In2, 888);
    }else if (i == 2){
        char sz_In3[] = "123456789abcdefghijklmnopqrstuvwxyz";
        i = fun(sz_In3, 888);
    }else{
        char sz_In1[] = "123";
        j = fun(sz_In1, 888);
    }
    return 0;
}

2.3保存为.c的文件,点击“组建”选项卡下的"编译”,编译文件遇到询问是否需要创建一个活动的项目工作区,点击“是"
堆栈缓冲区溢出实验_堆栈缓冲区_05
堆栈缓冲区溢出实验_堆栈缓冲区_06

2.4在程序中设置断点,进行调试。按F9进行设置,设置内容如下
堆栈缓冲区溢出实验_堆栈缓冲区_07

2.5按F5开始调试。询问是否创建exe文件, 点击“是"
堆栈缓冲区溢出实验_堆栈缓冲区_08

3.1进入断点调试按1的时候程序的中间变量变化情况.点Run to Cursor .将程序凋至fun函数的memcpy位置。
3.2第二个断点的结果显示
堆栈缓冲区溢出实验_堆栈缓冲区_09
根据上图可知申请的个八个区域的数组由于给他赋值为十块的内容,导致了变量溢出从而覆盖了c的值。
3.3 ( 淹没返回地址改变程序流程)退出程序,按F5重新运行。按2键进行返回值覆盖 ,回车。按下F5运行到c=a+b处,查看a,b,c三值发生了数据溢出。
堆栈缓冲区溢出实验_堆栈缓冲区_10

3.4得知,b,c的值金部被改变了,按F5继续执行代码弹出如下错误。
堆栈缓冲区溢出实验_堆栈缓冲区_11

上图说明子函数的返回地址被覆盖掉了,无法正常退出。
五、 实验总结
通过本次实验,了解了堆栈缓冲区溢出漏洞的原理以及防范的方法,掌握了vc++6.0使用方法,收获很大。