堆栈溢出的运行时探测(一)

文章:Run-time Detection of Heap-based Overflows
作者:William Robertson, Christopher Kruegel, Darren Mutz, and Fredrik Valeur(University of California, Santa Barbara)

声明:自己的理解不一定很透彻,对于自己就当笔记,不是逐字句翻译的。仅供大家参考,若有错误或不当之处欢迎批评指正!吐舌头

摘要:缓冲区溢出是如今网络上最常见的攻击类型之一。虽然目前基于栈的变量更普遍,基于堆的溢出正在获得愈来愈多的关注。现实世界中有一些漏洞,能够破坏堆管理信息并允许任意代码优于被攻击者的程序得以执行。

        本文提出了一项保护堆管理信息的技术,允许实时探测堆溢出。我们讨论了这些攻击的结构,我们提出的探测方案已经作为GNU Lib C的补丁。实验结果展示了此方法的探测效率。另外,我们讨论了内存保护的不同机制。

1. 简介

        缓冲区溢出漏洞属于如今网络中最骇人听闻的攻击。最近的研究表明报告给CERT的漏洞中大约50%是关于缓冲区溢出的。

        最常见的缓冲区攻击是基于堆栈溢出的。漏洞利用了程序调用的返回地址与局部变量存储在一起,溢出一个局部变量可以重写一个返回地址。当函数返回时更改程序流。这就无形中允许了恶意用户执行任意代码。

        基于堆栈的溢出可以分成两类:一类是分配给堆的缓冲区溢出,能够直接更改相邻内存块的内容;另一类则更改内存管理员使用的管理信息(如分配和释放内存)。多数内存分配都会将管理信息存储在本身的堆空间。攻击的主要思想就是修改管理信息,使得可以实现任意内存重写。这样,返回地址、连接表或者应用级别的数据都可以被更改。这类攻击是被Solar Designer首先提出的。

          本文提出的技术是为了保护基于边界标签的堆管理信息,防止被恶意或者意外更改。这种方法已经被用到Doug Lea的GNU Lib C 2.3版本的内存分配中了。

2. 关于堆栈溢出的预防和探测的相关工作

         目前关于堆栈溢出的预防和探测已经有很多研究。比较有名的是StackGuard,属于编译器的扩展,在每个函数返回地址前插入一个标识字符。当执行基于堆栈的攻击时,入侵者企图溢出分配给本地堆栈的缓冲区来改变当前函数的返回地址。这可能会使入侵者改变程序执行流并且控制执行过程。通过在返回地址和局部变量之间插入标识字符,返回地址的溢出会改变这个标识符,因此可以被探测到。

        也有不同的防攻击机制,通过仅仅在溢出流中插入标识符,这样会使保护机制不那么有效。一种解决方案是在启动程序的时候选择随机标识符,这样的标识符不能被猜到。另一种方案就是使用由4个不同字节组成的终结标识符,这4个字符由字符串操作函数库中的函数生成。这种方法原理是,入侵者需要插入这些字符溢出缓冲区来重写标识符并且不被探测到。然而,字符串操作函数遇到终结字符的时候会停止,因此返回地址保持不变。

        StackShield是一种类似的方法,这种方法不是在栈中插入标识符,而是保留第二个栈,只用来存储返回地址的副本。在一个程序返回之前,副本会与原始的地址进行比较,任何偏差都会使程序中止。基于堆栈的溢出是利用管理信息(函数返回地址)和数据(自动变量和缓冲区)存储在一起这个事实。StackGuard和StackShield都是强制保持栈内管理信息的完整性。我们的技术也是基于这种思想,将保护扩展到保护堆的管理信息。

        其他的预防堆栈溢出的方案不是被编译器强制加上的而是以库的形式执行。 Libsafe 和Libverify执行并覆盖了C函数库中的不安全函数。安全版本为运行中的缓冲区预测了一个安全边界,在任何写操作进行之前要先检查这个边界。这防止了在重写函数地址时的用户输入。

        另一种方法是使栈不能执行。虽然这并不能防止真正的溢出和返回地址的修改,这种方法是基于多数漏洞直接在栈上运行恶意负载这个事实。这种方法可能会阻碍合法使用,比如函数编程语言在运行时产生代码并且在栈上执行的时候。gcc使用可执行栈作为嵌套函数的中转,Linux用可执行用户栈来进行信号处理。这个问题的解决方案就是探测合法使用,动态地运行程序。然而,这样的方案通常情况下很难执行。

         关于保护堆内存的研究还不多。提供内存保护的系统是内存调试器,比如Nalgrind或者Electric Fence.这些工具监督内存使用(读和写)并且拦截内存管理调用来检测错误。这些工具使用的方法与我们的类似,企图保持使用内存的完整性。然而,每个内存使用都要进行检查,而我们的方法只有在分配和回收内存块的时候才需要进行检查。内存调试器有效地阻止非授权的内存使用,防止基于堆的缓冲区溢出。然而,这些工具会产生很大的运行代价,使程序变得很慢。

                未完待续。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值