百度定义
缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区 又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。
危害
在当前网络与分布式系统安全攻击中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。
示例解释
通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的,这就是缓冲区溢出攻击。造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。
分析下面的代码:
#include"stdio.h"
#define BUFSIZE 64
char *gets(char *s)
{
int c;
char *dest=s;
while((c=getchar())!='\n'&&c!=EOF)
{
*dest++=c;
}
*dest++='\0';
if(c==EOF)
return NULL;
return s;
}
void bad_echo() //将产生缓冲区溢出
{
char buf[10];
gets(buf);
puts(buf);
}
void good_echo() //避免缓冲区溢出
{
char buf[BUFSIZE];
int i;
while (1)
{
if (!fgets(buf, BUFSIZE, stdin))
return;
for (i = 0; buf[i] && buf[i] != '\n'; i++)
if (putchar(buf[i]) == EOF)
return;
if (buf[i] == '\n')
{
putchar('\n');
return;
}
}
}
void main()
{
bad_echo();
//good_echo();
}
上文的代码中,gets函数的问题是它没法保证为保存整个字符串分配了足够的空间,调用bad_echo函数,当输入的字符串长度超过9时就会导致写越界。
good_echo函数中,利用fgets函数,通过BUFSIZE限制了输入字符串的长度,避免了输入字符串时产生写越界的可能。
要写出一个能处理任意长度输入字符串的函数,目前还没想出来。在C++中可以通过下述方法实现:
string s;
getline(cin,s);
比较cin.getline和getline(cin,s):
cin.getline适合预先知道读入大小,固定char数组,速度快;
getline(cin,s)不需要指定大小,但速度慢、生成的文件大,适合偷懒用。
更多相关内容,参考:http://wallimn.iteye.com/blog/440584