(4)数组边界检查
可以说缓冲区溢出的根本原因是没有数组边界检查,当数组被溢出的时候,一些关键的数据就有可能被修改,比如函数返回地址、过程帧指针、函数指针等。同时,攻击代码也可以被植入。
因此,对数组进行边界检查,使超长代码不可能植入,这样就完全没有了缓冲区溢出攻击产生的条件。只要数组不能被溢出,溢出攻击就无从谈起。
为了实现数组边界检查,则所有的对数组的读写操作都应当被检查,以确保对数组的操作在正确的范围内。最直接的方法是检查所有的数组操作,但是会使性能下降很多,通常可以采用一些优化的技术来减少检查的次数。
(5)使堆栈向高地址方向增长
缓冲区溢出的一个重要要素是植入的代码成功地被执行。最常见的是被植入的代码放在堆栈区中。通过修改操作系统核心,在核心层引入保护机制,限制代码在堆栈区的执行,这样,缓冲区溢出攻击就不可能成功。
到目前为止,我们讨论利用函数返回地址控制程序转移到攻击代码的攻击方法时,有一个基本的前提,那就是当堆栈被压入数据时,栈顶向低地址方向增长,只有这样,缓冲区溢出时才可能覆盖低地址处的函数返回地址指针,从而控制程序转移到攻击代码。如果我们使用的机器堆栈压入数据时向高地址方向前进,那么无论缓冲区如何溢出,都不可能覆盖低地址处的函数返回地址指针,也就避免了缓冲区溢出攻击。但是这种方法仍然无法防范利用堆和静态数据段的缓冲区进行溢出的攻击。
(6)程序指针完整性检查
程序指针完整性检查是针对上述缓冲区溢出的另一个要素——阻止由于函数返回地址或函数指针的改变而导致的程序执行流程的改变。它的原理是在每次
在程序指针被引用之前先检测该指针是否已被恶意改动过,如果发现被改动,程序就拒绝执行。
因此,即使一个攻击者成功地改变程序的指针,由于系统事先检测到了指针的改变,因此这个指针不会被使用。与数组边界检查相比,这种方法不能解决所有的缓冲区溢出问题。但这种方法在性能上有很大的优势,而且兼容性也很好。
程序指针完整性检查大体上有三个研究方向:第一,手写的堆栈检测;第二,堆栈保护;第三,保护指针。在手写的堆栈检测中会介绍Snarskii为FreeBSD开发了一套定制的能通过监测cpu堆栈来确定缓冲区溢出的libc。在堆栈保护中会介绍我们自己的堆栈保护方法所开发的一个编译器,它能够在函数调用的时候自动生成完整性检测代码。最后在保护指针中介绍正在开发中的指针保护方法,这种方法类似于堆栈保护,它提供对所有程序指针的完整性的保护。
1)手写的堆栈监测
Snarskii为FreeBSD开发了一套定制的能通过监测cpu堆栈来确定缓冲区溢出的libc。这个应用完全用手工汇编写的,而且只保护libc中的当前有效纪录函数。这个应用达到了设计要求,对于基于libc库函数的攻击具有很好的防卫,但是不能防卫其它方式的攻击。2)堆栈保护:编译器生成的有效纪录完整性检测
堆栈保护是一种提供程序指针完整性检查的编译器技术,通过检查函数活动纪录中的返回地址来实现。堆栈保护作为gcc的一个小的补丁,在每个函数中,加入了函数建立和销毁的代码。加入的函数建立代码实际上在堆栈中函数返回地址后面加了一些附加的字节,如图2示。而在函数返回时,首先检查这个附加的字节是否被改动过。如果发生过缓冲区溢出的攻击,那么这种攻击很容易在函数返回前被检测到。
但是,如果攻击者预见到这些附加字节的存在,并且能在溢出过程中同样地制造他们,那么他就能成功地跳过堆栈保护的检测。通常,我们有如下的两种方案对付这种欺骗:
a.终止符号:
利用在C语言中的终止符号如0(null),CR,LF,-1(EOF)等不能在常用的字符串函数中使用,因为这些函数一旦遇到这些终止符号,就结束函数过程了。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30355-8.html
声音也超好听
那么现在让你们在大陆投资只是为了把更多的台湾经济扣押在大陆