一种静态检测缓冲区溢出的方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int someFunction(char * s) { char desBuf[20];
… strcpy(desBuf, s); …
基金项目:武器装备预研基金资助项目 作者简介:于志鹏(1976—),男,硕士生,主研方向:软件安全模式, 编译器构造;刘 坚,教授 收稿日期:2004-09-29 E-mail:zhpyu@mail.xidian.edu.cn
其参数进行长度检查或者用其它函数进行适当的替代,但是
很多的程序员并没有做到这些。可以使用静态分析的方法对
此类函数的调用参数进行分析、比较,并根据函数的语义进
行判断,如有缓冲区溢出情况则进行报告。
首先,为字符型指针变量和数组变量定义综合属性 alloc
和 len,分别表示分配的缓冲区大小和缓冲区中当前已经使用
计算机在各行业已经得到广泛应用,其相关知识也日益 普及,随之而来的安全问题更加引起人们的关注。尤其是在 当今网络时代,网络安全更是一个热门的课题,而缓冲区溢 出是其中的一个相当普遍而且后果严重的安全漏洞。
1 缓冲区溢出的概念和危害
计算机程序在进行数据操作时总要进行缓冲区的读写, 而其大小都是在读写之前由程序确定的。理想情况是,程序 检查数据长度并且不允许输入超过缓冲区长度的字符串。但 是绝大多数程序都会假设数据长度总是与所分配的存储空间 相匹配,这就为缓冲区溢出埋下隐患。缓冲区溢出是指当程 序向缓冲区内填充的数据位数超过了缓冲区本身的容量,溢 出的数据覆盖在合法数据上。当一个超长的数据进入缓冲区 时,超出部分就会被写入其他缓冲区,其他缓冲区存放的可 能是数据、下一条指令的指针,或者是其他程序的输出内容, 这些内容都被覆盖或者破坏掉。可见一小部分数据或者一条 指令的溢出就可能导致一个程序或者操作系统崩溃。
基于以上原因,缓冲区溢出一直是黑客攻击的重要手段, 也是病毒编写者和木马编写者经常使用的一种攻击方法。攻 击者或者病毒善于在系统当中发现容易产生缓冲区溢出之 处,运行特别程序,获得优先级,指示计算机破坏文件,改 变数据,泄露敏感信息,产生后门访问点,感染或者攻击其 它计算机。其中一个典型例子就是 2003 年的 W32. slammer. Worm 蠕虫。slammer 是针对 Microsoft SQL Server 2000 和 Microsoft Desktop Engine(MSDE)2000 的一种蠕虫。该蠕虫利 用 MS-SQL 的一个漏洞产生缓冲区溢出进行传播。由于蠕虫 发送大量的 udp 数据包,因此会造成网络攻击。
char *strcpy (char * des,const char * src);
功能是“将 src 所指向的字符拷贝到 des 中去,返回 des”。 假设 src 所指向的字符串长度大于 des 所指向字符串的长
度,而又不对其进行判断的操作,则 des 所指向的存储空间 不但会被完全覆盖,还将产生“溢出”。例如:
3 检测方法的具体实现
3.1 安全漏洞的抽象和形式化描述 在 C/C++程序产生缓冲区溢出的漏洞中,很多情况是由
几个高源自文库险函数的不当使用造成的,其中主要有 fets、fread、
gets、memcpy、memmove、memset、sprintf、strcat、strncat、
strcpy、strncpy、vsprintf 等。在调用其中某些函数时应该对
这里使用了安全模式的概念,是指在对安全漏洞进行归 纳总结后,根据一类漏洞的特点,采取相应的方式对其进行 形式化描述。例如,对于语法问题,可以采用文法产生式的 方式描述;对于静态语义问题,可以采用语义属性的方式描 述;对于动态语义问题,可以采用指称语义方式描述等。形 式化的描述方式一般是描述一类问题,而具体的问题,如对 于数组越界问题,可以使用记录数组总的空间和已经使用的 空间这两个属性来描述;对于字符串拷贝引起的缓冲区溢出 问题,可以借助指针(数组)所指向空间的总长度和使用长度 属性以及相应操作的语义进行描述。
因此,对于防止利用缓冲区漏洞进行攻击的最根本的手 段是保证程序的健壮性,尽可能减少漏洞,从而可以在很大 程度上解决问题。由此,我们通过对程序源代码进行分析, 找出可能的漏洞,再将漏洞的特性及修改建议报告出来供程 序员参考,以进行程序的修改和完善。
所谓安全漏洞,是指源程序中可能造成安全性故障的元 素,即安全隐患的各种程序表现。C/C++语言应用广泛的一 个重要原因就是其操作的灵活性,但这种灵活性同时也带来 了一些缺陷。如使用广泛的字符串拷贝函数 strcpy(),其函数 原型为:
(西安电子科技大学软件工程研究所,西安 710071)
摘 要:网络安全日益引起人们的重视,而利用缓冲区溢出进行攻击是黑客和病毒较为常用的手段。如果程序员能够采取足够的重视并且 写出安全性较高的代码将大大降低被攻击的危险。该文介绍了一种针对 C/C++源程序的静态分析方法,给程序编写者和修改者提供一定的 漏洞提示。 关键词:网络安全;缓冲区溢出;安全模式;属性
A Method of Statically Detecting Buffer Overflow
YU Zhipeng, LIU Jian
(Software Engineering Institute, Xidian University, Xi’an 710071)
【Abstract】Network security has been paid more attention to and hackers often take advantage of buffer overflow to attack other systems or spread virus. Safe code will decrease the risk if programmers focus on the question strictly. A method to statically detecting likely buffer overflow vulnerabilities is introduced and it may help programmers to improve the security of software. 【Key words】Network security; Buffer overflow; Safety pattern; Attributes
Evans 等人开发的 Splint 是个检测 C 程序中安全漏洞的 静态分析工具,采用的是向源程序中添加约束信息的方法, 即向程序中的相关元素处加入用指定标记形成的注释。然后 对修改后的源程序进行词法、语法和轻度的语义安全分析, 判定程序中可能的不安全因素,给出相应信息。Splint 目前 也只是针对单进程程序,还没有涉及到多进程和分布式程序。 Splint 最大的局限性在于,需要分析人员对所要分析的程序 有足够的了解,手工对关心的变量和函数加入注释,所以只 对分析人员所关注的部分进行分析,并且对使用者的要求也 较高。Purify 是另一个内存错误检测工具,是一个动态检测 工具,通过用 Purify 连接工具连接,可执行代码在执行的时 候数组的所有引用来保证其合法性,这将带来性能上的损失。
第 31 卷 第 19 期 Vol.31 № 19
计算机工程 Computer Engineering
·软件技术与数据库·
文章编号:1000—3428(2005)19—0096—03 文献标识码:A
一种静态检测缓冲区溢出的方法
2005 年 10 月 October 2005
中图分类号:TP309
于志鹏,刘 坚
then begin
variable.alloc := array_size.vlaue;
variable.len := 0;
-综合属性的计算
ptr_list_append(variable);
-存储指针变量及属性
end;
else if variable.type = integer_type
then begin
variable.value := 0;
var_list_append(variable);
-存储整形变量及值
end;
}
| variable = expression;
-变量声明语句语法
{
if variable.type = pointer_char_type
or variable.type = array_char_type
溢出的情况,同时要注意函数的副作用,既是否改变了参数
的两个综合属性。
下面以字符串拷贝函数 strcpy 为例,对描述该漏洞分析
过程的关键产生式予以介绍。
(1) 分析变量声明语句时取得字符型指针变量和数组变
量定义综合属性 alloc 和 len,相应产生式为:
var_decl_expr → variable;
2 缓冲区溢出的描述和检测的基本思想
2.1 安全漏洞的描述 缓冲区溢出主要是一个 C/C++问题。尽管在通常情况下
—96—
它很容易修补,但它仍然会威胁代码的安全性。目前防止缓 冲区溢出问题的主要方法除了从程序员角度提高编程要求 (编写正确的代码、加强程序的健壮性)以外,还有诸如对程 序的数据段地址空间不可执行、规定堆栈增长方向由低向高 等。其中前者必然降低程序的功能和性能,后者又没有解决 利用堆和静态数据段的缓冲区进行溢出的攻击问题。
-变量声明语句语法
{
if variable.type = pointer_char_type
then begin
variable.alloc := 0;
variable.len := 0;
-综合属性的计算
ptr_list_append(variable);
-存储指针变量及属性
end;
else if variable.type = array_char_type
return 0; }
上面程序中的函数 someFunction 并未对拷贝的源、目标 字符串的长度进行比较,因此存在一种安全漏洞。由于大多 的编译器,内存空间分配的方向是自高向低的,因此该程序 执行时,如果源字符串 s 的长度大于目标串 desBuf 的长度 20, 拷贝将发生缓冲区溢出,很有可能改变函数 someFunction 的 返回地址。 2.2 安全漏洞检测的基本思想
的字符串长度。二者均在解析变量声明语句时进行初始化,
并在变量的赋值语句或者另外一些可以改变变量的上述两个
属性值的函数调用中进行属性的更新。然后在分析到上述字
符串操作的函数调用表达式时,根据具体函数的语义,比较
参数的相关属性 alloc、len,得出是否有缓冲区溢出的漏洞。
其中值得注意的是在调用一些函数时既要检测是否有缓冲区
通过对问题的分析和前人工作的成果的研究、比较,考 虑以上工具的优缺点,我们的检测方法的主要思想是首先对 应语言的各种特性,在各种编译环境中(主要是 VC6.0 及 GCC3.1)进行系统全面的例程测试,总结安全漏洞,将要解 决的漏洞进行汇总,按类别进行抽象和形式化描述,在这一 方面,上一级的同学已经做了许多工作,对 C/C++语言的安 全漏洞进行了较为全面的分析和总结。本文以此为基础,在 具体的程序分析过程中将某一类漏洞的形式化描述进行具体 实现,检测该漏洞,报告结果。
为了解决诸如缓冲区溢出的问题,前人已经做了大量的 工作并且开发了各种检测工具。主要有基于词法分析的漏洞 检测方法、基于约束分析的检测方法和基于运行时数组边界 检查的检测方法。
基于词法分析最简单直接的方法是 Unix 中的工具 grep, 用它可以按字符匹配的方式查找不安全库函数的调用。Viega 等 人 开 发 的 词 法 分 析 工 具 ITS4(It's the Software Stupid! Security Scanner),就是通过扫描 C 和 C++源代码中的危险函 数调用,与漏洞数据库中的漏洞进行匹配来确定安全问题的。 另外还有 RATS(Rough Auditing Tool for Security),是与 ITS4 类似的工具。这些方法既快捷又简单,但不涉及程序的语法 和语义,所以其分析能力有限,对语法或语义问题无能为力。
相关文档
最新文档