!""#$!"计算机工程与应用
程序代码编写错误是软件安全漏洞产生的重要原因之一。而程序设计语言本身所固有的特性,如%&%’’中对数组、指针无自动的边界检查,使得许多错误无法在编译阶段被发现;同时随着程序规模的扩大,状态空间急剧增大,导致很多安全漏洞在程序动态测试阶段很难被发现。这其中以缓冲区溢出问题最为突出()*。为解决此问题,
前人做了大量工作,包括基于词法分析的漏洞检测工具+,-#(!*、基于携带验证代码技术的检测方法(.*以及基于代码转换策略的检测方法(#*等。
文章分析了%/%’’源代码中缓冲区溢出漏洞的特性,归纳其共性,从而提出了%/%’’缓冲区溢出的安全模式。它既可以结合程序分析技术进行代码自动检测,也可以指导程序员编写安全的代码。
)缓冲区溢出
%/%’’语言应用广泛的一个重要原因就是其操作的灵活
性,但这种灵活性同时也带来了一些缺陷。如使用广泛的字符串拷贝函数012345
(),其函数原型为:36728012345(367280129:01,3;<0136728012-23)
;功能是“将012-23所指向的字符拷贝到0129:01中去,
返回0129:01”
。假设012-23所指向的字符串长度大于0129:01所指向字符串的长度,而又对其不加判断的操作,则01290:1所指向的存储空间不但会被完全覆盖,还将产生“溢出”。
图)给出了两个典型的例子。图)
(7)中,主程序调用函数4
(),函数4()通过字符串拷贝函数将传进来的字符串7不加判断的拷贝给字符数组=;
图)(=)中,对字符串0的访问不进行任何边界检查。假设0中没有空格,则循环的结束点将超出0的范围,继而操作“80>"”也将发生在未知的程序点上。
图
)
图!中给出了另外两个例子。图!(7)的原意是构造一个
整型数组,并输出此数组。实际却是输出结果错误,输出的并不是所要求的内容。原因是由于在第一个?;2循环结束后,4指到了数组的尾部,而在第二个?;2循环之前没有使之重新返回数组起始,所以输出的是数组范围之后存储单元的内容,这样不但得不到正确结果,还会读取非法的内存空间,造成安全问题;图!
(=)的初衷是输出!"的阶乘,但实际是输出了错误的结果:@!)"!).!A.B 。原因是由于计算结果超出了整型数所能存储的范围,造成溢出,得到不正确的结果。实际计算时应该对结果进行检验,及时发现错误。
从例子可以看出,不加检查的向缓冲区内填充大于其容量的数据,会覆盖掉其它数据。若填充的数据足够长,甚至会覆盖掉函数的返回地址。这将会导致程序产生许多不可预料的行
!"!##源程序缓冲区溢出漏洞的静态检测
杨小龙
刘
坚
(西安电子科技大学软件工程研究所,西安A)""A))
C@D7EF :D55GFH:5;I$3;D
摘
要
讨论了%/%’’源程序中缓冲区溢出的常见表现;分析了其特性以及产生机理;提出了在源代码的J-,上附加
安全属性进行漏洞静态检测的方法;讨论了该方法的实现过程。关键词
缓冲区溢出
整数值域判断
静态检测
J-,
文章编号)""!@K..)@(!""#)!"@")"K@".文献标识码J
中图分类号,L.)#
$%&%’(&))*+,%,(%’-./’0,)*1233,456,43)7892)-,4&:’)’%’,;
’-!"!##<47.4&=
>&-.?’&7)7-./’2@’&-(-;?1M72:C A:;%4&(%:,6:?7DEFE722:42:0:<171E;<;?=I??:2;R:2?F;M RIF<:27=EFE1E:0E042;4;0:P$J 7<7F50E01;16:RIF<:27=EFE1E:0S3672T 731:2E01E307 0171E37FF5P:1:31E 基金项目:国家部委预研基金资助 作者简介:杨小龙()VAV@),男,硕士研究生,主要研究方向:软件安全模式、编译器构造。刘坚()VW#@),女,教授,主要研究方向:软件开发环境、编 译器构造等。 )"K 万方数据