Unix系统编程第一章:缓冲区溢出的后果

      缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统当机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。缓冲区溢出攻击有多种英文名称:buffer overflow,buffer overrun,smash the stack,trash the stack,scribble the stack, mangle the stack, memory leak,overrun screw;它们指的都是同一种攻击手段。第一个缓冲区溢出攻击--Morris蠕虫,发生在二十年前,它曾造成了全世界6000多台网络服务器瘫痪。

  1.概念

  缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间想匹配,这就为缓冲区溢出埋下隐患.操作系统所使用的缓冲区 又被称为"堆栈". 在各个操作进程之间,指令会被临时储存在"堆栈"当中,"堆栈"也会出现缓冲区溢出。

  2.危害

  在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。

        3.c语言例子

#include<stdio.h>
#include<string.h>
int main(){
  int d = checkpass();
  printf("%d\n", d);
  return 0;
}

int checkpass(void){
  char a[9];
  int x;
  x = 0;
  fprintf(stderr, "a at %p and\nx at %p\n", (void*)a, (void*)&x);
  printf("Enter a short word: ");
  scanf("%s", a);
  if (strcmp(a, "mypass") == 0)
     x = 1;
  return x;
}

1. 尽管程序只为数组 a 指定了9个字节,但编译器却为其分配了 12 个字节,这样,系统就可以维护一个与字边界对齐的栈指针了。

2. 在上面的程序中,如果字符数组 a 存储在栈上比整数 x 低的内存中,a 的缓冲区溢出可能会改变 x 的值。如果用户输入13个字符,那么,不管输入的是什么字符,x 都变成一个非零值,函数返回这个非零值。

3. 如果用户输入一个长口令,返回地址就会被重写,而且程序很可能就会试图返回到一个程序地址空间范围之外的单元上去,这样就会产生断保护错误(segmentation fault)和信息转储。



我互相掉换 x 和 数组 a 的声明位置,发现 x 总是在 a 的下面, 看来 unix 对于缓冲溢出机制还是不错的


你可能感兴趣的:(unix,操作系统,溢出,缓冲区,系统安全)