实验目的:
在掌握栈帧结构的基础上,学习栈溢出漏洞的基本原理。
完成功能:
根据代码熟悉栈帧结构,分析代码中str和passsword的关系,跳过密码验证。
实验代码:
#include <stdio.h>
#include <stdlib.h>
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;
}
实验结果和分析:
- 首先设置断点
- 使用debug跳进fun()函数里去
- 查看main()函数地址
main()函数的地址为0x4015aa - 查看fun函数的地址
fun函数的地址为0x401550 - 查看password数组的地址
password的地址为0x61fdea - 查看str数组的地址(此时str数组还没有被输入)
str的地址为0x61fde4 - 分析各个地址间的关系
按照地址由低到高进行排列
0x61fde4 str
0x61fdea password
可见windows中栈的地址是由高到低进行增长的。
在这张图里可以看到password数组已经被初始化,数组里的值为ABCDE,str数组与password数组紧挨着,当我们用gets这个不安全的函数输入时,如果故意地输入超过str数组长度的值,就会产生栈溢出造成对password中值的覆盖。 - 对上述假设进行验证,利用栈溢出来覆盖password数组,是程序打印OK
使用gets函数向str数组输出11个a,这时候我们再次查看内存信息
好的,成功地看到password数组里的值已经被a给覆盖掉了,原来的值是ABCDE。
接着我们继续让程序运行。
成功地打印OK,我们利用栈溢出成功地跳过了验证。经过查询资料和进行实验,gets这个函数在visual studio2019中已经被删除,它会提示使用fgets函数。
在Ubuntu虚拟机上编译上述程序时也会报错,提示使用fgets。本次实验利用栈溢出的环境是在WIN10上使用codeblocks20.03(自带编译器的版本)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。