谈谈缓冲区的溢出

      缓冲区的溢出是我们经常遇到的一种错误情况,同时也是我们万万不能忽略的一种情况,因为它给程序乃至系统安全带来了很大的安全隐患。先给大家展示一段有安全隐患的代码:

 

#include "stdafx.h"
#include"stdlib.h"
void test();
void main(){

	test();
	system("pause");
}
 
void test(){

	char buf[4];
	printf("input:");
	gets(buf);
	puts(buf);
}


       缓冲区是程序运行的时候机器内存中的一个连续块,它保存了给定类型的数据。缓冲区溢出是指当向缓冲区内填充数据位数超过了缓冲区自身的容量限制时,发生的溢出的数据覆盖在合法数据(数据、下一条指令的指针、函数返回地址等)的情况。最好的情况是程序不允许输入超过缓冲区长度的字符并检查数据长度,但由于大多数程序都会假设数据长度总是与所分配的存储空间相当,进而存在缓冲区安全隐患。

       现在我们回过来看上面所给的代码,由于test()函数没有执行边界检查,最终会导致test()函数存在缓冲区溢出安全漏洞。test()函数的缓冲区最多只能容纳3个字符和一个空字符'\0',所以当输入字符超过4个的时候就会造成缓冲区溢出。该程序的堆栈说明如图(1)所示,buf[4]被存储在test()函数的栈帧里。

                                                                                                      

                 main()栈帧
                 函数的参数
                函数返回地址
                保存的%ebp
[3] [2] [1] [0]
                  test()栈帧

 图(1)堆栈说明

如果输入的三个字符“sdf”,buf[4]正好被三个字符和'\0'填充,输入三个字符后的堆栈说明,如图(2)所示。

 

                 main()栈帧
                 函数的参数
08 04 84 27
bf f2 2f d8
\0 f d s
               test()栈帧

图(2)输入3个字符后的堆栈说明

 

如果输入五个字符“asdfg”,%ebp的一些区域的内容将被覆盖,进而造成了缓冲区的溢出。输入五个字符后的堆栈说明,如图(3)所示。

 

 

                 main()栈帧
                 函数的参数
08 04 84 27
bf f2 \0 g
f d s a
               test()栈帧

图(3)输入五个字符后的堆栈说明

 

      人为 的缓冲区溢出一般是由于攻击者写一个超过缓冲区长度的字符串植入缓冲区,然后再向一个有限空间的缓冲区中植入超长的字符串,这时可能会出现两个结果:一是过长的字符串覆盖了相邻的存储单元,引起程序运行失败,严重的可导致系统崩溃;另一个结果就是利用这种漏洞可以执行任意命令,甚至可以取得系统root特级权限,进而危害系统安全。

     缓冲区溢出是目前导致“黑客”型病毒横行的主要原因。防止黑客利用换出去溢出发起的攻击,关键在于程序开发者在开发程序时仔细检出溢出情况,明令禁止数据溢出缓冲区。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(缓冲区,系统安全)