硕士学位论文COM组件栈缓冲区溢出漏洞检测技术研究.docx
《硕士学位论文COM组件栈缓冲区溢出漏洞检测技术研究.docx》由会员分享,可在线阅读,更多相关《硕士学位论文COM组件栈缓冲区溢出漏洞检测技术研究.docx(66页珍藏版)》请在冰豆网上搜索。
硕士学位论文COM组件栈缓冲区溢出漏洞检测技术研究
硕士学位论文
COM组件栈缓冲区溢出漏洞检测技术研究
ADissertationSubmittedtoHuazhongUniversityofScienceand
TechnologyfortheDegreeofMasterofEngineering
TheResearchonstackbufferoverflowdetectionofCOMcomponent
Candidate
:
ZhangChao
Major
:
ComputerSoftwareandTheory
Supervisor
:
Prof.LuYansheng
HuazhongUniversityofScienceandTechnology
Wuhan430074,P.R.C.
January,2007
独创性声明
本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的研究成果。
尽我所知,除文中已经标明引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写过的研究成果。
对本文的研究做出贡献的个人和集体,均已在文中以明确方式标明。
本人完全意识到,本声明的法律结果由本人承担。
学位论文作者签名:
日期:
年 月 日
学位论文版权使用授权书
本学位论文作者完全了解学校有关保留、使用学位论文的规定,即:
学校有权保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。
本人授权华中科技大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。
本论文属于
保密□,在_____年解密后适用本授权书。
不保密√。
(请在以上方框内打“√”)
学位论文作者签名:
指导教师签名:
日期:
年 月 日 日期:
年 月 日
摘要
为了解决软件复用,缩短软件开发时间,降低维护成本和实现程序动态升级,软件设计领域产生了组件化程序设计结构,并且日益成为发展趋势。
微软的COM组件对象模型是当今比较成熟的软件组件模型之一,被广泛应用于Windows操作系统和应用程序中。
随着COM组件技术的大量使用,COM组件暴露出越来越多的安全问题,其中,缓冲区溢出安全问题占了很大比例。
缓冲区溢出漏洞一直是安全漏洞最常见的一种形式。
缓冲区溢出问题主要出现在C/C++这类非类型安全语言中,而在新一代的编程语言,例如Java、C#中不存在。
一个重要的原因就是C/C++允许通过指针进行间接内存访问但没有缓冲区边界检查和提供了大量对缓冲区可能存在不安全操作的库函数,在Windows操作系统中也存在类似的函数。
因此,如果能采用有效的手段对COM组件的缓冲区溢出漏洞进行检测,将能极大地提高组件软件的安全性。
根据COM组件多数情况下源代码未可知的测试特点,基于COM组件的二进制代码实现对其可能存在的栈缓冲区溢出漏洞的检测。
检测方法是将检测缓冲区溢出问题转化为整数范围分析问题。
建立适用COM组件的危险函数库,在汇编代码中识别危险函数的调用位置,然后根据危险函数参数的类型通过扫描识别不同的缓冲区,将声明的缓冲区大小和使用的缓冲区大小等价为整数范围,依据制定的缓冲区溢出标准检测溢出漏洞。
根据COM组件使用虚表定位函数的结构特点,实现了COM组件中用户函数的精确定位;同时利用IDC脚本语言提取了COM组件中的函数依赖关系图。
基于以上工作,实现了一个COM组件栈缓冲区溢出漏洞检测原型系统。
关键词:
缓冲区溢出,静态分析,二进制代码,COM组件,危险函数
Abstract
Inordertosolvetheproblemofsoftwarereuse,shortensoftwaredevelopingperiod,reducemaintenancecostandrealizesoftwareautomaticupdating,componentsoftwaredesignisputforwardandhasbecomeaninevitabledevelopmentaltrend.Microsoft'sComponentObjectModel(COM)isarelativelymatureoneofsoftwarecomponentmodels,whichiswidelyusedinWindowsoperatingsystemandapplicationprograms.AlongwiththeprevalenceofCOM,moreandmoresecurityproblemsareexposed,ofwhichbufferoverflowconstitutesahighproportion.
Bufferoverflowhasbeenoneofthecommonestformsofsecurityholes.Itmainlyexistsinthenontype-safelanguages,suchasCandC++.However,newgenerationlanguages,suchasJavaandC#,donothavethisproblem.OneofthemostimportantreasonsisthatCallowindirectmemoryaccessbypointerwithoutboundarycheckandprovidemanyunsafefunctionswhichmaycausebufferoverflow.Meanwhile,therearesuchfunctionsinWindowsoperatingsystem.Therefore,ifeffectivemeanscanbeadoptedtodetectbufferoverflow,securityofcomponentsoftwarewillbegreatlyenhanced.
BufferoverflowdetectionbasedonbinarycodeisthoroughlystudiedinthisthesisbecauseinmostcasesthesourcecodeofCOMisunknown.Adetectionalgorithmisproposedbymodelingthebufferoverflowproblemandtransformittorangescomparisonofintegers.First,establishanunsafefunctionlibraryofCOManduseittodistinguishunsafefunctioncallsinassemblycode.Second,accordingtotypesofargumentspassedtounsafefunctions,differentbuffersaredistinguished.Third,obtainrangesofintegersbasedonthesizeofdeclaredbuffersandallocatedones.Last,usebufferoverflowdetectioncriterionmadebythisthesistodetectbufferoverflow.COMusesvirtualtabletolocatefunctions.Accordingtothisstructuralcharacteristics,thisthesisrealiseaccuratepositioningofuserfunctionsandextracttheirdependencerelationsbymeansofIDCscriptlanguage.Basedontheworkmentionedabove,aprototypesystemthatcandetchstackbufferoverflowofCOMisrealised.
Keywords:
bufferoverflow,staticanalysis,binarycode,COMcomponent,unsafefunction
目录
摘要I
AbstractII
1绪论
1.1课题背景
(1)
1.2国内外概况
(2)
1.3论文主要研究工作(4)
1.4论文结构(5)
2COM组件及栈缓冲区溢出漏洞检测方法基础
2.1COM组件(6)
2.2缓冲区溢出原理(8)
2.3栈缓冲区溢出检测技术(11)
2.4小结(19)
3COM组件栈缓冲区溢出漏洞检测技术
3.1函数的识别(21)
3.2参数的识别(25)
3.3函数的返回值(25)
3.4变量的识别(27)
3.5COM组件危险函数库建立(30)
3.6小结(34)
4COM组件栈缓冲区溢出漏洞检测系统设计与实现
4.1模块结构和功能(35)
4.2主要数据结构(36)
4.3函数定位模块实现(37)
4.4栈溢出静态分析模块实现(38)
4.5结果输出模块实现(47)
4.6与CSTS的接口(49)
4.7小结(50)
5实验与测试
5.1实验目的(51)
5.2实验环境(51)
5.3测试用例(52)
5.4测试结果(53)
6总结与展望
6.1工作总结(59)
6.2工作展望(60)
致谢(61)
参考文献(62)
附录攻读学位期间参与的科研项目(67)
1绪论
1.1课题背景
继面向对象的软件设计方法之后,基于组件的软件设计方法正在逐渐成为新的趋势[1]。
按照组件化程序设计的思想,复杂的应用程序被设计成一些小的、功能单一的组件模块,这些模块可以运行在同一机器上,也可以运行在不同的机器上,每台机器的运行环境可以不同,甚至可以是不同的操作系统。
为了实现这样的应用软件,组件需要一些细致的规范,只有组件程序遵守这些共同的规范,组件软件才能正常运行。
目前流行的组件规范有三种,它们是OMG(ObjectManagementGroup)提出的CORBA(CommonObjectRequestBreakerArchitecture);微软提出的COM(ComponentObjectModel);还有SUN公司提出的EJB(EnterpriseJavaBean)。
Cai[2]给出了三种规范的详细比较。
微软的COM组件对象模型是当今比较成熟的软件组件规范之一,被广泛应用于Windows操作系统和应用程序中。
在分布式计算、Internet网络、三层体系结构开发以及音视频处理等前沿领域,COM组件技术正在被大量使用。
COM组件在受到广泛应用的同时,自身的安全问题也日益暴露。
其中,缓冲区溢出安全问题占了很大的比例。
在安全日益被人们所关注的今天,缓冲区溢出毫无疑问是最大的安全威胁之一。
1988年,Internet上的第一例蠕虫(Morris)攻击,就是利用Vax和Sun机器fingerd中的缓冲区溢出漏洞。
SANS评选出的2005年威胁最大的20个漏洞中,有8个跟缓冲区溢出有关。
国内绿盟科技根据安全漏洞的严重程度、影响范围等因素综合评出2006年度的十大安全漏洞,缓冲区溢出漏洞占4个。
绿盟科技在2006年发布CVE漏洞8个,而缓冲区溢出漏洞就占了5个。
根据CERT的统计数据,近几年与缓冲区溢出有关的安全事件在50%以上。
经过十几年的发展,缓冲区溢出已经成为一种成熟和最有效的黑客攻击手段。
并且在接下来的许多年里,情况仍然会是这样。
随着COM组件的广泛应用,COM组件中暴露的缓冲区溢出的安全问题的数量也是逐年上升。
因此检测COM组件的缓冲区溢出漏洞具有十分重要的意义。
COM组件多数情况下源代码不可知,目前常用的测试方法是黑盒测试。
按照经验和一般规律设计大量测试用例,以期望触发组件的漏洞和异常。
这种方法在某些时候会起到较好的效果,但效率太低,而且对测试人员的经验和技术水平要求很高。
为了改进已有的COM组件测试方法,提高对COM组件安全漏洞的检测,本论文研究并实现了COM组件栈缓冲区溢出漏洞检测原型系统。
同时,对COM组件进行静态分析获取其结构信息和安全漏洞信息是实验室正在研发的针对COM组件的安全漏洞自动检测工具的需要。
所以本论文研发的原型系统可以很好与实验室研发的自动检测工具结合,以完善该工具的效率和功能。
1.2国内外概况
软构件技术提供了一种较面向对象方法更为有效的软件设计模式,构件软件被广泛应用并成为一种主流软件形态[3](本段及后两段中的“构件”与论文中的“组件”概念一样,只是翻译的不同)。
然而,构件的内部信息屏蔽、演变速度快以及构件间的异质、松耦合等特点给构件及构件软件的测试工作带来一系列的问题[4,5]:
对于构件提供者,问题在于需要使用相当充分的覆盖准则进行测试以提高构件的可复用性;对用户使用构件的上下文环境并不完全了解;并且不能很好的获得构件的错误报告。
对于构件使用者而言,问题在于源代码不可见性给测试设计和用例生成带来了极大的障碍[6];系统中构件的异质性不利于测试标准的统一及自动化的实现;构件版本更新快以及不确定性迫使要对构件系统进行较为频繁的回归测试等。
构件软件测试通常分为构件测试、子系统测试、系统测试三个阶段[7],分别与传统软件测试过程的单元测试、集成测试和系统测试相对应。
Harrold[8]认为应该从构件开发者和构件使用者两个不同的角度来看待构件软件的测试问题。
一般来讲,构件测试主要由构件的开发者完成,而后两个阶段的测试则由使用者实施。
总之,根据构件自身的特点,寻求高效的构件软件测试技术和开发实用的测试工具是当今软件业界一个亟待解决的问题。
相对于构件测试的研究,针对缓冲区溢出攻击的研究比较成熟。
缓冲区溢出攻击可追溯到1988年臭名昭著的Morris蠕虫,在随后的1989年里,Spafford提交了一份关于运行在VAX机上的BSD版UNIX的fingerd的缓冲区溢出程序的技术细节的分析报告,这引起了一部分安全人士对这个研究领域的重视。
但真正让众人认识缓冲区溢出攻击的论文是1996年11月AlephOne在Phrack杂志第49期发表的论文“Smashingthestackforfunandprofit”[9]。
该论文阐述了Linux系统中栈的结构和如何利用栈缓冲区溢出,并首次提出shellcode的概念。
1999年,IIS4.0远程攻击代码的作者darkspyritAKABarnabyJack[10]在PhrackMagzine(第55期)上提出了使用系统核心DLL中的“jmpesp”的指令来完成到shellcode跳转的想法,从此开创了Win32平台下缓冲区溢出的新思想,大量Windows平台下的缓冲区溢出漏洞也被利用。
在缓冲区溢出漏洞挖掘和检测方面,国外已经有一些较为深入的研究工作,并且这些技术都能应用到在Win32平台下开发的软件中,而国内的研究还处于初级阶段。
通过对目前国内外相关研究文献的搜集整理,按照各种技术的研究对象的不同,可将缓冲区溢出漏洞检测的研究工作进行如下分类[11,12,13]:
1、基于源代码的静态检测技术:
将源代码作为输入,通过建立漏洞库,扫描源代码,匹配漏洞模式来检测缓冲区溢出漏洞。
目前关于此方面的研究较多,典型的工具有ITS4[14]、BOON[15]、Splint[16,17]、ARCHER[18]等。
2、基于源代码的动态检测技术:
可通过扩展编译器功能和直接修改源代码来完成溢出漏洞的检测,如StackGuard[19,20]和STOBO[21]等工具。
3、基于二进制代码的动态检测技术:
通过静态或动态修改二进制代码和采用“黑盒测试”的方法实现栈溢出漏洞检测,如RAD[22]、libverify[23]和Fuzz[24]等工具。
4、基于二进制代码的静态检测技术:
该技术的研究目前比较少见,目前典型的研究是通过一些反汇编工具对目标代码进行处理,然后再依赖一些源代码静态检测技术进行处理[25,26,27],如TerryEruceCillette[28]、bugscam[29,30]等工具。
漏洞检测方法各有利弊,需要根据具体情况选择相应的方法来确保最大程度上挖掘出缓冲区溢出漏洞。
在上述的研究工作中,基于二进制代码的静态检测技术对于针对COM组件的缓冲区溢出检测具有指导意义。
论文中的检测技术就是归属于基于二进制代码的静态检测技术的。
1.3论文主要研究工作
论文的主要工作为:
在研究已有缓冲区溢出检测技术,分析现存成熟的缓冲区溢出检测工具,研究C/C++程序的逆向技术以及参加实验室的针对COM组件的安全漏洞自动化检测工具的开发的基础上,设计了一种针对COM组件二进制代码的栈缓冲区溢出漏洞检测算法SBOD-BC-CC(stackbufferoverflowdetectionbasedonbinarycodeofCOMcomponent),并最终实现一个COM组件栈缓冲区溢出检测原型系统。
具体工作包括:
1、现有的栈缓冲区溢出检测技术的总结
对现有的栈缓冲区溢出检测技术进行了深入的研究,将溢出检测技术分为四大类:
基于源码的静态检测、基于源码的动态检测、基于二进制代码的静态检测和基于二进制代码的动态检测。
详细分析了这四类技术并介绍了各自的代表自动化工具。
在分析现有检测技术的基础上,提出论文研究的检测技术。
2、C/C++程序的逆向技术研究
熟悉反汇编工具IDA、OllyICE和Win32dsm,熟练掌握IDC脚本语言。
研究在汇编代码中识别程序流程,识别函数(库函数和用户编写的函数),识别函数的参数,识别函数的变量等技术,在研究识别库函数的过程中提出了一个切实可行的算法。
3、函数定位模块的实现
为了减少扫描汇编代码得到的无用信息,提高检测效率。
根据COM组件结构特点,设计了一种自动识别接口函数的算法,并实现了一个函数定位模块,可以将COM组件中用户函数名和该函数在汇编代码中的线性地址实现精确定位。
4、COM组件危险函数库的建立
栈缓冲区溢出通常发生在字符串操作函数中,对于一般的C/C++程序,使用的是C字符串,所以危险函数库主要是由常规字符串操作函数(如strcpy、strcat等)的子集构成。
但COM组件中使用的是混合字符串。
常规的字符串操作函数无法处理该类型字符串。
因此必须建立适用COM组件的危险函数库。
5、栈溢出检测算法的实现
在详细分析bugscam的基础上,对其两大核心函数SHeapBuffSize和函数StckBuffSize做了改进。
利用IDA的脚本语言IDC实现了一个完整的栈溢出检测算法SBOD-BC-CC。
该算法可以根据危险函数的参数类型,识别不同的赋值操作指令,从而较准确的得到参数代表的缓冲区的分配长度和使用长度。
依据缓冲区溢出的标准,判断栈溢出漏洞。
同时通过识别函数调用的操作指令,并结合函数定位模块,可以提取用户函数的依赖关系,以XML格式输出的函数依赖关系为COM组件的后续分析提供良好的输入信息。
1.4论文结构
第一章为绪论,主要介绍论文研究内容的一些背景情况,国内外研究现状和论文的主要内容。
第二章首先介绍了COM组件,然后对缓冲区溢出的机理做了分析。
重点介绍了栈缓冲区溢出的原因和分类,同时比较分析了现有的栈缓冲区溢出检测技术和工具。
第三章重点介绍静态分析的理论基础,研究如何从二进制代码中识别高级语言的关键结构。
介绍了在汇编代码中识别函数,识别函数参数,识别函数返回值以及识别函数变量的技术。
同时讨论了COM组件危险函数库的建立。
第四章详细介绍COM组件的栈缓冲区溢出漏洞检测系统的设计与实现。
第五章介绍对实现的原型系统进行的测试与分析。
第六章是对本文工作的总结和展望。
2COM组件及栈缓冲区溢出漏洞检测方法基础
COM组件在受到广泛应用的同时,自身的安全问题也日益暴露。
其中,缓冲区溢出安全问题占了很大的比例。
为了提高组件软件的健壮性,针对COM组件缓冲区溢出漏洞检测方法的研究具有十分重要的意义。
本章首先简单介绍了COM组件,然后详细介绍了缓冲区溢出原理和目前成熟的检测方法及工具。
2.1COM组件
COM组件是符合COM规范编写的组件。
COM是由Microsoft提出的组件标准,不仅提供了组件之间的接口标准,还引入了面向对象的思想。
在COM标准中,对象是某个类的实例,称为COM对象。
接口是一组方法的集合,其方法也称为接口成员函数。
COM组件为COM对象提供活动空间,COM对象以COM接口方式提供服务。
COM组件、COM对象和COM接口三者之间的关系如图2.1所示[31]。
图2.1COM组件、COM对象和COM接口关系
COM组件有两种,一是进程内组件,是一个DLL(动态链接库)文件;二是进程外组件,是一个EXE(可执行程序)文件。
当组件的客户程序调用组件的功能时,首先创建一个COM对象,然后通过该对象实现的COM接口调用所提供的服务。
当所有的服务结束后,如果客户程序不再使用该COM对象,那么应该释放掉COM对象所占有的资源,包括对象本身。
组件的内部实现对客户程序是完全隐藏的。
2.1.1COM对象
COM提供的是面向对象的组件模型,COM组件提供给客户的是以对象形式封装的实体。
客户程序与COM组件通过COM对象交互。
COM规范采用了128位全局唯一标识符GUID来标识COM对象。
与C++对象相比两点不同:
1、COM对象的数据成员的封装以组件模块为最终边界,对于对象用户是完全透明的;而C++对象的封装特性相比之较差,可能对于用户是可见的。
2、COM对象的可重用性通过COM对象的包容和聚合来实现;而C++对象的可重用性是通过继承机制实现的。
2.1.2COM接口
1、接口的定义
接口是一组逻辑上相关的函数集合。
COM对象通过接口成员函数对外提供服务。
接口的传统命名前缀为I。
COM模型中,客户程序通过接口获得对象的服务。
每个接口由一个128位的全局唯一标识符IID来标识,客户通过IID获得接口的指针,再通过接口指针调用相应的接口成员函数。
COM规范使用IDL(接口描述语言)来定义COM接口。
MicrosoftVisualC++提供了MIDL工具,可以把IDL接口描述文件编译成C/C++兼容的接口描述头文件(.h),该文件可以被组件程序和客户程序所使用。
2、接口的内存结构
客户程序用一个指向接口的指针来调用接口方法,接口指针又指向另一个指针(pVtable),pVtable指向接口函数表(vtable),接口函数表的每一项为4个