C语言黑客编程教学(2)--堆溢出实验

缓冲区是内存中存放数据的地方,一般来说,它是“包含相同数据类型的实例的一个连续计算机内存块”,它保存了给定类型的数据。应用最多的缓冲区类型是字符数组。
缓冲区溢出(Buffer Overflow)是指向固定长度的缓冲区中写入超出其预先分配长度的内容,造成缓冲区中数据的溢出,从而覆盖缓冲区相邻的内存空间。就象一个杯子只能盛一定量的水,如果倒入太多的水到杯子中,多余的水就会溢出到杯外。
一般来说,单单的缓冲区溢出,比如覆盖的内存空间只是用来存储普通数据的,并不会产生安全问题。但如果覆盖的是一个函数的返回地址空间且其执行者具有 root 权限,那么
就会将溢出送到能够以 root 权限或其它超级权限运行命令的区域去执行某些代码或者运行一个 shell,该程序将会以超级用户的权限控制计算机。
造成缓冲区越界的根本原因是由于 C 和 C++等高级语言里,程序将数据读入或复制到缓冲区中的任何地方,所用函数缺乏边界检查机制,包括 strcpy()、strcat()、sprintf()、vsprintf()、gets()、scanf()、fscanf()、sscanf()、vscanf()、vsscanf()和 vfscanf()等。
比如一个简单的例子:
void overflow (char *input)
{
char buf[20];
strcpy(buf,input);
}
strcpy()将直接将 input 中的内容复制到 buf 中。如果我们赋予 input 的长度大于 20,就会造成 buf 的溢出,使程序运行出错。
最常见的手段是通过制造缓冲区溢出使程序运行一
个用户 shell,再通过 shell 执行其他命令。如果该程序属于 root 且有 suid 权限的话,攻击者就获得了一个有 root 权限的 shell,便可以对系统进行任意操作了。

#include 
#include 
#include 
#include 
#define FILEMME "myoutfile"
int main (int argc, char *argv[])
{
FILE *fd;
int diff;
char bufchar [100];

char *buf1= (char*)malloc (20) ;
char *buf2= (char*)malloc(20); 
diff=buf2 - buf1; 
strcpy (buf2, FILEMME);
printf("buf1存储地址:%p: \n", buf1);
printf("buf2存储地址:%p,储存内容为文件名:%s\n", buf2,buf2);
printf("两地址间距离:%d个宇节\n", diff);
if(argc<2)
{
printf("请输入要写入文件%s的字符串:\n",buf2);
gets (bufchar);
strcpy (buf1,bufchar);
}
else
{
strcpy(buf1,argv[1]);
}
printf("bufl存贮内容:%s \n",buf1);
printf("buf2存储文件名:%s \n" ,buf2);

printf ("将%s写入文件%s中\n", buf1, buf2);
fd=fopen(buf2, "a");
if(fd==NULL)
{
fprintf (stderr," %s 打弁错误\n", buf2);
if (diff<=strlen(bufchar))
{
printf("提示:buf1内存溢出!");
}
getchar();
exit(1);
}
fprintf (fd,"%s\n"	,buf1);
fclose(fd);
if (diff<=strlen(bufchar))
{
printf("提示bufl已溢出,溢出部分覆盖buf2中的myoutfile!\n");
}
getchar();
return 0;
}

当我们输入内容少于buf2与buf1中间距离时候,这时候没有问题不会报错
buf1存储地址:0000000000191B10:
buf2存储地址:0000000000191B70,储存内容为文件名:myoutfile
两地址间距离:96个宇节
请输入要写入文件myoutfile的字符串:
1
bufl存贮内容:1
buf2存储文件名:myoutfile
将1写入文件myoutfile中

刚好输入中间差距长度的字符,此时buf2为空

buf1存储地址:0000000000A11B10:
buf2存储地址:0000000000A11B70,储存内容为文件名:myoutfile
两地址间距离:96个宇节
请输入要写入文件myoutfile的字符串:
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
bufl存贮内容:123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
buf2存储文件名:
将123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456
写入文件中
打弁错误
提示:buf1内存溢出!

过长以后也会溢出
buf1存储地址:0000000000021B10:
buf2存储地址:0000000000021B70,储存内容为文件名:myoutfile
两地址间距离:96个宇节
请输入要写入文件myoutfile的字符串:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111qwewqewqewqe
bufl存贮内容:1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111qwewqewqewqe
buf2存储文件名:1111111111111111111qwewqewqewqe
将1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111qwewqewqewqe
写入文件1111111111111111111qwewqewqewqe中

这就是缓冲区溢出的基本原理

你可能感兴趣的:(C语言黑客编程教学)