(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf_第1页
(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf_第2页
(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf_第3页
(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf_第4页
(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf_第5页
已阅读5页,还剩48页未读 继续免费阅读

(计算机软件与理论专业论文)软件安全漏洞的自动化探测方法研究.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要 本文的主要目的是如何使用自动化方法或者半自动化辅助的方法对漏洞 进行研究,尤其侧重于如何发现计算机软件中存在的安全漏洞。 本文首先对目前c c + + 程序中存在的各种安全漏洞做出总结,并对这 些漏洞的原理和如何进行相关漏洞的检测方法做出描述。之后,文章着重 描述了目前已有的各种自动化检测方法和半自动化工具,并对其进行了分 析对比。 目前已有的技术基本上集中在静态检测和黑盒测试方面,在这两方面的 探讨有大量的论文和实际的模型可以参考。而近来逐渐成为焦点的是动态 检测的方法,但是这方面的研究相对比较零散,没有一个系统仡的检测模 型和实际的实现。 基于现有的方法和经验,本文提出了以动态检测技术中的数据流检测为 核心的裣测流程和方法,将现有的静态分析、技未动态分析技术和黑盒测 试方法融入到漏洞检测的各个环节中。在考虑到检测效率和准确性的前提 下,充分利用各种检测技术的优点,来进行漏洞检测。 基于上述提出的流程和方法,我们发现了一些应用软件存在的安全漏 洞,这些漏洞的发现初步证明了我们提出的方法是有效的。 当然在实际的应用中,我们提出的检测流程和数据流检测,其中描述的 一些环节还有待于通过进一步的研究来完善,以使文中提出的流程和方法 可以达到检测更准确、人工干涉更少的自动化检测安全漏洞的目标。 a b s tr a c t t h i sp a p e rm m n l yf o c u s0 1 2h o wt ou s ea u t o m a t i cm e t h o do rc o m p u t e ra i d t o o l si nv u l n e r a b i l i t i e sr e s e a r c h ,e s p e c i a l l yo nh o wt of i n d8 e c l l r i t yv u l n e r a b i l - i t i e si nc o m p u t e rs o f t w a g e s a tt h eb e g i n n i n go ft h i sp a p e r ,t h e r ei sas u m m a r ya b o u ta l lt y p e so f v u l n e r a b i l i t i e si nc c + + p r o g r a m s ,a n dt h ep a p e rd e s c r i b e st h ep r i n c i p l e o ft h e ma n dh o wt od e t e c tt h e s ev u l n e r a b i l i t i e s t h e n ,t h ep a p e ra n a l y z e s c u r r e n ta u t o m a t i cm e t h o da n dc o m p u t e ra i dt o o l s a n dg i v eac o n t r a s ta m o n g t h e m c u r r e n tt e c h n o l o g yi sm a i n l yo ns t a t i cc h e c ka n db l a c kb o xt e s t ,a n dt h e r e a r el o t so fp a p e ra n dm o d d sa b o u tt h e m t h ed y n a m i cc h e c ki st h et e c h n o l o g y r a i s e dr e c e n t l y , b u tm a t e r i a l so i lt h i sa s p e c t & r er e l a t i v e l yr a g e ,a n dt h e r ei s n t a ni n t e g r a t e dm o d e ly e t b a s e do np r e v i o u se x p e r i e n c e s ,t h i sp a p e ri l l u s t r a t e sap r o c e d u r ew h i c hi s m a i n l yb a s e do nd a t af l o wt e c h n o l o g yo f ( 1 y n a m i c ( m e c k i n g a n di tc o m b i n e s s t a t i cc h e c k i n g ,d y n a m i cc h e c k i n ga n db l a c k - b o xt e s t i n t oa l la s p e c t so fi t b a s e dt h e i ra d v a n t a g e s u s i n gt h i sp r o c e d u r em e n t i o n e da b o v e ,w ef i n ds e v e r a ls e c u r i t yv u l n e r a - b i l i t i e si ns o l n ep o p u l a rs o f t w a g e s a n di tp r o v e st h a ti t se f f e c t i v et ou s et h i s p r o c e d u r e o fc o t l r s e i t sn o taf i n a lv e r s i o na n dt h e r ea r el o t so fp r o b l e m sw h i c h c a nn o tb es o l v e dy e t b u tw i t hm o r ed e e pr e s e a r c h ,i t se x p e c t e dt h a tt h e p r o c e d u r ec a l lm a k et h ec h e c k i n gm o r ee f f e c t i v ea n dr e d u c em o r eu l a l 3 u a l w o r k i 第一章1 序言 随着黑客攻击事件数量的不断上升,蠕虫在i n t e n e t 上的泛滥,信息安 全逐渐成为人们眼中的焦点。信息安全中的一个核心问题就是存在于计 算机系统中的安全漏洞,恶意的攻击者可以利用这些安全漏洞访问未授 权资源,甚至于破坏敏感数据。从上世纪9 0 年代,信息安全学者,计算机 安全研究人员就开始了对计算机安全漏洞的研究。常见的计算机漏洞包 括缓冲区溢出,格式化字符串,整数溢出等等( 本文对第二章中这些漏洞 进行了模式总结和归类) 。而研究的范围主要包括如何如何如何监测和防 止恶意攻击者利用安全漏洞进行攻击。由此衍生出来- i d s ( 入侵监测系统) 和1 p s ( k 侵防止系统) 等等商业产品,以及针对缓冲区溢出的堆,栈保 护,不可执行堆栈等等技术。直到本世纪初,研究人员才把研究重点放在 如何发现安全漏洞,进一步地,如何设计和使用自动化或者半自动化的辅 助工具发现软件中的安全漏洞成为最近相关研究的热点。 传统的漏洞发现一般是安全研究人员通过阅读源代码或者对软件进行 反汇编分析,在理解软件工作原理的情况下,通过手工对目标软件进行 分析,从而发现软件中的安全漏洞。随着软件安全性需求的不断增强,这 种手工作坊式的方法难以满足快速和准确地找出软件漏洞的要求。在这种 形势下,利用自动化方法或者半自动化的辅助工具发现漏洞成为研究的重 点。 自动化方法或者半自动化的辅助工具有如下需求: 快速准确发现软件中的安全漏洞 可以对无源码的闭源软件进行测试 2第一章1 育言 尽可能的提供相关的信息,例如软件运行时数据,调用序列等等 完善的漏洞检测模式,尽可能提供对目前已有的漏洞模式的检测 本文的目的就是研e c c + + 软件漏洞发现过程中存在的各种问题,以 及如何设计和编写相关的漏洞发掘辅助工具,从而解决这些问题,进而实 现半自动化以及自动化的漏洞发现。 如何发现漏洞,首先要了解计算机漏洞的原理,以及对安全漏洞的模式 进行总结,归类。本文第2 章中描述了常见的安全漏洞,例如缓冲区溢出, 格式化字符串,整数溢出等等,井对这些漏洞进行模式总结和归类,同时 总结出了判断各种漏洞需要的相关信息以及判别模式。在第2 章最后,文章 着重描述了漏洞存在于什么类型的计算机软件中,以及如何针对不同类型 的软件进行漏洞分析。 之后第3 章中主要探讨发现漏洞的自动化方法和半自动化的辅助工具。 目前利用自动化方法发现漏洞基本上可以归为两类,一类是基于软件测试 中的黑盒测试原理,这类方法主要针对软件提供的接口,而不是针对软件 的实现进行测试。测试引擎通过发送大量的测试例对软件进行测试,如果 监测到被测试软件有异常情况( 例如软件崩溃,或者产生异常等等) ,就 可以使用一些判断条件来确定是否某个测试例可以触发软件漏洞。 这一类的典型方法可以参考f 和i t l 的研究方法。在文献1 3 1 描述的针 对s i p , h 3 2 3 ,s n m p 等等协议的测试中,已经有效地发现了多个安全漏洞; 而s p i k e n 在其不断的开发过程中,发现了微 x w i n d o w s 操作系统,以及微 软s q ls e r v e r 中多个远程缓冲区溢出漏洞。 另外一类是使用编译技术,对软件的源代码进行扫描,针对不安全的 库函数使用以及内存操作进行语义上的检查,从而发现安全漏洞。其中的 典型就是文献【4 6 | 中描述的静态检查技术,与此类似的还有( 6 】, 7 1 等等,但是 这些检查方法只能局限于从库函数使用错误,不能识别动态内存错误。文 献【8 】8 中提出了使用静态方法检查动态错误的简单模型,但是检测效果不是很 明显,难以进行实用化的操作。静态方法着重点还是在代码扫描和函数使 用检查上,而且静态检查方法只能针对开源软件进行检查,对于一些闭源 软件束手无策。 微软( t + j v i u s a lc + + n e t 编译器中【1 0 】使用了相关的方法进行安全性检查 以尽可能地减少软件中的安全隐患。除了针对开源软件软代码扫描的方、法 之外,b u g s c a m l 7 ;和b u g a u d i t t 4 1 l 在反编译平台i d ap r o 弱i 基础上,针对编译 后的二进制可执行文件进行静态检查,在针对非开源软件方向上做出了有 3 益的尝试。同样地,针对二进制可执行文件的检查也存在着缺乏运行时数 据带来的一系列问题。 诚然,上述自动化方法确实很有成效地发现了一些安全漏洞,但是发现 的这些安全漏洞模式相对简单,而且这些测试方法还存在着许多不足。黑 盒测试相对比较盲目,难以达到比较理想的分支覆盖测试,同时测试的结 果依赖于测试例,而测试例的构造需要对被测试软件使用的协议,接口信 息有很深入的了解。基于编译技术的方法由于缺乏软件运行时的数据,难 以确定软件在实际运行时的数据以及执行状态,造成无法进行漏洞判断, 或者判断的失误率过高。 基于上述考虑,一些安全研究人员对运行时检查安全漏洞的方法进行了 探讨。文献 i i 提出了一些运行时的检测方法,但是其中描述的技术过于分 散,没有形成一个系统的模型和工具,而且,没有对如何在运行时匹配漏 洞模型给出一个完整的构想。 本文基于以上因素的一些考虑,在第四章中经过对相关的漏洞挖掘方法 的研究对比和分析,选取了运行时的数据流分析作为分析的核心组建,在 不同的分析过程中融入不同的分析方法。在此基础上实现了一个简单的检 测模型。本文实现的检测模型可以在运行时实现细粒度的调用树记录,数 据流信息记录,并且可以根据这些记录的信息进行漏洞模式的匹配,从而 实现运行时检查软件可能存在的漏洞。 在本文的最后对上诉检测方法做了简单的总结回顾,比较了各种方法的 优劣,并对自动化和半自动化的漏洞挖掘辅助工具提出了展望。 第二章2 安全漏洞概述 在r f c 2 8 2 8 “j 中对漏洞1 的定义如下 af l a wo rw e a k n e s si nas y s t e m sd e s i g n i m p l e m e n t a t i o n o ro p e r a t i o na n dm a n a g e m e n tt h a tc o u l db ee x p l o i t e dt ov i o l a t et h e s y s t e m ss e c u r i t yp o s c y 也就是说安全漏洞可以被恶意攻击者用来突破系统的安全策略,从而访 问未授权的资源和数据。安全漏洞存在于计算机软件的各个方面,这一章 我们主要针对如下几个问题对计算机安全漏洞进行分类总结: 什么样才是安全漏洞 安全漏洞在哪里 怎么样判断一个安全漏洞 2 1 安全漏洞类型 文献1 2 q 和| 2 8 | 对程序员如何防止编写的程序中出现相关的安全问题提出了 有益的建议,同时也对安全漏洞的类型做出了总结和归类。 一般来说比较典型的可以用来提升权限的漏洞包括 缓冲区溢出 1 英文为v u l n e r a b i l i t y 4 2 1 安全漏洞类型 5 整数溢出 格式化字符串 条件竞争( r a c ec o n d i t i o n l 函数重入 解析错误 设计错误 s q li n j e c t i o n c r o s ss i t es c r i p t 其r 丰i s q li n j e c t i o n 和c r o s ss i t es c r i p t 属:= j :w e b 脚本范围,不在本文涉及 范围,本文描述的主要针对c c + + 编写的软件。这里我们将条件竞争,函 数重入,解析错误和设计错误四类归为逻辑漏洞。下面文章将详细解释每 一种漏洞模式以及相关的检测方法和需要的信息以及判断的方法。 2 1 1 缓冲区溢出 文献【1 2 l 描述了缓冲区溢出攻击和防范的手段,文献 2 3 i 是经典的描 述u n i x 环境下缓冲区溢出问题的文章,关于缓冲区溢出技术上的解释 以及如何利用缓冲区溢出获取权限执行代码在这篇文章中都都有详细的描 述。这里我们从漏洞检测的角度出发,以归纳总结漏洞模式为主要任务, 以此入手来总结缓冲区溢出的类型。 简单地,我们将缓冲区溢出分为如下几类进行详细说明。 2 1 1 。1 不安全的库函数使用 这一类错误是之前提到的文献中描述最多的,形如 c h a rd s t 2 5 6 ; c h a r8 r c 1 0 2 4 ; s t r c p y ( d s t ,s r c ) ; 的代码中,如果s r c 缓冲区中的字符串长度大于2 5 6 ,那么s t r c p y 的执行将导 致一个典型的缓冲区溢出问题。这里我们在缓冲区溢出的基本原理和如何 利用这类问题执行代码上不做太多叙述,具体的可以参考【2 3 】和i2 7 1 中关于缓 6第二章2 i 安全漏漏概述 冲区溢出的叙述。这里我们对常见的可以导致缓冲区溢出的不安全的库函 数做简单总结,具体如表2 1 2 所示。 l 函数名函数参数同类醇数 备注 s t r c p y 目标地址,源地址 s t r c p y ,s t r c a t ,w c s c p y , w c s c a t s p r i n t f 目标地址,源地址,格式串s p r i n t , f ,v s t ) r i n t f ,s w 斋婴包含s 类似的格 p r i n t f 、v s w n i n t f 式串 s s c a l l i 目标地址,源地址,格式串s s c q n f ,v s s c a n f ,s w s 一 需要包含s 类似的格 ( :a l i f v s w s c a n f式串 f g e t s 目标地址 f g e t , s ,g e t s 用来从s t d i o 括得字符 宙 g e t w d 目标地址 g e t w d 没有分配足够空间串 容纳结果 r e a l o a t h目标地址,源地址 r e a l p a t h ,m u l t i c h a r 一 罕符串转化,没有分 露矗f i d e c b a r配足够空间容纳结果 可以根据函数参数中包含的元素将这些典型的危险库函数分为三类,从 i 币根据不同的判断方式进行漏洞匹配。表21 。 t 列出的函数参数有三类:目 标地址,源地址和格式串,这里我们分别用d s t ,s r c 干n h n t s t r 来表示这些字符 串,) 手 l e n ( d s t ) ,l e l l ( s r c ) 和l c i ,( f m t s t r ) 来表示这些字符串的长度。 s l r c p y ,这一类函数只有d s t 和s i c 两个参数,在判断缓冲区溢出时,只要 满足 f 2 1 1 s p r i n t f 与s s c a l l f ,这一类函数除l d s t f l j s r c 删个参数之外,还有一个格 式串,一般而言只有f i n t s t r 中包含了”s ”或者”s ”类似的格式串时, 才有可能发声缓冲区溢出。刚时格式f : f 中还有控制字符串输入长 度的元素,例如”5 0 s ”就是只接受5 0 个字节的字符串。此时,我们 用f i n t l e n 来表示格式串中b j 以接受的缓冲区的长度3 所以判断这一类函 2 这里所列的函数t :;1 a n s lc 标准为准,其它库函数的实现可能有所不同,一些其它 非a n s lc 典型的例子也有收录 3 形如”a b c s e f g ”的格式串中f m t l e n :l e n ( s r c ) + l e n a i l c ”+ e n ”e f g ”,而形 如”a b c 5 0 s d e f ”的格式串中,f m g l e n = 5 0 一l e n ( ”a p , c ”1 一t e n ( ”e f g ”1 2 。1 ,安全漏洞类型 数使用时是否发生缓冲区溢出的条件就是 l e n ( d s t ) m a ;z l e n( 2 3 ) 2 1 1 2 库函数使用错误 为了解决以上使用不安全的库函数错误,一般地,安全编程的建议是使 用安全的库函数来替代上述的库函数,从而解决潜在的安全问题。表2 2 列 出了各种不安全库函数的替代函数。 库函数名称督代函数 s t r c p y , s c r c a ts t r n e p y , s t r n c a t w c s c p y , w c $ c a tw c s n c p y , w c s n c a t s p r i n t f , v s p r i n t f s n p r i n t f , v s n p r i n t f s w p r i n t f , v s w p r i n t f s w n p r i n t f , v s w n p r i n t f 相应的替换函数在原有函数参数的基础上,加入了一个s i z e 的整数参 数,用来限制写入d s t 缓冲区的总长度。这里以s t r n c p y 为例,函数的原型为 c h a r * s t r n c p y ( c h a r * d e s t ,c o n s tc h a r s r c ,s i z e tn ) 8 s t r n c p y 的正确使用方法应该为 c h a rd s t 2 5 6 j c h a r $ r c i 0 2 4 ; s t r n c p y ( d s t ,s r c ,s i z e o f ( d s t ) 一1 ) ; d s t s i z e o f ( d s t ) 一1 = 0 : 第二蕈2 安全漏祷撅述 长度值为8 i z e o “d s t ) 一1 ,这样限制了8 t h l c p y 操作中,最大拷贝到d s t 缓冲 区的数据不超过d s t 缓冲区的长度一l 。最后将缓冲区的最有一个字符设置为 字符串的结束标志0 ”。 但是在实际的软件开发过程中,程序编码人员对于这些安全库函数的使 用存在很多错误。下面是几种常见的错误: 错误的s i z e 值 最常见的使用错误是s t r n c p y 中的s i z e 参数指定错误,具体的代码如下 这样的操作实际上等同于 上诉使用方法相当于还是饺用了一个不安全的庠函数,s t r n c p y 完全没 有起到应该有的保障作用。 这样的误用s i z e 值的函数除- ( s t r n c p y 类似的安全字符串操作函数之 外,还存在:j :m e m c p y ,i n e m l n o v e 等等函数的使用中a 在这种情况 下,判断此类函数的使用是否导致缓冲区溢出问题,需要满足 s i z e l e n ( d s t ) 且l e n ( s r e ) l e n ( d s t ) 4 这是为了解决下文叙述中的n u l lt e r m i n a t e 问题 ( 2 4 ) cn 虹。 弱k 晗n 拈 乳k “ d长8 让 缸 m血- 8 乳 2 1 安全漏漏类型9 o f fb yo n e o f fb yo n e l 2 4 1 是一类极端情况下的缓冲区溢出问题,在这种情况 下,目标缓冲区将被溢出一个字节。文献中详细描述了o f fb y o n e 的原因以及如何利用这一类漏洞执行命令。这里s n p r i n t f 中s i z e 参 数的误操作也会引起o f fb yo n e 的问题5 。 下面的代码是一个典型的o f fb yo n e 问题 c h a rd s t 2 5 6 ; c h a rs r c i 0 2 4 ; s t r n c p y ( d s t ,s r c ,s i z e o f ( d s t ) ) 如果s r c 的长度超过d s t ,s t r n c p y 在对字符串拷贝结束之后,会在”d s t + s i z e o f ( d s t ) ”处写入一个o ,而d s t + s i z e o f ( d s t ) 已经超越了d s t 缓冲区一 个字节。在某些特定的情况下,例如d s t 靠近s t a c kf r a m ep o i n t e r ,这将 导致f r a m ep o i n t e r 中的一个字节被修改,从而引起o f fb yo n e 的安 全问题。 这种情况的判断很简单,只要符合如下条件即可 s i z e = = l e n ( d s t 、( 2 5 ) n u l lt e r m i n a t o r 由于规范之间的不同6 导致s n p r i r l t f 此类函数的实现有所不同。即在有 些库函数版本中,s n p r i n t f ;卞保证操作之后的目标字符串最后会以字符 串的结束标志n i l 结束。 下面是l i n u x 操作系统下s n p r i n t f 的m a n 页对这个问题的描述: t h ef u n c t i o n ss n p r i n t fa n dv s n p r i n t fd on o tw r i t em o r et h a n s i z eb y t e s ( i n c l u d i n gt h et r m l i n gn i l ) i ft h eo u t p u tw a st r u u - c a t e dd u et ot h i sl i m i tt h e nt h er e t u r nv a l u ei st h en u m b e r o fc h a r a c t e r s ( n o ti n c l u d i n gt h et r a i l i n gn i l ) w h i c hw o u l d h a v eb e e nw r i t t e nt ot h ef i n a ls t r i n gi fe n o u g hs p a c eh a db e e n a v a i l a b l e 5 这个问题只存在于一些特定版本的c 库函数中 6 例如s u s ( s i n g l eu n i xs p e c i f a t i o n ) t c 9 9 :之i n - 1 0 第二章27 安全漏洞概述 上诉操作将会导致s n p r i 毗操作之后的d s t 字符串进入一个不确定状 态,此字符串计算出来的长度有可能会比实际的大,之后对d s t 进行的 操作可能会引起潜在的安全问题。 2 1 1 3 循环错误 循环中进行内存相关的操作时,如果循环的边界值选取不正确,或者内 存读写的地址偏移计算错误都会引起相应的安全问题。这一类问题的解决 涉及到如下几个问题: 如何从源码和二进制文件中寻找循环块 判断循环块中是否有内存读写操作 这些操作是否会引起安全问题 目前为止,在探测循环中内存读写是否存在安全问题这个问题上并没有 一个比较实用化的方法或者模型。但是安全研究人员已经在这个问题的部 分子集上取得了一些成果。 文献p 。l 中描述了如何在二进制代码中发现函数体l j 的循环和判断循环中 是否有内存读写操作。作为文献【2 q 的一个实用化结果,工具 4 爿中提供了从 二进制文件的反汇编结果中发现函数体内是否有循环的功能。这些成果主 要是针对二进制文件中代码识别困难这一问题做出的,虽然对于最终的自 动化或者半自动化检测没有直接贡献,但是也是这一方面有益的尝试。 另外还有一些总结出来的模式,例如,在一个循环内部调用f r e e ,有可 能会造成2 1 4 中描述的d o u b l ef r e e 问题。最为典型的就是i a 3 2 体系结构中针 对循环操作和内存操作优化的一系列指令,这些指令从某种意义上等同于 一些常见的库函数操作,表2 3 给出了两者之间的对比关系。这里和安全相 指令厍幽数备注 r e p em o v s b d ws t r c p y , s t r n c p y , m e m c p ye c x :x 黾s i z e ,e d i 是d s t ,e s i 是8 r c r e p es t o s b d w m e m s e t 同上 r e p es c a s b w 】 s t r l e n 关的就是r e p e l o v s 【b d w 】系列指令,此时我们采取2 1 1 1 与2 1 1 2 中的检查 方法进行即可。 这些都是一些零散的不成系统的组合,一个完整的针对循环错误的检查 模型依赖于数据沸分析和数据关联技术的进一步提高。 2 1 安全漏洞类型 2 1 1 4 异常函数返蚓值 在软件开发的过程中,很多时候使用函数的返回值作为计算内存偏移的 参考值。例如如下部分的代码: i n tm a i n ( i n ta r g c ,c h a r * * a r g v ) t c h a rb u r 5 0 : c h a r * p t r ; p t r = b u r ; p t r + 一s n p r i n t f ( p t r ,s i z e o f ( b u i ) ,”7 s ”,a r g v n ) ; p t r + = s n p r i n t f ( p t r ,s i z e o f ( b u f ) 一( p t r b u r ) ,“x s ”,a r g v 2 ) ; p r i n t f ( “:i s n ”,b u f ) : 在正常情况下,s n p r i n t f 酐j 返回值是已经写入到目标缓冲区中的字符个 数,但是在某些c 库函数7 的实现中,如果目标缓冲区p t r 不足以容纳数据时 或者s n p r i n t f 的调用发生内部错误8 时,此f l 寸s n p r i n t f 的返回值是一个负数, 这样第二个s n p r i n t f 的调用中,s i z e 的计算就不正确,不能反映真实的调 用,此时s n p r i n t 珀调用就会出现错误。 其它还有类似的例子,这里不一一列举。对于这种类型的错误,只能通 过记录实际调用过程中的函数返回值来等待进一步的判断。 2 1 2 整数溢出 2 0 0 2 年出现了很多基于整数溢出的安全漏洞,包括a p a c h eh t t p d 圳, o p e n s s h i “i 以及s u nr p c 的x d rl i b 3 2 】都存在着整数溢出的问题。文 献【2 5 l 描述了整数溢出的原理以及相应的执行代码的技术。文献【z q 中将整数 溢出分为三类 w i d t h n e s so v e r f l o w s a r i t h m e t i co v e r f l o w s s i g n e d n e s sb u g s 7 例如g l i b c 4 8 目前所有的c 库函数中,发生i o 错误都会返回一个负值 1 2 第二章2 安全漏嗣概述 、这里我们按照其成因,将w i d e n e s s 溢出和s i g n e d n e s s 溢出归为一类,因 为这两种整数溢出都是在不同类型的整数值转化之中发生的错误。w i d e n e s s 是:- 忽略了一个s i g n e di n t j , 于0 的情况,而直接将其转化为一个u n s i g n e di n t 整 数,之后作为参数传递给被调用函数;而s i g n e d n e s sb u g s 同样也是由 于s i g n e di n t 和u n s i g n e di n t 之间的差异造成的安全问题。 a r i t h m e t i co v e r f l o w s 是由于每个平台上表示整数值都有一个上限值或者 下限值( 有符号数的负数边界值) ,如果一个整数值达到了这个上限或者下限 值,整数值将越过这个界限变成另外一个和原有值差距很大的整数值,从 而导致安全问题。例如对于一个u n s i g n e di n t 自j 3 2 位整数值,下边是一些边 界值计算时的错误: o x f f f f f f f + 1 = o x o o x 9 0 0 0 0 0 0 2 = o x 2 0 0 0 0 0 0 0 o x l o o x 2 0 0 = o x t t f f f e i o 文献1 2 5 中举出了一个比较典型的基于上诉原理的错误代码: i n tc a t v a r s ( c h a r * b u l l ,c h a r * b u f 2 ,u n s i g n e di n tl e n l u n s i p 丑e di n tl e n 2 ) ( c h a rm y b u f 2 5 6 3 ; i f ( ( 1 e n l + f e n 2 ) 2 5 6 ) t 3 十 r e t u r n i : ) m e m c p y ( m y b u f ,b u f l ,l e n l ) : 4 m e m c p y ( m y b u f + l e n l ,b u r 2 ,l e n 2 ) : d o s o m e s t u f f ( m y b u f ) r e t u r n0 ) l e t , 1 = o x l 0 4 j l l e n 2 = o x 艇雕c 时候,可以通过 3 】中的检查,但是单独 f l 够寸m e m c p y q ;进行的内存操作远远超过2 5 6 个字节,所以m e m c p y 的操作将 导致一个缓冲区溢出。 2 1 安全漏溺类型 出于上述考虑我们将整数溢出分为如下两类,使用不同的方法进行检 测。 有符号整数向无符号整数的转化 整数边界值溢出( o v e r f l o w ,u n d e r f l o w ) 文献【l q 提出了一个数据驱动的有限状态机模型,用来检测安全漏洞。但 是只针对”有符号整数向无符号整数的转化”中的有符号无符号问题提出了 检测模型,而且这个模型太过于理论化,缺乏一个实用化的检测平台来实 现。而且其中些问题太过于依赖手工,例如将程序模型转化为有限状态 机的过程。 这里我们将整数溢出的安全问题可以分为以下面三个部分来考虑,而针 对整数溢出的检测也可以从这三个方面入手来进行进一步的研究: 1 首先程序从用户输入得到一个整数值,这个整数值可以是直接指定的 数值,也可以是根据用户输入的某些数据计算而来的整数值9 。 2 然后程序将这个整数值和某一个数组或者内存区域联系起来,针对堆 或者栈的操作地址是由这个内存值计算而来的。 3 最后程序使用某一些操作函数或者指令来对内存进行操作。 第一个步骤的主要目的是确认函数中的某一个整数值是否来源于用 户输入。此时需要从用户输入处进行代码扫描或者数据流跟踪来判断 是否到达最终某一个操作的值是否来源子这个用户输入。这个问题我们 在2 2 和2 3 节中有详细描述。 第二个步骤就是确定用户输入的某个整数值或者由用户输入计算而来的 数值,这个数值在最终到达操作点之前是否有数学运算或者其它影响值变 动的操作。以及对这些整数值进行边界检查时的边界值。这是一个很复杂 的过程,涉及到对自动理解程序算法以及针对某一个特定数据的数据流跟 踪a 我们在2 3 中有详细描述。 第三个步骤主要是最终发生安全问题的点,一般来说针对整数溢出,我 们需要对如下函数1 0 进行检查 内存分配函数( m a l l o c ,i i e w ) 9 例如字符串长度 ”这些函数的整数值参数般都足无符号整形 1 4第二章2 安全漏洞概述 字符串,内存拷贝函数 循环边界值 检查的内容包括,关联整数值,即将函数的整数参数与用户输入进行关 联,检查整数参数是如何从用户输入的内容中变化而来的。其次就是是否 对这个整数值进行了边界检查,需要特别注意的是程序中是否对一个有符 号整数小于0 的情况做出检查n 。只要符合上述两个条件,即这个整数来源 于用户输入,而又没有进行严格的边界检查,或者存在着不同类型的整数 相互转化,就可以判断这里存在着潜在的整数溢出问题。 2 1 3 格式化字符串 格式化字符串漏洞存在与p r i n t f 类似的格式化输出或者转化函数中。文 献【2 6 l 中详细描述了存在格式化字符串漏洞的函数以及如何利用格式化字符 串漏洞获取权限,执行命令。这里我们只简单在表2 ,4 “列举一下下存在格 式化字符串漏洞的库函数。 幽数名相关幽数 用途 p r i n t fp r i n t f v p r i n t f ,f p r i n t f ,v p r i n t f 格式化输出 s p r i n t fs p r i n t f ,s n p r i n t f , v s p r i n t f , v s - 格式化转换 n p r i n t f s e t p r o c t i t l e 设置输入参数 s y s l o g 记录日志 一个格式化字符串漏洞的表现形式如下 i n tf u n c ( c h a r * u s e r ) p r i n t f ( u s e r ) ; ) 正确的用法应该是 “在4 3 3 中我们实现了一个针对这种情况检查的算法 ”表中没有列函数等同的w i d ec h a r 处理函数 2 1 安全漏漏类型 i n tf u n c ( c h a r * u s e r ) p r i n t f ( ”z 8 ”,u s e r ) ) 1 5 关于如何在源码中检查格式化字符串漏洞,文献悯和【6 j 中有了比较完整 和实用的自动化检测方法。针对二进制文件中的格式化字符串检测,工 具 3 9 l 也做出了有益的尝试,但是在确定格式串是否由用户控制的问题中, 需要进行数据流回溯m ,由于静态分析中数据流技术的限制,仍然没有特别 精确的方法可以检测此类问题。 2 1 4 逻辑漏洞 这一节主要介绍各种非上述类型的安全漏洞,包括条件竞争f r a c ec o n d i t i o n ) ,函数重入,内存腐烂,解析错误等等安全问题。这些安全漏洞有一 个共同的特征就是都是由于软件的设计失误或者是程序员的编程失误,某 些操作的执行方式或者是执行顺序不正确引起的。我们将这类操作归类 为“逻辑漏洞”,之所以称之为“逻辑”,是因为引起这些漏洞的操作存 在逻辑错误。 1 条件竞争 文献f 2 对于r a c ec o n d i t i o n 有深入的分析,并对l i n u x 和u n i x 平台下如 何避免条件竞争做出了建议。w i n d o w s 上由于编程错误造成的r a c e c o n d i t o n 同样有例子【s 3 和。 对于l i n i x 和u n i x 下边的r o , c ec o n d i t i o n 检查一般通过对程序创建临时文 件的代码进行分析得到,而w i n d o w s 下的r a c ec o n d i t i o n - - 般是由于更 复杂的逻辑造成的,针对这种类型的漏洞很难做到自动化分析,只能 依赖于人工检查或者3 2 中描述的黑盒测试方法对程序进行类似的测 试。 虑 1 3 2 3 一节中专门讨论这个问题 “函数重入归根究底还是一个条件竞争问题,考虑到其特殊性,这里单独做为一类来考 1 5 第二章2 安全漏漏溉述 函数重入一个比较典型的安全类型就是u n i x 和l i n u x 系统中的信 号处理函数的重入问题,文献对于这个问题有很深入的讨沦。 与u n i x 和l i n u x r 串不同的是。w i n d o w s 中采取消息机制做为进程中或 者进程间的通讯机制,针对某一个消息都会有相应的处理,虽然目前 还没有出现类似的问题,但是消息处理函数的重入也是一个重点检查 的对象。 3 内存腐烂 内存腐烂中的大部分都是和堆相关的,正常的堆操作依赖于库函数中 的堆管理结构。一般来说内存腐烂的意思就是特定的堆操作的参数指 向一个非正常的堆管理结构,从雨引起安全问题。 这一类中比较典型的是d o u b l ef r e e ,即对同一个堆分配的地址进行了 两次f r e e - 由此造成的闻题可以导致攻击者以此来执行代码。同样类 似的问题还存在于程序逻辑没有处理好内存管理的代码,导致函数在 没有进行m a l l o c 或者n e w 操作就对一个内存地址进行f r e e ,同样地,也 可能导致代码执行或者程序崩溃。 4 解析错误 解析错误一般是针对文件路径中的特殊字符处理错误而引起的安全问 题。例如w e b s e r v e r 中一般需要对”_ ”进行检查,因为如果客户端提 交一个”一e t c p a s s w d ”的请求,如果没有对”i ”进行检查,那 么将突破w e b s e r v e r 的路径限制,访问到未授权的系统文件。此类错误 一般可以让攻击者访问w e b s e r v e r 上的未授权文件或者查看c g i 程序的 源代码等等。 这方面很多漏洞都集中在c g i 程序中,这里我们针对服务器端软件进 行描述。比较典型的漏洞有【l q 和。 文献f 1 日使用运行时监测方法来探测解析错误,根据不同请求生成的调 用图形来判断是否存在解析问题。其中使用的一些数据流检测方法很 值得借鉴。 5 设计错误 逻辑错误这一类都可一用设计错误来概括,但是这里所说的设计 错误并不是指上述这些。而是在结构或者机制设计上的失误导致 2 2 存在漏洞的程净 1 7 的安全问题。例女 1 w i n d o w s 操作系统中的s h a t t e r 2 1 i 攻击,是由 于w i n d o w s 操作系统在用户进程和特权进程之间的消息传递没有进行 权限验证,从而允许用户进程向特权进程发送特定的消息来执行命 令。因为这是在w i n d o w s 操作系统消息机制设计上的失误,所以我们 这里称之为设计错误。类似的还有文献1 2 目中描述的w i n d o w s 操作系统 中命名管道安全机制的缺陷。 逻辑漏洞一般很难使用自动化的方法进行检测,除了一些针对性特别强 的,例如内存腐烂中的d o u b l ef r e e 等等可以针对内存分配和释放相关的函数 进行检测和识别,其它类型的错误只能借助于人们的不断地理解系统提供 的安全机制或者手工分析程序来发现。 2 2 存在漏洞的程序 上一节中描述了各种类型的安全漏洞,但是并不意味着只要是一个计算 机程序存在着上述模式的问题就可以认为是安全漏洞。安全漏洞是用来进 行未授权访问或者权限提升的,所以只有特定类型的软件中存在上述模式 的问题,才可以认为是安全漏洞。 2 2 1 服务器软件 这里指的服务器软件是指提供i n t e r n e t 服务的软件,例直i l w e bs e r v e r ,f t p s e r v e r 等等,这些服务在网络上大部分都是可以匿名访问的。这样一个恶意 攻击者就可以利用服务器程序中间存在的漏洞,以服务器程序的安全上下 文执行命令。但是也有一部分服务是需要进行认证的,例如p o p 3 ,i m a p 等等 服务,需要用户提供一个合法的用户名和密码才能进行下一步的动作。而 有些漏洞只有通过合法的验证之后才能被触发。由此,针对服务器程序的 漏漏可以分为两类:p r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论