ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 被黑客们使用的代码混淆技术

被黑客们使用的代码混淆技术

原创 Linux操作系统 作者:turingbooks 时间:2012-05-08 09:40:06 0 删除 编辑

长久以来,代码混淆技术一直都被认为是不能登大雅之堂的奇巧淫技,没有哪个学者会拿正眼瞧它一眼。国际C语言混乱代码大赛(International Obfuscated C Code Contest,IOCCC)[177,227]就是一个很好的例子——尽管每年都有不少参赛选手写出令人啧啧称奇的代码,但是大家对此的评价却总是:“啊!这个很有意思,不过对实际工作有什么用处吗?”当时C语言还被认为是写这类程序的最佳选择 。人们那时以为:代码混淆技术并没有什么真正的价值,使用这些技术的人脑子都坏掉了,想靠这种把戏愚弄攻击者简直就是痴心妄想。但是突然Java横空出世了。Java在带给人们可以在任何平台上运行的便利的同时,由于Java字节码设计的特殊性,使得传统的针对机器码的安全保护技巧一夜之间变得毫无用处。这时人们才想起了代码混淆技术,因为当时在Java平台上,这似乎是唯一有效的代码保护技术。

不幸的是,代码混淆技术被应用的最成功的领域是在黑客的手上。大家对此应该已经见怪不怪了。好像坏蛋们总能比好人们更快地适应新技术——尽管这些新技术都是好人们设计出来的。比方说密码学吧,它既可以保护执法部门之间的通信,也能够用来保护罪犯之间的联系。又比如隐写术,国家安全部门可以用它保护国家机密信息,但犯罪分子也能利用它以不被发现。目前已知的最早破解基于智能卡的防护技术的人是破解电视机机顶盒的黑客,但是这些黑客转手又使用相关防护技术来保护他们自己的产品免受机顶盒厂家的破解。
Axel对他编写的病毒进行混淆处理,使之免于被Doris发现——这是黑客们手中代码混淆技术的用途之一。如图1-22所示。

病毒由两个部分组成:载荷(payload)和混淆部件(obfuscator),载荷是用来做坏事的代码,而混淆部件则是病毒用来保护自身免于被查杀的。Axel首先要感染程序P,使之携带病毒v,这样得到一个带病毒的程序P ′。然后Axel开始传播P ′。如果Doris在她的机器上运行了P ′,那么病毒就会感染Doris系统中的另一个程序Q。在病毒感染Q之前,会先使用代码混淆技术对自身进行修改,生成自身的另一个完全不同的版本v',然后再去感染Q,产生带毒程序Q ′……Axel这样做的目的在于:如果每一代病毒都是完全不一样的话,Doris的杀毒软件就很难完全查杀这些不同版本病毒。这和之前讨论的系统变形的情形是类似的,只不过攻守的双方互换了下位置罢了。

1. 故意出错——不露痕迹地进行代码混淆

如果你见过IOCCC的参赛代码,就会发现它们与普通代码迥然不同。机器生成的、经过混淆的或者被优化过的代码看上去也是这个德行——与人工编写的代码之间存在巨大的差异。比如说,看看代码清单1-1,你一下子就能断定这些代码肯定不是人写的。所以当Axel分析Doris的程序时,这段代码首先就会引起他的怀疑——密码不是很可能就藏在这种被混淆的代码中吗?在本书的许多案例中,你都可以看到不露痕迹地使用保护技术是多么的重要——不能给对手以提示:我们对这些代码使用了软件保护技术,或者我们按着那样的一个顺序使用了这几种软件保护措施。

如果坏人们使用了这种技术,我们分析嫌疑程序时就很头疼了。黑客们通过故意在程序中插入错误的方式来达到隐蔽地使用代码混淆技术的目的。我们来看一下代码清单1-3,这个程序是用来对“美国偶像”的投票结果进行记录和统计的。该程序从系统的标准输入中读取投票数据,然后经过统计输出投票结果。下面给出的就是该程序的一次运行实例。

代码清单1-3 经过混淆的投票统计代码

这个程序的对投票进行统计的算法正确吗?其中是否含有作弊代码?在阅读提示之前 ,请先花点时间,看看从这个只有58行代码的程序中找出错误需要多少时间?好吧,现在你又认为在现实中,从一个拥有成千上百行代码的投票系统中找出类似的错误要花你多少时间呢?如果代码清单1-3中所示的技术与代码清单1-1中所示的技术被结合起来使用的话,又会有怎样的结果呢?这样是否就能使作弊程序隐蔽地潜伏到投票系统的代码中,而不被发觉呢?也许下一期的“美国偶像”早就已经被内定了。(或者,要是这个作弊程序被嵌入在美国总统选举的计票系统中呢……)

