一个软考题目让你清晰了解缓冲区溢出漏洞!!

代码

#include <stdio.h>
#include <string.h>

// 定义一个函数,接受一个字符指针作为参数
void Challenge(char *str) {
    char temp[9] = {0}; // 定义一个长度为9的字符数组temp,并初始化为0
    strncpy(temp, str, 8); // 使用strncpy函数复制字符串,最多复制8个字符
    printf("temp=%s\n", temp); // 打印temp数组的内容

    // 如果temp和"Please!@"相等
    if (strcmp(temp, "Please!@") == 0) {
        printf("KEY:****\n"); // 打印密钥
    }
}

int main(int argc, char *argv[]) {
    char buf2[16]; // 定义一个长度为16的字符数组buf2
    int check = 1; // 定义一个整型变量check并初始化为1
    char buf[8]; // 定义一个长度为8的字符数组buf

    strcpy(buf2, "give me key!!"); // 使用strcpy函数复制字符串
    strcpy(buf, argv[1]); // 将命令行参数argv[1]复制到buf数组中

    // 如果check等于65
    if (check == 65) {
        Challenge(buf); // 调用Challenge函数
    } else {
        printf("check is not 65 (%d)\nProgram terminated!!\n", check); // 打印错误信息
    }
    return 0; // 结束main函数
}

题目

1.main 函数内的三个本地变量所在的内存区域称为什么,它的两个最基本操作是什么?

2.画出buf,check,buf2 三个变量在内存的布局图。

3.应该给程序提供什么样的命令行参数值(通过argv变量传递)才能使程序执行流程进入判断语句 If(check=65),然后调用challenge( )函数。

4.上述代码所存在的漏洞名字是什么,针对本例代码,请简要说明如何修正上述代码

分析

首先我们看到题目先不要怕,从第一题入手,内存区域,那我们是不是要对计算机代码的存储有所了解?

内存区域的划分

根据进程使用的内存区域的预定功能划分,一般可大致分成以下三个部分:

静态数据区

存放全局变量,分为初始化数据和未初始化的数据

动态数据区

存放程序运行时的动态变量,分栈和堆区

栈区(stack segment):用于存储函数之间的调用关系以及函数内部的变量,以保证被调用函数在返回时回到父函数中继续执行。

堆区(heap segment):程序运行时向系统动态申请的内存空间位于堆区,用完之后需要程序主动释放所请求的内存空间。在C/C++中使用malloc或者new等方式申请的空间就在堆区。

代码区

就是放代码的地方

用代码理解
int x;
int y;
#x和y就是全局变量,存放在静态数据区
int main()
{
int a;
int b;
#a和b就是在函数内部的变量,在内存里面存放在动态数据区里面的栈区
int *value;
// 使用malloc分配内存给一个整型变量
value = (int*)malloc(sizeof(int));
free(value);
#value就是存放在动态数据区里面的堆区
}
然后这一串代码,你可以理解为txt文本,是存储在代码区的
解题

第一题分析:

三个本地变量是在函数里面的,所以属于动态数据区里面的栈,我们这里说动态数据区就好了。两个基本操作就是刚刚代码里面的分配存储空间和释放存储空间呗,c语言里面的malloc和free

第二题分析:

让我们画出buf,check,buf2 三个变量在内存的布局图

刚刚说到了栈,什么是栈呢?栈是一种后进先出的数据结构,然后我们的内存是根据我们的声明顺序一个个存储进去的,我们看一下我们的源代码,先后声明了buff2,check,buf,也就是先存buff2

注:我们存储的时候是先从计算机的高地址开始存储,然后到低地址(这里就牵扯到计算机原理了,感兴趣的自己去查)

答案:

高地址 buff2

    |       check

   V       buf

低地址

第三题分析:

好了我们现在才开始真正的审计我们的源代码

总结就是,定义一个比较的函数,定义几个变量,main函数传参数,复制到数组里面

ok现在开始讲我们缓冲区溢出的重要部分了

1.我们先往argv[]中的第9个字符传入十进制65

2.然后代码会把我们的字符串传入buf中

3.因为buf的大小只有8,所以传进去的东西是不是溢出了?

4.溢出的内容到哪里了?我们看我们刚刚的内存图,自然就知道是往高地址的地方走了,也就是65把check的值给覆盖了

5.到此我们成功的通过溢出进入了if里面,调用了challenge函数

答案:

往argv[]中的第9个字符传入十进制65

第四题分析:

上述代码所存在的漏洞名字就是缓冲区溢出拉,修正的话我们刚刚能够传大于8的数据进去,不就是因为strcpy的问题嘛,所以要加一个检测边界的功能

至此,缓冲区溢出的漏洞的基本原理讲完了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值