1、1美Mark Stamp著Information Security:Principles and Practice,2nd Edition张 戈译第12章 软件中的安全212.1 引言本章主要内容:软件逆向工程 数字版权管理 软件开发312.2 软件逆向工程软件逆向工程有时也被称为逆向代码工程,或者简称为逆向工程。用途有好有坏。好的用途包括理解恶意代码或是对以往的遗留代码进行分析。不那么好的用途包括移除对于软件的使用限制、查找和利用软件缺陷、在游戏中实施欺诈活动、破解DRM系统以及许许多多其他类型的针对软件的攻击。基本的逆向工程工具包括反汇编器(disassembler)和调试器(debugg
2、er)。反汇编器能够将可执行文件转换为汇编代码,这种转换属于尽力而为型,但是反汇编器并不能确保总是正确地反汇编出汇编代码。调试器用来设置程序中断点,据此Trudy就可以在程序运行时一步步地跟踪代码的执行过程。对于任何有一定复杂度的程序而言,调试器都是理解代码的必备工具。比如OllyDbg。IDA Pro是一款强大的反汇编器和调试器412.2.1 Java字节码逆向工程当你编译Java的源代码时,会将其转换成字节码,之后字节码再被Java虚拟机(Java Virtual Machine,JVM)执行。有一些工具就可以用于将Java字节码转换成Java源程序代码,而且得到的源程序代码很可能与原始的
3、源程序代码非常相似。512.2.2 SRE示例攻击者Trudy不知道序列号,当她给出(错误的)猜测时,得到的结果如图12-1中所示:Trudy决定她首先要做的第一件事就是对serial.exe实施反汇编。图12-2中给出了一小部分使用IDA Rro反汇编的结果。6在图12-2中,地址显示为0 x401022的一行表明正确的序列号是S123N456。于是Trudy尝试使用这个序列号并且发现确实是正确的,这从图12-3中就可以看出来。Trudy想要对这个可执行文件serial.exe进行修补,以便她不再需要记录这个序列号。接下来Trudy对这个exe文件(以十六进制表示的形式)在地址0 x4010
4、30处的二进制位进行检查,这时她观察到图12-4中呈现的结果。7图12-5中给出了原始可执行文件和经过修补之后的可执行文件的对比。于是,Trudy执行这个经过修补的代码serialPatch.exe,并输入不正确的序列号。图12-6中的结果表明,这个修补的程序可以接受不正确的序列号。8最后,我们又对文件serial.Exe和serialPatch.Exe分别执行反汇编,图12-7中给出了结果的对比情况。这些代码片段表明修补工作达成期望的目标结果。912.2.3 防反汇编技术防反汇编的方法 对可执行文件实施加密 错误反汇编 自修改代码。n 顾名思义,自修改代码能够实时地修改自身的可执行文件 10
5、12.2.4 反调试技术有几种不同的方法可以用来令调试更加困难。因为调试器会使用一些特定的调试寄存器,所以程序就可以监控这些寄存器的使用,并且当这些寄存器被使用时,程序就停止。调试器不能很好地对线程进行处理,因此在被恰当实现的情况下,相互作用的线程就能够提供一种相对而言比较强的方法以便对调试器产生迷惑作用。还有许多其他的能令调试器工作不力的技巧,其中的大部分都是高度调试器相关的。1112.2.5 软件防篡改防篡改的目标是要令修补更为困难,通过让代码更加难以被理解,或是让代码一旦被修补便无法执行等方式来实现这个目标。1.Guard 让程序包含自身的哈希片段,当执行时可以将新计算出的哈希值与已知的
6、原始代码的哈希值进行比较。如果有篡改行为(例如代码已被修补过)发生,哈希校验将会失败,从而程序也就可以采取规避措施。研究表明,使用Guard机制有可能以一种最小的性能损失来获得对于软件较好程度的一种保护。2.混淆处理混淆处理的目标就是令代码更加难以被理解。基本逻辑则是:如果Trudy无法理解代码,那么她在对代码进行修补时也就会遭受折磨。例子:spaghetti代码 12对于下面伪码:无论 x 和 y 为任何值,if 条件总是为假,因为(x-y)(x-y)=x2-2xy+y2 代码混淆处理有时候会被提高到作为一种强大的通用型安全技术的层面上。事实上,在Diffie和Hellman提出的关于公开密
7、钥加密技术的原始概念里,他们提议了一种所谓的“单向编译器”(也就是混淆处理的编译器),将其作为开发这样一个密码系统的一种可能途径。混淆处理技术也可以与其他的手段结合在一起使用,包括前面提到的防反汇编、反调试以及防修补技术等诸多方法中的任何一种。1312.2.6 变形2.0“一次攻破,处处得逞”(BOBE)的免疫力变形软件可以被病毒编写者用来逃避检测手段。那么,相似的技术是否可以用于行善而不是作恶呢?由于开放平台和SRE技术的存在,我们无法阻止针对软件的攻击行为。可以说,我们所能够期望的,最多也就是提高BOBE抵抗力的水平。而要获得一定程度的BOBE抵抗力,变形软件就是其中一种可能的手段。变形并
8、不能阻止SRE,但却能够提供实质性的BOBE抵抗力。变形技术最为引人注目的是在恶意软件中的应用。1412.3 数字版权管理数字版权管理(Digital Rights Management,DRM)为了说明软件中实施安全的局限性提供了很好的示例。接下来我们要讨论DRM是什么,以及DRM不是什么。然后,我们还将介绍实际的DRM系统,该系统的设计目标是为了在特定的公司环境之内保护PDF文档资料。此外,我们也会简略地给出用于流媒体保护的DRM系统的梗概,最后我们还要讨论一款推荐的peer-to-peer应用,其中就使用到了DRM。1512.3.1 何谓DRM从最基本的层面上看,DRM可以被视为一种针对
9、数字内容提供某种“远程控制”的尝试。例子:如何在数字化时代防止书本被复制?持久保护(persistent protection)是DRM保护理论层面的时髦术语。意思是说,我们希望对数字化内容进行保护,要使得即便在数字化内容被交付之后,这种保护仍能够伴随内容本身而留存。n 禁止拷贝n 仅读一次n 直到圣诞节才能打开n 禁止转发如何施加这样的持久保护?n 一种选择就是完全依赖信用系统,在这种情况下,我们实际上并不强制用户遵守规则。n 另外一种选择是放弃在诸如PC这样的开放平台上强制实施DRM的做法。16开发“强壮的”基于软件的DRM系统 出于某种客观需要,基于软件的DRM系统在很大程度上要依赖于不
10、透明带来的安全性。强壮的基于软件的DRM系统是不可能实现的。1712.3.2 一个真实世界中的DRM系统MediaSnap公司的DRM系统共包括两个主要的组成部分。n 一个服务器组件,称之为安全文档服务器(SDS);n 另一个是客户端软件,可以作为插件加载到Adobe的PDF阅读器程序中。在这个DRM框架中,整个电子邮件都会被转换成PDF格式,随后再被加密并发送给SDS。最后SDS将期望的持久保护措施应用到文档上面。然后,通过邮件,这样处理之后的结果文档就被发送给了Bob。18在这个架构中,服务器和客户端都存在一些安全问题。n SDS必须保护密钥并对用户进行身份认证,还必须将需要的持久保护应用
11、到文档上面。n 客户端软件必须保护密钥,对用户进行身份认证,并且实施持久性保护,所有这些操作都是在一种可能会暗藏敌意的环境中执行。另一方面,DRM客户端软件对于任何攻击者来说都随手可得。下面的讨论主要集中在客户端软件上。客户端软件高阶设计的图解 这个软件的外层用于尝试创建抗篡改的屏障,这包括防反汇编技术和反调试技术的应用。19反调试技术相当复杂精深,虽然基本思想只不过就是对调试寄存器的使用进行监控。它面临中间人攻击。防篡改技术能够对攻击者起到延缓的作用,但是这些技术并不能阻止持之以恒的攻击者获得最终的成功。混淆处理技术被应用于一些至关重要的安全操作中,这包括密钥管理、身份认证以及加密操作等。在
12、这个系统中,对数字内容的加密使用的是高级加密标准(AES)的分组加密方案。因此,MediaSnap的系统也利用了“加扰”算法,这本质上又是一种专门的密码方案。MediaSnap的DRM系统利用了多个层次的混淆处理技术。这个系统实现的另一个安全特性就是一种防抓屏技术。20MediaSnap的这款DRM软件使用变形技术来提升BOBE抵抗力。其中,变形技术的使用体现在几个不同的地方,而最为引人注目的就是“加扰”算法。MediaSnap的DRM系统利用到各种各样的软件保护技术。几乎可以肯定,这款产品应该是最先进的基于软件的DRM系统之一了。其中唯一没有采用的重要保护机制就是guard,也可以称为“脆弱
13、化”技术。2112.3.3 用于流媒体保护的DRM针对流媒体可能存在的攻击形式包括对端点之间传递的流实施欺诈、中间人攻击、重放或重新分发数据,以及在客户端抓取明文信息等。我们主要考虑最后一种攻击行为。客户端软件的每一个实例都在其中配备了大量的加扰算法。主集合包含了所有的加扰算法,每一个客户端都有不同的从主集合中挑选出来的加扰算法的子集合,而服务器知道这个主集合。在这个DRM框架中,数据在服务器上被加扰混乱,然后再被加密。在客户端一侧,数据必须被解密,然后再被解扰恢复。解扰恢复的过程发生在专用的设备驱动程序上,刚好在内容被播放之前进行。这种处理方式的目的是希望保持明文信息尽可能地远离攻击者Tru
14、dy,直到媒体被播放之前的最后一刻。22假设服务器知道N种不同的加扰算法,分别表示为S0,S1,.,SN-1。每一个客户端都配备了这些算法的一个子集。举个例子,某个特定的客户端可能会有如下加扰算法集合:LIST=(S12,S45,S2,S37,S23,S31)这个LIST以加密形式E(LIST,Kserver)存储在客户端,其中Kserver是只有服务器才知道的密钥。为了协商出加扰算法,客户端要将LIST发送给服务器。之后服务器解密LIST,再选择客户端内置的某个算法。接下来,服务器必须安全地将其对于加扰算法的选择传达给客户端。23通过加扰算法实现的这种变形已经深深地嵌入到系统中,并与所有的数
15、据绑定在了一起。而且,如果服务器知道某个特定的加扰算法被破解了,那么服务器就不会再选择该算法。并且,如果某个特定的客户端有过多的已破解算法,那么服务器在同意分发内容之前,将强制执行一次软件更新。服务器也可以等到分发内容之前的那一刻再去分发客户端软件(或者其中某些关键的组件),这将会令Trudy实时抓取流媒体的行为更加困难,因为可用于攻击软件的时间非常有限。当然,Trudy可以录制媒体流,然后待闲暇之时再对软件实施攻击。不过,在许多情况下,攻击如果无法实现接近于实时的效果,就几乎不会被考虑了。因为加扰算法对于攻击者来说是未知的,所以他们需要付出相当大的努力来实施逆向工程,然而标准的加密算法则根本
16、无须逆向工程攻击者唯一需要寻找的就是密钥。2412.3.4 P2P应用中的DRMpeer-to-peer通常简写为P2P,大量的数字内容都会通过peer-to-peer网络方式进行递送。例如,在这样的网络上包含有大量不合法的或是盗版的音乐。例子:n 假设Alice已经加入到某个P2P网络中,这时她想要一些音乐,比如由某人“转播”的一首歌。于是,对这首歌曲的查询就在整个网络上传播,而任何拥有这首歌的站点并且也愿意将其分享就会对Alice予以响应。25服务提供站点 简称为POS。POS站点的行为与任何其他站点没有什么不同,除了只提供合法的并且受到DRM保护的音乐之外。为了令POS的设想工作有效,必
17、须使得Alice无法知道某个站点究竟是普通的站点还是POS站点。此外,POS站点及其兄弟站点必须能够以相当高的概率出现在响应列表中的前10位里。n 设置POS站点的想法非常聪明,因为这可以将自身骑附于现存的P2P网络之上。而且,在这个基于POS站点运行的场景中,相对来说比较弱的DRM系统就足够了。2612.3.5 企业DRM有一些政府法规会要求商业公司对特定类型的个人私有信息进行保护。另外,对于许多类型的商业记录也有相类似的法规约束。考虑到HIPAA的规定,企业必须小心谨慎,以防这些记录被泄露给非授权的接收方。DRM系统就有助于解决这个问题。在电子商务环境中,DRM系统的强度是压倒一切的首要任
18、务。但是,在企业环境中,还有许多其他的常规事务更为重要。电子商务环境中的DRM和企业DRM面临着类似的技术障碍。但是,由于人为因素导致的对这两者理解上的巨大差异,一种几乎成了不可解的难题,而另一种则看起来易如反掌。2712.3.6 DRM的败绩 失败的电子商务类DRM系统的案例非常多n 安全数字音乐行动(Secure Digital Music Initiative,SDMI)n 微软公司的MS-DRM(第二版)2812.3.7 DRM小结 DRM说明了在软件中实现安全的局限性,特别是当软件还必须在充满敌意的环境中执行时。这样的软件很容易受到攻击,同时相应防护的选择还极其有限。换句话说,攻击者
19、几乎占尽了各种优势。防篡改硬件和可信操作系统则会有显著不同。2912.4 软件开发对软件开发来说,标准的套路就是尽可能快地开发和发布软件产品。虽然也已经执行了不少的测试工作,但仅仅这些永远都不够,所以当用户发现软件缺陷之后,就需要对代码打补丁。在安全方面,这就是所谓的“渗透和补丁”模式。一般来说,“渗透和补丁”模式是一种不好的软件开发方法,对于开发安全软件而言则是一种灾难性的方式。即便软件缺陷给公司造成了重大损失,软件的生产商也不会负任何法律责任。3012.4.1 开源软件和闭源软件对于开源软件,源程序代码是用户可以获得的,比如Linux操作系统。对于闭源软件,源程序代码则是普通公众无法得到的
20、,比如Windows操作系统。开源软件声称的主要安全优势可以被总结为“更多的眼球”,即有更多的人能够查看代码,所以会有较少的缺陷仍能够保持隐藏状态。这实际上恰恰是Kerckhoffs原则的另一种表现形式。与开放源代码相关的另一个问题就是攻击者能够在这些源代码中寻找缺陷。开放源代码案例研究的例子:n Wu-ftp31闭源软件中的安全缺陷对于攻击者而言并不是那么明显,这也可以被看做提供了某种安全保护手段。开源软件的倡导者们常常会援引所谓的“微软谬论”来说明为什么开源软件天生就要优于闭源软件,谬论如下:n 微软制造了差的软件。n 微软的软件是闭源的。n 因此,所有的闭源软件都是差的。经过t个单位的测
21、试之后,发生安全性故障的概率大约是K/t,其中K是常量,并且这个近似值对于跨度很大的t值均可以成立。常量K是关于软件初始质量的度量K值越小,软件最初的质量就越好。开源软件的平均故障间隔时间(MTBF)为:MTBF=t/K 闭源软件的平均故障间隔时间(MTBF)为:MTBF=2t/K3212.4.2 寻找缺陷与软件测试相关的基本安全问题是,诚恳认真的好孩子们必须找出几乎所有的安全缺陷,而Trudy只需要找到那些好孩子们尚未发现的缺陷即可。这就意味着,相对于通常意义上的软件工程,软件的可靠性在安全领域面临的挑战要大得多。3312.4.3 软件开发相关的其他问题对于安全性而言至关重要的软件开发议题:
22、设计:设计:就安全性而言,设计阶段起着至关重要的决定性作用,因为深思熟虑的初始设计可以避免一些高阶错误,而这些错误在后面的阶段很难被改正。风险分析风险分析:方法包括危险和可操作性研究(HAZOP)、失效模式和效果分析(FMEA)以及故障树分析(FTA)。同行评审:同行评审:是一种可辅助提高安全性的有用工具。共有三个层次的同行审查,从最不正式到最为正规,有时候会依次将其称为复审(review)、走查(walk-through)以及检查(inspection)。测试:测试:位于开发过程层面的测试分类位于开发过程层面的测试分类n 模块测试(module testing):对小部分的代码实施独立测试。
23、n 组合测试(component testing):将几个模块组合在一起并进行测试。n 单元测试(unit testing):将很多组件联合在一起进行测试。n 集成测试(integration testing):将所有的部分全部放在一起,作为整体进行测试。34 位于审视测试活动层面的分类:位于审视测试活动层面的分类:n 功能测试(function testing):要验证系统功能是否与要求相一致。n 性能测试(performance testing):对诸如执行速度和资源利用水平等相关要求进行符合性验证。n 验收测试(acceptance testing):这是指客户主动参与的测试活动。n 安
24、装测试(installation testing):顾名思义这是在软件安装时执行的测试。n 回归测试(regression testing):这是指在任何对于系统的重要变动发生之后执行的测试活动。其他测试技术:其他测试技术:n 主动故障检测(active fault detection):由测试者主动尝试令系统出现问题。n 软件错误注入(fault injection):主动施加故障到软件中以促进系统错误的发生。n bug注入技术:可以让测试人员对于代码中存留的bug数量获得估量。35配置管理:指我们如何去处理对系统的变更。n 细微变更(minor changes),是指那些为了维持每天系统功能的正常运行而发生的变更;n 适应性变更(adaptive changes),这是更加实质性的变更;n 完善性变更(perfective changes),是指对软件的改进;n 预防性变更(preventive changes),意在防止任何性能方面的损失 事后故障排查:用来从问题中学习经验教训,进而能够提升同一类问题在未来可以被避免的概率。3612.5 小结本章内容回顾 软件逆向工程(SRE)数字版权管理(DRM)安全软件开发面临的一些困难 37