




已阅读5页,还剩57页未读, 继续免费阅读
(计算机软件与理论专业论文)c语言安全编译器研究.pdf.pdf 免费下载
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
电子科技大学硕士学位论文c 语言安全编译器研究 摘要 随着计算机的应用越来越广泛以及互联网的不断扩大,信息安全也越来越重 要。互联网众多的系统面临着越来越多的安全挑战,其最大的挑战源于缓冲溢出 攻击,而此类攻击的主要形式就是堆栈溢出攻击。 缓冲溢出攻击原因在于c c + + 程序缺乏相应的安全机制和程序的漏洞。堆栈 溢出在缓冲溢出中相对出现的较多,而且堆栈溢出攻击程序也比较容易实现,所 以尤其需要要重点关注。堆栈溢出利用程序中边界条件检查的不严谨,在修改某 个堆栈上的局部变量的过程中,同时完成注入攻击代码和更改程序运行流程的任 务。缓冲溢出攻击可能得到远程访问的系统管理员权限,在众多攻击方式中尤为 危险。 目前已有众多的方法用来防御堆栈溢出攻击,大致从程序编译角度,操作系 统内核,c p u 体系结构等方面着手。影响较大的如s t a c k g u a r d ,通过在堆栈中放 置c a n a r y 来检测堆栈是否被溢出;如s t a c k s h i e l d 通过保存堆栈中的返回地址 保证程序流程正确:如1 i b s a f e 通过提供安全的库替换标准的不安全的库; s o l o a r i s 和l i n u x 使用的不可执行堆栈;等等。这些方式方法,为后续的研究 开拓了思路。 我们的方案试图从编译角度着手,使用了开源软件g c c 作为试验起点。所以 简要介绍了g c c 的前端的内容。g c c 前端目的是根据源代码生成a s t 语法分析树, 再根据a s t 树,生成r t l 中间表示。最后把r t l 中间表示交给g c c 后端进一步处 理。 最后,作为本文的最终目的,我们提出了两种分离数据和控制的堆栈程序运 行时环境。并进一步分析了这种结构的安全性,兼容性等问题。最后,简要说明 了g c c 中如何修改并实现这样的分离堆栈的程序运行时环境。 关键词:c 语言,缓冲区溢出,堆栈溢出,g c c ,r t l 电子科技大学硕士学位论文c 语言安全编译器研究 a b s t r a c t a sc o m p u t e ra n di n t e r n e th a v eb e e nw i d e l yu s e d ,t h es y s t e ms e c u r i t y b e c o m e sm o r ea n dm o r ei m p o r t a n t o ni n t e r n e tm o r ea n dm o r es y s t e m sf a c e t h eb i gc h a l l e n g eo fs e c u r i t y ,m o s to fw h i c hc o m ef r o mt h ea t t a c k so f b u f f e ro v e r f l o w s ,a n dt h em o s tp o p u l a rw a y st oa t t a c kt h es y s t e ma r e t h r o u g hs t a c ko rh e a po v e r f l o w s t h el a c ko fc c + + p r o g r a ms e c u r i t yo rp r o g r a m m e z 7sc a r ei st h er e a s o n o fb u f f e ro v e r f l o wa t t a c k s s i n c et h es t a c ko v e r f l o w sa t t a c kc a ne a s i l y b ep e r f o r m e da n db ev e r yp o p u l a ri nb u f f e ro v e r f l o wa t t a c k , w es h o u l d p a yc l o s ea t t e n t i o no ni t t h i sk i n do fa t t a c k si sg e n e r a l l ya c h i e v e db y t h ec a r e l e s s n e s so fb o r d e rc o n d i t i o nc h e c kt h r o u g hm o d i f y i n gt h ep r o c e s s o fl o c a lv a r i a b l e si ns t a c kt oi n j e c ta t t a c kc o d e sa n dt h u sc h a n g et h e o p e r a t i o np r o c e d u r eo fp r o g r a m i t i st h em o s td a n g e r o u sa t t a c kj u s t b e c a u s eo ft h ep o s s i b i l i t yo fo b t a i n s t h ea u t h o r i t yo fr e m o t es y s t e m a d m i n is t r a t o r s i nr e c e n t ,t h e r ea r em a n ym e t h o d st op r e v e n ts t a c ko v e r f l o wa t t a c k s r o u g h l yb yp r o g r a mc o m p i l e ,o sc o r e ,s t r u c t u r e o fc p ue t c af e wo ft h e m h a v et h eg r e a ti m p a c t , s u c ha ss t a c k g u a r dw h ic hp u tc a n a r yt od e t e c tt h e s t a c ko v e r f l o w :s t a c k s h i e l dw h i c hs a v et h er e t u r na d d r e s st og u a r a n t e e t h ec o r r e c to p e r a t i o np r o c e d u r e :l i b s a f ew h i c hr e p l a c et h ei n s e c u r i t y l i b r a r yb y t h es e c u r i t yo n e :s o l o a r i sa n dl i n u xw h i c hp r o v i d et h en o t e x e c u t a b l es t a c ka n ds oo n t h e yo p e nu pt h el a t e rt h i n k i n g w ew i l lt r yt os o l v et h ep r o b l e mt h r o u g hc o m p i l i n go p e ns o f t w a r eg c c f i s t ,w es i m p l yi n t r o d u c et h ef r o n tc o n t e n to fg c c t h ea s tp a r s i n gt r e e w i hb eb u i l tt h r o u g hs o u r c ec o d e ,a n dt h e nt h er t lw i l lb eg e n e r a t e d f i n a l l y ,t h er t lw i l lb e h a n d e dt ot h eb a c ke n d l a s t ,w ep r o v i d et w ok i n d so fs e p a r a t i n gd a t aa n dc o d es t a c kp r o g r a m r u n t i m ee n v i r o n m e n t s f u r t h e r m o r e , w ew i l l a n a l y z e t h es e c u r i t ya n d c o m p a t i b i l i t yo ft h i ss t r u c t u r e a n db r i e f l yi n t r o d u c eh o wt or e a l i z et h e s e p a r a t i n gs t a c kp r o g r a mr u n t i m ee n v i r o n m e n t i ng c c k e y w o r d s :c l a n g u a g e , b u r ro v e r f l o w ,s t a c ko v e r f l o w ,g c c ,r t l i l 独创性声明 本人声明所呈交的学位论文是本人在导师指导下进行的研究工 作及取得的研究成果。据我所知,除了文中特别加以标注和致谢的地 方外,论文中不包含其他人已经发表或撰写过的研究成果,也不包含 为获得电子科技大学或其它教育机构的学位或证书而使用过的材料。 与我一同工作的同志对本研究所做的任何贡献均已在论文中作了明 确的说明并表示谢意。 签名:日期:年月日 关于论文使用授权的说明 本学位论文作者完全了解电子科技大学有关保留、使用学位论文 的规定,有权保留并向国家有关部门或机构送交论文的复印件和磁 盘,允许论文被查阅和借阅。本人授权电子科技大学可以将学位论文 的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或 扫描等复制手段保存、汇编学位论文。 ( 保密的学位论文在解密后应遵守此规定) 签名:导师签名:磁 日期:年月日 电子科技大学硕士学位论文c 语言安全编译器研究 1 1 概述 第一章绪论 1 1 1 缓冲区溢出和堆栈溢出攻击 缓冲区溢出是病毒编写者和特洛伊木马编写者偏爱使用的一种攻击方法。攻 击者或者病毒善于在系统当中发现容易产生缓冲区溢出之处,运行特别程序,获 得优先级,指示计算机破坏文件,改变数据,泄露敏感信息,产生后门访问点, 感染或者攻击其他计算机。 缓冲区溢出攻击利用了目标程序的缓冲区溢出漏洞,通过操作目标程序堆栈 并暴力改写其返回地址,从而获得目标控制权。它的原理是:向一个有限空间的 缓冲区中拷贝过长的字符串,这带来两种后果,一是过长的字符串覆盖了相邻的 存储单元而造成程序瘫痪,甚至造成当机、系统或进程重启等;二是可让攻击者 运行恶意代码,执行任意指令,甚至获得超级权限等。 事实上,在网络空间中利用这种缓冲区溢出漏洞而发起的攻击屡见不鲜。 1 9 8 8 年1 1 月,许多组织不得不因为“m o r r i s 蠕虫”而切断i n t e r n e t 连 接,“m o r r i s 蠕虫”是2 3 岁的程序员r o b e r tt a p p a nm o r r i s 编写的用于 攻击v a x 和s u n 机器的程序。据有关方面估计,这个程序大约使得整个 i n t e r n e t 的1 0 崩溃。 2 0 0 1 年7 月,另一个名为“c o d er e d ”的蠕虫病毒最终导致了全球运行微 软的i i sw e bs e r v e r 的3 0 0 ,0 0 0 多台计算机受到攻击。 2 0 0 3 年1 月,“s l a m m e r ”( 也称为“s a p p h i r e ”) 蠕虫利用m i c r o s o f ts q l s e r v e r2 0 0 0 中的一个缺陷,使得南韩和日本的部分i n t e r n e t 崩溃,中断 了芬兰的电话服务,并且使得美国航空订票系统、信用卡网络和自动出纳机 运行缓慢。所有这些攻击以及其他许多攻击,都利用了一个称为缓 冲区溢出的程序缺陷。 名燥一时的“s q ls l a m m e r ”蠕虫王利用未及时更新补丁的m ss q ls e r v e r 数据库缓冲区溢出漏洞,采用不正确的方式将数据发到m ss q ls e r v e r 的监 听端口,这个错误可以引起缓冲溢出攻击。攻击代码通过缓冲溢出获得非法 权限后,被攻击主机上的s q l s e r v e r e x e 进程会尝试向随机的i p 地址不断 发送攻击代码,感染其他机器,最终形成u d pf l o o d ,造成网络堵塞甚至瘫 痪。 。 电子科技大学硕士学位论文c 语言安全编译器研究 在c 和c + + 中,缓冲区通常是使用数组和诸如m a l l o c 0 和n e w 这样的 内存分配例程来实现的。极其常见的缓冲区种类是简单的字符数组。溢出是指数 据被添加到分配给该缓冲区的内存块之外。 由上可知,缓冲区溢出攻击通常是在一个字符串里综合了代码植入和激活纪 录。如攻击者将目标定为具有溢出漏洞的自动变量,然后向程序传递超长的字符 串,进而引发缓冲区溢出。经过精巧设计的攻击代码以一定的权限运行漏洞程序, 获得目标主机的控制权。这种攻击手段屡次得逞主要是利用了程序中边境条件、 函数指针等设计不当问题,即利用了c 程序本身的不安全性。大多数w i n d o w s 、 l i n u x 、u n i x 系列的开发都依赖于c 语言,所以缓冲区溢出攻击成为操作系统、 数据库等应用程序最普遍的漏洞之一。 如果攻击者能够导致缓冲区溢出,那么它就能控制程序中的其他值。虽然存 在许多利用缓冲区溢出的方法,不过最常见的方法还是“s t a c k s m a s h i n g ”攻 击。e 1 i a sl e v y 的一篇经典文章“s m a s h i n gt h es t a c kf o rf u na n dp r o f i t ” 解释了s t a c k s m a s h i n g 攻击。 值得关注的是,防火墙对这种攻击方式无能为力,因为攻击者传输的数据分 组并无异常特征,没有任何欺骗( 这就是n i m d a 、s q ls l a m m e r 可以顺利穿透防 火墙的原因) 。另外可以用来实施缓冲区溢出攻击的字符串非常多样化,无法与 正常数据有效进行区分。缓冲区溢出攻击不是一种窃密和欺骗的手段,而是从计 算机系统的最底层发起攻击,因此在它的攻击下系统的身份验证和访问权限等安 全策略形同虚设。 1 1 2 当前信息安全面临的主要挑战缓冲区溢出攻击 据c e r t 安全小组称,操作系统中超过5 0 的安全漏洞都是由缓冲区溢出引起 的,这些与内存溢出相关的安全漏洞正在被越来越多的蠕虫病毒所利用。 根据绿盟科技提供的漏洞报告,2 0 0 2 年共发现各种操作系统和应用程序的漏 洞1 8 3 0 个,其中缓冲区溢出漏洞有4 3 2 个,占总数的2 3 6 。 绿盟科技评出的2 0 0 2 年严重程度、影响范围最大的十个安全漏洞中,和缓 冲区溢出相关的就有6 个。 有资料显示,8 0 的攻击事件与缓冲区溢出漏洞有关。 在1 9 9 8 年c e r t 的1 3 份建议中,有9 份是与缓冲区溢出有关的。 1 9 9 9 年,至少有半数的建议与缓冲区溢出有关,目前公开的安全漏洞通告也 2 电子科技大学硕士学位论文c 语言安全编译器研究 有相当部分属于缓冲区溢出漏洞。 1 9 9 9 年b u g t r a q ( 个讨论安全缺陷的邮件列表) 进行的一次非正式调查 发现,三分之二的参与者认为第一号的缺陷就是缓冲区溢出。 从1 9 9 7 年到2 0 0 2 年3 月,c e r t c c 发出的半数安全警报都基于缓冲区 缺陷。 年份安全建议总数与缓冲溢出相关的建议数及比例 1 9 9 62 7 51 9 1 9 9 72 81 5 5 4 1 9 9 8】3 75 4 1 9 9 91 7 84 7 2 0 0 02 2 29 2 0 0 13 7 1 95 1 表1 :c e r t 历年安全建议数据统计 c c + + 广泛的应用及其本身难以避免缓冲区溢出是目前导致“黑客”型病毒 横行的主要原因。从红色代码到s l a m m e r ,再到日前爆发的“冲击波”,都是利 用缓冲区溢出漏洞的典型。特别是在军事、国家安全、商业等领域的应用中,如 何保证系统的安全性以避免灾难性后果的发生,是当前计算机软件一个十分重要 的研究课题。 缓存溢出问题是使用很多其它诸如p e r l 、p y t h o n 、7 a v a 和a d a 9 5 语言的一 个很好的理由。大多数编程语言从根本上避免了这个问题,或者是因为它们自动 地重新设置数组大小( 如p e r l ) ,或者是因为它们般检测并防止缓存溢出( 如 a d a 9 5 ) 。但是,c 语言根本没有提供对此问题的保护,c + + 在使用时也很容易导 致此问题。而几乎现在使用的所有其它编程语言( 除了汇编语言) 都可以防范缓 存溢出。当然,使用其它语言并不能消除所有问题还有确保其它语言的基础结 构( 如运行库) 可用而且安全的问题,但总的来说,它们比c c + + 安全很多。所 以,如何防范c c + + 中的缓冲区溢出将深刻的影响今后大型软件中c c 十+ 的使用, 或者c c + + 的前途。 电子科技大学硕士学位论文 c 语言安全编译器研究 尽管已经有不少针对缓冲区溢出攻击的研究,但是缓冲区溢出仍呈现泛滥之 势。如何根除缓冲区溢出攻击仍然是信息安全中一个活跃的研究方向。本文试图 在前人研究的基础上进一步讨论如何防御缓冲区溢出攻击中的主要形式堆栈溢 出攻击。 1 | 2 主要工作 围绕c 语言安全编译器这课题内容,本文作者在毕业论文阶段做了如 下一些工作: 了解缓冲区溢出、主要是堆栈溢出攻击的成因,原理及危害: 了解前人所作的研究,分析其优缺点; 了解某一编译器( 即g c c 3 4 ) 结构, i i , 以该编译器为原型进行修改,使其生成的代码具有抵御缓冲区溢出攻击的能 力 1 3 ,本文组织 本文首先描述了当前信息安全面临的挑战,随后描述了堆栈溢出攻击及对应 策略。最后提出了数据和控制信息分离的双栈结构,并简单的分析了这种结构的 优缺点和实现。 组织如下 第二章:堆栈溢出攻击概述 第三章:目前针对堆栈溢出攻击的防御手段 第四章:g c c 编译器结构 第五章:彻底分离参数和函数控制的双栈结构 第六章:试验一c r a c kg c c 第七章:总结与展望 4 电子科技大学硕士学位论文c 语言安全编译器研究 第二章堆栈溢出攻击概述 2 i 缓冲区堆栈溢出攻击简介 缓冲区溢出攻击是一种利用软件中边境条件、函数指针等设计不当的造成地 址空问错误进行的一种攻击手段它的原理是:试图向一个有限的缓冲区的拷贝 入一个过大的数据。如果过长的数据覆盖了相邻的缓冲区,那么,占用该缓冲的 数据就会被修改,带来很多非预期的效果。 简单的,一个变量的值可能被改变 果目标缓冲区在程序的运行记录堆栈中 信息就会被修改,导致函数访存错误。 一个字符串内容可能会被改变等等;如 那么,很可能函数调用的返回地址等等 在前一种情况中,如果被修改的数据是一个随后就要被引用的指针变量,比 如一个h a n d l e f i l e ( c h a r * f i l e n a m e ) 中的f i l e n a m e ,如果被修改来指向另一 个相当重要的文件名,就会导致严重后果,如果修改了一个函数指针参数的话, 后果就更难以预料。后一种情况中,如果返回地址等信息被精心修改,程序就可 能会跳转到某些恶意代码上执行。 利用了函数运行时堆栈溢出漏洞的缓冲区溢出进行的攻击就是堆栈溢出攻 击。堆栈溢出攻击相比其他通常形式的缓冲区溢出攻击而言更容易也更普遍。下 面是一个有堆栈溢出缺陷的例子函数: v o i df u n c t i o n ( c o n s tc h a r * s t r ) ( c h a rb u f f e r 1 6 : s t r c p y ( b u f f e r ,s t r ) : j 上面的s t r c p y ( ) 将直接吧s i r 中的内容c o p y 到b u f f e r 中。这样只要s t r 的长 度大于1 6 ,就会造成b u f f e r 的溢出,使程序运行出错。当然,随便往缓冲区中 填东西造成它溢出一般只会出现s e g m e n t a t i o nf a u i t 错误,而不能达到攻击的 目的。在l i n u x 中最常见的手段是通过制造缓冲区溢出使程序运行一个用户 s h e l l ,再通过s h e l l 执行其它命令。如果该程序属于r o o t 且有s u i d 权限的话, 攻击者就获得了一个有r o o t 权限的s h e l l ,可以对系统进行任意操作了。 电子科技大学硕士学位论文c 语言安全编译器研究 2 2 堆栈溢出攻击的固有原因 从根本上来说,缓冲区溢出漏洞的产生有两个根本原因,首先是c 语言缺乏 类型安全机制和程序员有意无意的编码错误。 2 2 1 c i c + + 缺乏安全机制 c c + + 具有效率高,功能强的特点。 首先,c c + + 语言编译后产生的是机器码,执行时效率高: 其次,c c + + 可以直接操作内存的分配回收,或者嵌入汇编语言直接操作寄 存器,功能很强。 同时经过多年发展,c c + + 已经广泛应用于计算机软件开发中,包括嵌入式 开发、系统软件,应用软件等各个方面,具有不可替代的地位。 但是c c + + 本身缺乏安全机制,这一点或许是为了保证效率高,功能强所不 能不牺牲的。正是由于c c + + 本身缺乏安全机制,同时又广泛应用,造成了目前 缓冲区溢出攻击横行的状况。 而j a v a 语言,对数据进行了高度封装,使程序员不需要直接访问内存,安 全性远强于c c + + 。在j a v a 语言中,不存在缓冲区溢出。除非溢出攻击c c + + 实现的j a v a 虚拟机。这一点上,c c + + 缺乏现代气息。 2 2 _ 2 导致缓冲区溢出的常见c 和c + + 错误 从根本上讲,在程序将数据读入或复制到缓冲区中的任何时候,它需要在复 制之前检查是否有足够的空间。能够容易看出来的异常就不可能会发生但是 程序通常会随时间而变更,从而使得不可能成为可能。 然而,c 和c + 上附带的大量危险函数( 或普遍使用的库) 甚至不检查空间。 程序对这些函数的任何使用都是一个警告信号,因为除非慎重地使用它们,否则 它们就会成为程序缺陷。这些函数包括s t r c p y 0 、s t r c a t 0 、s p r i n t f ( ) 、 v s p r i n t f 0 、g e t s 0 。s c a n f 0 函数集( s c a n f 0 、f s c a n f 0 、s s c 8 n f 0 、v s c a n f 0 、 v s s c a n f0 和v f s c a n f0 ) 可能会导致问题,因为使用一个没有定义最大长度的 格式是很容易的( 当读取不受信任的输入时,使用格式“s ”总是一个错误) 。 其他危险的函数包括r e a l p a t h 0 、g e t o p t 0 、g e t p a s s 0 、s t r e a d d 0 、 s t r e c d v 0 和s t r t r n s0 。从理论上讲,s n p r i n t f 0 应该是相对安全的在 现代g n u l i n u x 系统中的确是这样。但是非常老的u n i x 和l i n u x 系统没有实 电子科技大学硕士学位论文c 语言安全编译器研究 现s n p r i n t f ( ) 所应该实现的保护机制。 m i c r o s o f t 的库中还有在相应平台上导致同类问题的其他函数( 这些函数包 括w c s c p y 0 、一t c s c p y 0 、_ m b s c p y 0 、w c s o a t 0 、一t c s c a t 0 、_ m b s c a t 0 和 c o p y m e m o r y 0 ) 。尤其注意,如果使用m i c r o s o f t 的m u l t i b y t e t o w i d e c h a r ( ) 函 数,还存在一个常见的危险错误该函数需要一个最大尺寸作为字符数目, 但是程序员经常将该尺寸以字节计( 因为其他大部分函数的参数都是以字节为单 位计算缓冲) ,从而计算出一个偏小的错误缓冲长度,结果导致缓冲区溢出缺陷。 另一个问题是c 和c + + 对整数具有非常弱的类型检查,一般不会检测操作 这些整数的问题。由于它们要求程序员手工做所有的问题检测工作,因此以某种 可被利用的方式不正确地操作那些整数是很容易的。特别是,当您需要跟踪缓冲 区长度或读取某个内容的长度时,通常就是这种情况。但是如果使用一个有符号 的值来存储这个长度值会发生什么情况呢攻击者会使它“成为负值”,然后 把该数据解释为一个实际上很大的正值吗? 当数字值在不同的尺寸之间转换时, 攻击者会利用这个操作吗? 数值溢出可被利用吗? 有时处理整数的方式会导致 程序缺陷。 2 2 3 编程错误难以避免 如果能够在编程中避免缓冲区溢出错误,缓冲区溢出攻击也就可以避免。但 是,从某种意义上来说,很难避免这一点。尽管有些工具基于某些算法试图查 找出所有的缓冲区溢出漏洞,但是这些工具仍然不能查找到所有的漏洞。 程序员尽管会尽可能小心的调用s p r i n t f ,g e t s ,s t r c p y 一类的函数,但是, 除了这些函数之外,还有很多情况也可能造成缓冲区溢出。程序员的编程习惯甚 至也影响到代码的安全性。 2 3 堆栈溢出攻击的原理 典型的堆栈溢出攻击在一个覆盖过程中需要实现两个目标: 把攻击代码注入目标程序空间中 修改程序的流向,使程序最终调用恶意代码 下面我们在简要的说明堆栈的作用后,具体的分析堆栈溢出攻击的原理。 2 3 1 进程的用户堆栈段 任何一个程序通常都包括代码段和数据段,这些代码和数据本身都是静态 电子利技大学硕士学位论文c 语言安全编译器研究 的。程序要想运行,首先要由操作系统负责为其创建进程,并在进程的虚拟地址 空间中为其代码段和数据段等建立映射。光有代码段和数据段是不够的,进程在 运行过程中还要有其动态环境,其中最重要的就是堆栈。首先,e x e c v e 会负责 为进程代码段和数据段建立映射,真正将代码段和数据段的内容读入内存是由系 统的缺页异常处理程序按需完成的。另外,e x e c v e 还会将b s s 段清零,这就是 为什么未赋初值的全局变量以及s t a t i c 变量其初值为零的原因。进程用户空间 的最高位置是用来存放程序运行时的命令行参数及环境变量的,在这段地址空间 的下方和b s s 段的上方还留有一个很大的空洞,而作为进程动态运行环境的堆栈 和堆就栖身其中,其中堆栈向下伸展,堆向上伸展。i 3 8 6 平台上的l i n u x 的进 程的地址空间如图2 3 1 所示: 图231 i in u x 进程空间示意图 高地址,4 6 b 2 3 2 程序运行过程中堆栈的作用 一个应用程序载在运行时,它在内存中的映像可以划分为三个部分:代码段, 数据段和堆栈段。代码段对应于运行文件总的t e x ts e c t i o n ,其中包括运行代 码和只读数据,这个段在内存中一般被标记为只读,任何企图修改这个段中数据 的指令将引发一个s e g m e n t a t i o nv i o l a t i o n 错误。数据段对应于运行文件中的 d a t a s e c t i o n 和b s s s e c t i o n ,其中存放的是各种数据( 经过初始化的和未经初始 化的) 和静态数据。 堆栈是一种计算机中经常用到的抽象数据类型。作用于堆栈的操作主要有两 个:p u s h 和p o p ,即压入和弹出。堆栈的特点是l i f o ( l a s ti n ,f i r s to u t ) , 即最后进入堆栈的对象最先被弹出堆栈。从物理上讲,堆栈是就是一段连续分配 的内存空间。静态全局变量是位于数据段并且在程序开始运行的时候被加载,动 电子科技大学硕士学位论文 c 语言安全编译器研究 态的局部变量则分配在堆栈里面。从操作上来讲,堆栈是一个先入后出的队列, 其生长方向与内存的生长方向正好相反。 大部分程序员都是用高级语言进行模块化编程。在这些应用程序中,不可避 免的会出现各种函数调用,比如调用c 的运行库,w i n 3 2 a p i 等等。这些调用大 部分都被编译器编译成c a l l 语句。当c p u 在执行这条指令时,除了将i p 变成调 用函数的入口点以外,还要把调用后的返回地址放入堆栈。这些函数调用往往带 有不同数量的入口参数和局部变量,这种情况下,编译器往往会生成一些指令把 这些数据也存入堆栈,有时也用寄存器传递。将一个函数调用在堆栈中存放的这 些数据和返回地址称为一个栈帧( s t a c kf r a m e ) 。图2 3 2 描述了一个标准的栈 帧结构。 图2 3 2 栈帧结构图 在调用某个函数的时候,调用方把参数和将要返回的地址压入栈中,跳转到 被调用函数执行,在被调用函数执行完成后,再从栈中取出返回的地址信息,继 续执行。 当前绝大多数c 编译程序编译出的代码基于这样的堆栈运行环境。在c 语言 程序中,参数的压栈顺序是反向的:比如f u n c ( a ,b ,c ) 在参数入栈的时候, 是先压c ,再压b ,最后压a ;在取参数的时候,由于栈的操作是先入后出,先 取栈顶的a ,再取b ,最后取c 。 堆栈就由这样一些逻辑堆栈帧组成当调用函数时逻辑堆栈帧被压入栈中, 当函数返回时逻辑堆栈帧被从栈中弹出。堆栈帧包括函数的参数,函数地局部 变量,以及恢复前一个堆栈帧所需要的数据,其中包括在函数调用时指令指针 ( i p ) 的值。 堆栈既可以向下增长( 向内存低地址) 也可以向上增长, 这依赖于具体的实 现。通常,堆栈是向下增长的。这是很多计算机的实现方式, 包括i n t e l , m o t o r o l a ,s p a r c 和m i p s 处理器。 电子科技大学硕士学位论文c 语言安全编译器研究 堆栈指针( s p ) 也是依赖于具体实现的。它可以指向堆栈的最后地址,或者 指向堆栈之后的下一个空闲可用地址。通常,s p 指向堆栈的最后地址。除了 堆栈指针( s p 指向堆栈项部的低地址) 之外,为了使用方便还有指向帧内固定地 址的指针叫做帧指针( f p ) 。或者局部基指针( l b l o c a lb a s ep o i n t e r ) 。从理论 上来说,局部变量可以用s p 加偏移量来引用。然而,当有数据被压栈和出栈 后,这些偏移量就变了。尽管在某些情况下编译器能够跟踪栈中的字操作,由 此可以修正偏移量,但是在某些情况下不能。而且在所有情况下,要引入可 观的管理开销。而且在有些机器上,比如i n t e l 处理器,由s p 加偏移量访问 一个变量需要多条指令才能实现。因此,许多编译器使用第二个寄存器,f p , 对于局部变量和函数参数都可以引用,因为它们到f p 的距离不会受到p u s h 和 p o p 操作的影响。在i n t e lc p u 中,b p ( e b p ) 用于这个目的。 考虑到我们堆栈的增长方向,从f p 的位置开始计算,函数参数的偏移量 是正值,而局部变量的偏移量是负值。当一个例程被调用时所必须做的第一件 事是保存前一个例程的f p ( 这样当例程退出时就可以恢复) 。然后它把s p 复制 到f p ,创建新的f p ,把s p 向前移动为局部变量保留空间。这称为例程的序 幕( p r o l o g ) 工作。 当例程退出时,堆栈必须被清除干净,这称为例程的收尾 ( e p i l o g ) 工作。i n t e l 的e n t e r 和l e a v e 指令,都可以用于有效地序幕和收尾 工作。 堆栈指针( s p ) 的寄存器指向堆栈的顶部。堆栈的底部在一个固定的地址。堆 栈的大小在运行时由内核动态地调整。c p u 实现指令p u s h 和p o p , 向堆栈中添 加元素和从中移去元素。通常内存的生长方向为向上,栈的生长方向为向下,于 是,压栈的操作p u s h = s p 一4 ,出栈的操作是p o p :s p + 4 在一次函数调用中,堆栈中将被依次压入:参数,返回地址,e b p ,如果函 数有的话局部变量,接下来,就在堆栈中开辟相应的空间以构造变量。函数执行 结束,这些局部变量的内容将被丢失,但是不被清除。在函数返回的时候,弹出 e b p ,恢复堆栈到函数调用的地址,弹出返回地址到e i p 以继续执行程序。 2 3 3 程序运行过程中堆栈的变化 下面我们用一个简单的示例程序来分析栈帧的结构。 v o i dp r o c ( i n ti ) a n tl o c a l ; 1 0 电子科技大学硕士学位论文c 语言安全编译器研究 p r o c ( 1 ) ; 这段代码经过编译器后编译为:( 不同版本的g c c 以及不同的参数会有不同结果) m a i n :p u s h 1 c a l l p r o c p r o c :p u s he b p m o v e b p ,e s p s u b e s p ,4 m o v e a x , e b p + 0 8 m o v e b p 4 ,e a x a d d e s p ,4 p o pe b p r e t4 下面我们分析一下这段代码。 m a i n :p u s h1 c a l lp r o c 首先,将调用要用到的参数l 压入堆栈,然后c a l lp r o c p r o c :p u s he b p m o ve b p ,e s p 1 l 电子科技大学硕士学位论文 c 语言安全编译器研究 我们知道e s p 指向堆栈的顶端,在函数调用时,各个参数和局部变量在堆栈 中的位置只和e s p 有关系,如可通过 e s p + 4 存取参数1 。但随着程序的运行, 堆栈中放入了新的数据,e s p 也随之变化,这时就不能在通过 e s p + 4 来存取1 了。因此,为了便于参数和变量的存取,编译器又引入了一个基址寄存器e b p , 首先将e b p 的原值存入堆栈,然后将e s p 的值赋给e b p ,这样以后就可以一直使 用 e h p + 8 来存取参数1 了。 将e s p 减4 ,留出一个i n t 的位置给局部变量l o c a l 使用,l o c a l 可通过 e b p 一4 来存取 首先e s p 加4 ,收回局部变量的空间,然后p o p e b p ,恢复e b p 原值,最后 r e t4 ,从堆栈中取得返回地址,将e i p 改为这个地址,并且将e s p 加4 ,收回 参数所占的空间。不难看出,这个程序在执行p r o c 过程时,栈帧的结构如下: 44 4 4 局部变量 e b p r e t 地址 参数1 内存高端 i 1i e s p ( 栈顶) e b p 栈底 我们可以总结出一般栈帧的结构: 局部变量 e b p r e t 地址 参数1 _ - 参数n 。内存高端 ii i e s p ( 栈顶) e b p 栈底 了解了栈帧的结构以后,现在我们看一下b u f f e r o v e r f l o w 的机理了。 鹏 雠 p e 酞 , , 一 x p , , 唧 咖 。 v v d 鲁_ 吨 榭 甜 阳 x叭 是就 电子科技大学硕士学位论文c 语言安全编译器研究 电子科技大学硕士学位论文c 语言安全编译器研究 以结果是b u f f e r 后面的2 5 0 字节的内容也被覆盖掉了,这其中自然也包括e b p , r e t 地址,l a r g e s t r i n g 地址。因为此时r e t 地址变成了o x 4 1 4 1 4 1 4 1 h ,所以 当过程结束返回时,它将返回到o x 4 1 4 1 4 1 4 1 h 地址处继续执行,但由于这个地址 并不在程序实际使用的虚存空间范围内,所以系统会报s e g m e n t a t i o n v i 0 1 a t i o n 。 从上面的例子中不难看出,我们可以通过b u f f e ro v e r f l o w 来改变在堆栈中 存放的过程返回地址,从而改变整个程序的流程,使它转向任何我们想要它去的 地方。这就为黑客们提供了可乘之机,l i n u x 中最常见的方法是:在长字符串 中嵌入一段代码,并将过程的返回地址覆盖为这段代码的地址,这样当过程返 回时,程序就转而开始执行这段我们自编的代码了。一般来说,这段代码都是 执行个s h e l l 程序( 如b i n s h ) ,因为这样的话,当我们入侵一个带有b u f f e r o v e r f l o w 缺陷且具有s u i d r o o t 属性的程序时,我们会获得一个具有r o o t 权限 的s h e l l ,在这个s h e l l 中我们可以干任何事。因此,这段代码一般被称为s h e 】 c o d e 。 2 3 5 s h e l l c o d e s h e l l c o d e 是编写缓冲溢出攻击程序中最艰难的一部分。通常来说,要得到 一个可用的s h e l l e o d e ,首先需要用编译器编译一个简单的程序,然后得到这个 程序的反汇编代码,再重定位,替换含0 命令,最后添加到一段n o p 指令后。其 间还需要反复的调试。因为s h e l l c o d e 的编写复杂且和本文主旨关系不大,故略。 2 4 小结 缓冲区溢出攻击通过利用编程漏洞,可以得到很高的权限,从远程控制主机。 是当今最危险的安全问题。而且,由于某些堆栈溢出攻击程序编写不难,造成了 当今计算机网络上病毒横行。如何有效地防御堆栈溢出攻击成为一个不可回避的 问题。 1 4 电子科技大学硕士学位论文c 语言安全编译器研究 第三章目前针对堆栈溢出攻击的防御手段 一般来说,更改底层系统以避免常见的安全问题是一个极好的想法。事实证 明存在许多可用的防御措施,而一些最受欢迎的措施可分组为以下类别: 基于探测方法( c a n a r y ) 的防御。这包括s t a c k g u a r d ( 由g c c 和i m m u n i x 所 使用) 、p r o p o l i c e ( 由o d e n b s d 所使用) 和m i c r o s o f t 的g s 选项。 非执行的堆栈防御。这包括s o l a rd e s i g n e r 的n o n e x c 补丁( 由 o p e n w a l l 所使用) 和e x e cs h i e l d ( 由r e dh a t f e d o r a 所使用) 。 其他方法。这包括1 i b s a f e ( 由m a n d r a k e 所使用) 等等。 遗憾的是,迄今所见的所有方法部具有弱点,但是它们会提供一些帮助。 3 1 s t a c k g u a r d 和v s n e t 的g s 选项 s t a c k g u a r d 是一种用来防止堆栈溢出攻击的编译器。由c r i s p i nc o w a n 及 i m m u n i x 开发小组维护。用它编译的程序可以有效的防止堆栈溢出问题。它的工 作原理是在调用函数时,将返回地址压栈后,再将一个随机产生的字也压入堆栈。 当函数调用完毕返回时,查看是否这个随机字被修改,若已被改动,则说明有溢 出发生。掇引s t a c k g u a r d 作者的话,s t a c k g u a r d 是一种”用轻微的性能损失来 消除堆栈溢出问题的编译器技术”。 s t a c k g u a r d 修改c 编译器( g c c ) ,以便将一个“探测”值插入到返回地址的 前面。“探测仪”就像煤矿中的探测仪:它在某个地方出故障时发出警告。在任 何函数返回之前,它执行检查以确保探测值没有改变。如果攻击者改写返回地址 ( 作为s t a c k s m a s h i n g 攻击的一部分) ,探测仪的值或许就会改变,系统内就 会相应地中止。这是一种有用的方法不过要注意这种方法无法防止缓冲区溢出 改写其他值( 攻击者仍然能够利用这些值来攻击系统) 。人们也曾扩展这种方法 来保护其他值( 比如堆上的值) 。s t a c k g u a r d ( 以及其他防御措施) 由i m m u n i x 所 使用。 3 1 1 原理 下面是s t a c k g u a r d 的堆栈结构示意图 l 栈底方向,高址 传递给函数的参数 电子科技大学硕士学位论文c 语言安全编译器研究 函数的返回地址( r e t ) c a n a r y 保存的栈帧指针( e b p ) 局部变量 栈顶方向,低址 对比前面的标准堆栈结构图2 3 2 ,s t a c k g u a r d 在栈帧中添加了一个探测数 据一- - c a n a r y 。这个c a n a r y 位于前一栈帧指针和局部变量之上,返回地址之下。 通过设置和检查c a n a r y ,s t a c k g u a r d 确定是否发生了堆栈溢出攻击。 在典型的堆栈溢出攻击过程中,攻击的数据长度超过了局部变量所能容纳的 长度,从而覆盖了栈帧中保存的返回地址,使程序在这个函数结束r e t u r n 时, “返回”到了非预期的地址上运行。但是在s t a c k g u a r d 保护下,如果通过局部 变量溢出覆盖返回地址,必然要让攻击数据覆盖掉局部变量和返
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 阜阳界首市教师招聘考试真题2024
- 扁鹊考试题及答案
- 考试题及答案数学
- 切线考试题及答案
- 系统解剖学模拟练习题(含参考答案)
- 眼科基础知识模考试题与参考答案
- 高级养老护理员理论测试试题含答案
- 中学数学教学设计与案例分析知到智慧树答案
- 2025版三方公司环保设备更新借款合同
- 2025独家销售合同:智能家居系统区域独家代理协议
- 中学政治九年级《坚持改革开放》说课课件
- 2025届广州市高三年级阶段训练(8月市调研摸底) 数学试卷(含答案)
- 制造业企业质量管理能力评估规范
- 《中国民航发展史》课件-第一章 中国民用航空的萌芽与初步发展
- 2024年(学习强国)思想政治理论知识考试题库与答案
- 地球物理勘探合同范本
- 《飞机结构与系统》课件-机翼结构
- 渠道维护工考试题库考点
- DL-光伏发电站电能质量检测技术规程
- 游戏传媒策划方案
- 变压器油色谱分析(详细超值版)
评论
0/150
提交评论