看程序体验缓冲区溢出漏洞

     缓冲区溢出漏洞从计算机出现初期就已经存在,并且今天仍然存在。大多数Internet蠕虫程序使用缓冲区溢出漏洞来传播,甚至Internet Explorer中的O-day漏洞,2004年的Sasser是一个利用微软操作系统的Lsass缓冲区溢出漏洞就是由于缓冲区溢出造成的。
   缓冲区溢出通常是向数组中写数据时,写入的数据的长度超出了数组原始定义的大小。C 语言的教程里时通常会告诉你程序溢出后会发生不可预料的结果,但在网络安全领域,缓冲区溢出是可控的。
   C语言是一种高级程序设计语言,但C假定程序员负责数据的完整性。如果将这种责任移交给编译器,由于对每个变量都要检查其完整性,最后所得到的二进制速度将会非常慢。并且,这会使程序员失去一个重要的控制层,并会使语言复杂化。
    尽管C语言的简单性增加了程序员的控制能力,提高了最后所得到的程序的效率,但是,如果程序员不小心的话,这种简单性会导致程序缓冲区溢出和存储器泄漏这样的漏洞。这意味着一旦给某个变量分配了存储空间,则没有内置的安全机制来确保这个变量的容量能适应己分配的存储空间。如果程序员把10个字节的数据存入只分配了8个字节空间的缓冲区中,这种操作是允许的,即使这种操作很可能导致程序崩溃。这称为缓冲区超限(buffer overrun)或缓冲区溢出,由于多出的2个字节数据会溢出,存储在己分配的存储空间之外,因此会重写已分配存储空间之后的数据。如果重写的是一段关键数据,程序就会崩溃。下面以在Linux环紧下,代码overflowe.c提供了一个讲解的例子。

 

 

gcc编译
      编译,即把人类可读的源代码转换为机器可读的二进制文件的过程,编译得到的二进制文件可在计算机上执行。更具体地说,编译器接受源代码,并将其转换为一组中间文件称之为目标代码。这些文件接近可执行文件,但可能引用了一些初始源码文件中未包含的符号和函数,这些引用在目标代码文件中是无法解析的。这些符号和引用通过称之为链接的过程进行解析,在此过程中各个目标文件相互链接起来,形成可执行的二进制文件。在这里,笔者简化了编译过程,以便读者理解。当使用C语言在Unix系统上编程时,所选的编译器是GNU C Compiler (gcc)。Gcc提供了许多选项供编译时使用。最常用的选项:
-o filename 编译得到的二进制文件以指定的文件名保存,默认是a.out
-c 只编译不链接,生成的目标文件扩展名为.o, 下面我们开始编译overflow_example.c

    现在,您应当能够读懂上面的源代码并且能弄明白程序要干什么。在下面例子的输出中,程序编译之后,我们试图从第1个命令行参数复制10字节到buffer two,但给它已分配的内存只有8字节。请大家注意在内存中buffer_one紧挨在buffer_two的后面,因此将10字节复制到buffer_two中时,最后两个字节9 0会溢出到buffer_one中,并将这里的数据覆盖。较大的缓冲区自然会溢入到其他变量中,但是如果使用了一个足够大的缓沖区,程序会崩溃并终止。

 

     为什么得到segmentationfault?,是因为地址超出了进程段的允许范围,从而导致了segmentationfault。  

  好了,以上我们已经可以通过溢出来修改目标程序流程了,已经掌握了溢出的基本原理。现实生活中的溢出利用当然更复杂一点,需要更多的系统体系结构知识和小技巧而已。相信你以后会逐步了解到所谓溢出漏洞.

 最后我们浏览下面这段视频,下面的输出展示了程序编译和执行的过程  下载高清视频: http://down.51cto.com/data/155677