2. 混淆病毒

正如你所见,今天,对于一些很重要的实际问题,代码混淆技术可能是唯一可行的解决方案。但不幸的是,代码混淆技术最辉煌的成就却是在黑客们手中实现的——用于保护病毒、蠕虫、木马和rootkit免遭查杀。观察黑客们研发并在实践中已经证明了其有效性的技术,以及安全研究者们能否再次利用同样技术确实是件很意思的事情。病毒的作者和杀毒软件厂商已经陷入了一场猫捉老鼠的游戏中:每当杀毒软件厂商开发出一种新的病毒检测技术时,病毒的作者们就会使用一种更为巧妙的代码混淆技术来抵御这种检测技术,而这又促使杀毒软件厂商研发更为强大的病毒检测技术……到目前为止,好像还是黑客们在这场游戏中略占上风。根据最新的报道,世界上有25%的计算机曾经被botnet[368]入侵和控制。当然,这一“成就”也不能光归功于恶意软件中使用的代码混淆技术,许多人不及时给操作系统打补丁、不经常升级杀毒软件也是一个很重要的原因。

病毒逃避杀毒软件检测的主要方法是使杀毒软件“看不见” 病毒体中的代码。由于杀毒软件只能占用计算机中极小一部分资源 ,所以它不可能完整地分析硬盘中每个文件。而且即使它能做到这一点,理论研究的结果也表明仍然会有病毒可能漏网。因此大多数杀毒软件都是使用病毒的特征码来识别病毒的。从某种角度上说,如果病毒体的代码在病毒每次感染文件时都不会发生变化的话,特征码确实是一个不错的检测方法。它就类似于软件“胎记”(这一技术将在第10章中详细讨论)。

那么病毒的作者又是使用哪些技术让杀毒软件“看不见”病毒体中的代码呢?我们来看一下代码清单1-4中给出的这个Java程序。当然,在实际生活中几乎不会有人会用Java去编写病毒,我们编写这个例子只是为了帮助你理解病毒是怎样使用代码混淆技术保护自身的。所以也请你大人有大量,原谅我们用Java编写它吧。
在这个Java病毒中有几个做法值得引起我们的注意。首先,我们注意到病毒好像是把自己的整个源码都当成是一个字符串,并把它放在了程序中。为了不至于不断地重复自身导致死循环,编写这个程序的程序员使用了一些代码复制的技巧 。这个技巧在一种源自基内斯 的搞怪表演中也常被使用——在这种表演中,程序运行之后将会输出自己的源码。

源码是被放在一个名为self的变量中的。最终它会被写到一个文件(m.java)里去,并由被感染计算机上安装的Java编译器编译执行。最近出现的Slapper蠕虫[320]及其变种也使用编译器来尽量减少自身对于平台的依赖性。使用编译器对黑客有利的另一个副作用是——使用不同的编译器编译同一份源码时可能会产生略微不同的可执行文件(尽管在语义上这些可执行文件是完全等价的),这就使得我们提取病毒特征码时还要考虑不同编译器之间的差异,进而增加了特征码提取的难度。

代码清单1-4中的代码更进了一步。在把自身复制到m.java文件中之前,它先要把自身用morph函数处理一下。morph函数的作用就是在程序的各行之间都插入一句i++语句。这个语句并不会影响程序的行为或者输出结果,但是这个小花招的确使每个新的病毒样本都与其前一代不一样!这也就是说,只使用了简单的特征码技术的杀毒软件是无法发现这个病毒的。

代码清单1-4 一个Java变形病毒

你可以想象一下:如果这里,病毒的作者没有使用这个简陋的morph函数,而是使用了那些下文详细介绍的、更为狡诈的代码混淆技术,你认为杀毒软件要用到哪些分析技术才能发现这个病毒呢?

实践中,病毒会使用代码混淆技术尽可能地确保每次感染后产生的新一代病毒的许多属性都变得完全不同。我们把这种在每次感染之后都用代码混淆技术把整个病毒体的代码全部改得面目全非的病毒称为变形病毒。而多态病毒可以认为是变形病毒的更进一步优化的版本。因为它不像变形病毒对整个病毒的代码都进行混淆处理 ,而是用不同密钥把整个病毒的代码全都加密起来。当然,为了保证能正常运行,病毒还要自带一个解密模块,多态病毒中使用代码混淆技术处理的就只有这个解密模块。总的来说,在多态病毒中,代码混淆技术只是保护了解密模块免于被杀毒软件发现,而病毒剩下的部分则全部是由加密技术进行保护的。

本文摘自:《软件加密与解密》

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14730899/viewspace-722964/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-07-02

  • 博文量
    52
  • 访问量
    92551