软件安全实验:栈溢出漏洞一

实验目的:

在掌握栈帧结构的基础上,学习栈溢出漏洞的基本原理。

完成功能:

根据代码熟悉栈帧结构,分析代码中str和passsword的关系,跳过密码验证。

实验代码:

#include 
#include 

void fun() {
    char password[6] = "ABCDE";
    char str[6];
    gets(str);
    str[5] = '\0';

    if(strcmp(str, password) == 0)
        printf("OK. \n");
    else
        printf("NO. \n");
}

int main() {
    fun();
    int a = 0;
    return 0;
}  

实验结果和分析:

  1. 首先设置断点
    软件安全实验:栈溢出漏洞一_第1张图片
  2. 使用debug跳进fun()函数里去
    软件安全实验:栈溢出漏洞一_第2张图片
  3. 查看main()函数地址
    软件安全实验:栈溢出漏洞一_第3张图片
    main()函数的地址为0x4015aa
  4. 查看fun函数的地址
    软件安全实验:栈溢出漏洞一_第4张图片
    fun函数的地址为0x401550
  5. 查看password数组的地址
    软件安全实验:栈溢出漏洞一_第5张图片
    password的地址为0x61fdea
  6. 查看str数组的地址(此时str数组还没有被输入)
    软件安全实验:栈溢出漏洞一_第6张图片
    str的地址为0x61fde4
  7. 分析各个地址间的关系
    按照地址由低到高进行排列
    0x61fde4 str
    0x61fdea password
    可见windows中栈的地址是由高到低进行增长的。
    软件安全实验:栈溢出漏洞一_第7张图片
    在这张图里可以看到password数组已经被初始化,数组里的值为ABCDE,str数组与password数组紧挨着,当我们用gets这个不安全的函数输入时,如果故意地输入超过str数组长度的值,就会产生栈溢出造成对password中值的覆盖。
  8. 对上述假设进行验证,利用栈溢出来覆盖password数组,是程序打印OK
    image.png
    使用gets函数向str数组输出11个a,这时候我们再次查看内存信息
    软件安全实验:栈溢出漏洞一_第8张图片
    好的,成功地看到password数组里的值已经被a给覆盖掉了,原来的值是ABCDE。
    接着我们继续让程序运行。
    软件安全实验:栈溢出漏洞一_第9张图片
    成功地打印OK,我们利用栈溢出成功地跳过了验证。经过查询资料和进行实验,gets这个函数在visual studio2019中已经被删除,它会提示使用fgets函数。
    在Ubuntu虚拟机上编译上述程序时也会报错,提示使用fgets。本次实验利用栈溢出的环境是在WIN10上使用codeblocks20.03(自带编译器的版本)。

你可能感兴趣的:(安全)