杀毒软件(AV)是一个较大规模安全防护策略的重要组成部分,能够减缓恶意软件在互联网上的传播速度。这就像一个农场主保护自己的牲畜一样。一个聪明的农场主会在生物威胁出现之前给很多牲畜接种这方面的疫苗。即便是有一只牲畜被感染,它与其他未接种疫苗的牲畜的接触会被降低。由此一来,该生物威胁就会在造成极小损失的情况下自行消除。一个没那么谨慎的农场主可能只会给一小部分的牲畜接种疫苗。由此一来,一旦有一只牲畜被感染,感染就会在牲畜之间快速蔓延,进而造成灾难性的损失。
杀毒软件就像接种一样,而连通互联网的计算机和设备就是牲畜。当恶意软件等新威胁出现后,一个疫苗或签名就会被创建来识别这种威胁并注射到所有客户端中,进而大幅降低一个未接种疫苗的客户端与感染接触的可能性。
不过这一系统意味着在“解药”研制出之前还是造成了损害,从而使得杀毒软件在抵御威胁方面显得必要但不足够。要想针对某个威胁对一个目标进行接种,就必须知道这个威胁。因此,在研发出疫苗对客户端进行保护之前至少会有一小部分的客户端被感染。这是一个很多杀毒软件供应商都不会突出强调的事实。此外,尽管这是一个常识,客户通常也不会认识到这一常识,既因为杀毒软件在长达几十年的时间里已经成为了一个行业标准,又因为杀毒软件在早些年被认可为解决这一问题的良方妙招。
近期,我对杀毒软件以及恶意软件检测策略进行了讲解演示以帮助突出强调这一担忧 ,并承认每天都会有未识别的新威胁进入网络,进而无可避免地造成一些损害。为了对此进行演示,我特意编写了一个恶意软件,旨在作为一个命令与控制(C&C)僵尸程序(bot)进行运行。它将接收来自攻击者的指令并在受感染的机器上以最高的优先级对这些指令进行执行。
很多的现代攻击都需要大量的独立机器。比如,一次分布式拒绝服务(DDoS)攻击需要互联网上成千上万台机器在同一时间访问同一网站,从而让服务器过载死机。一个命令与控制僵尸程序能够完美地帮助完成这种类型的攻击。攻击者可能不知道僵尸程序最终的用途是什么,不过如果僵尸程序被设计得足够灵活和通用,它们就很容易被扩展,从而在无需发起一个新的恶意软件传播活动的前提下发起新的攻击。事实上,攻击者可以拥有和控制互联网上数万台独立计算机并利用这些计算机来实施他们想要实施的任何行动。在安全领域之外的其他领域有很多正派的研究人员会乐意付出任何代价以拥有如此强大的资源场,特别是在不需要为此付钱的情况下。
有了这个特意编写的恶意软件,我便开始了解现代的杀毒软件客户端在面对未知威胁时的有效程度。此时,还没有杀毒软件供应商有机会见到恶意软件代码,因此也就没有机会为其编写签名。这就让众多的杀毒软件供应商有些为难。要想提供任何形式的保护,就必须采用不依赖对某个特定威胁编写签名的创新检测策略。
这时候一种名为“代码模拟”的技术就派上用场了,而这一技术也被众多的杀毒软件解决方案所采用以帮助弥补签名的不足。代码模拟是一些较为高端的杀毒软件客户端所采用的用来识别恶意应用程序的创新策略之一,即便是这些恶意应用程序此前从未被发现过。并不是所有的杀毒软件客户端都使用这一技术。一些杀毒软件客户端会使用一些替代技术,有些杀毒软件客户端在使用替代技术的同时也会使用代码模拟。我选择了一些拥有最大市场份额的流行杀毒软件客户端对我特意编写的病毒进行了测试。在理想状态下,所有这些客户端都应该使用了此类策略。不过从实际情况来看,我发现我测试的八家杀毒软件供应商中只有一家杀毒软件供应商能够检测到我特意编写的这个恶意软件。
事实上,这并不是一个特别糟糕的结果。测试结果表明,至少有一家杀毒软件供应商能够检测出一个所有杀毒软件供应商都未曾见过的恶意软件,这至少意味着该恶意软件相对来说能够很快地被检测到。一旦恶意软件被至少一家杀毒软件供应商在至少一台客户端机器上检测到,该恶意软件通常会被分享给所有其他的杀毒软件供应商以便大家能够发布签名对此进行防护。不过在恶意软件碰到来自那家杀毒软件供应商的那个杀毒软件客户端之前,在那家杀毒软件供应商跟其他人分享之前,一些附带损害又会再一次出现。
在恶意软件攻击者看来,即便是被一家杀毒软件供应商检测到,这也意味着他们的恶意软件将不会持续太久,而恶意软件持续的时间越长,他们所获得的价值也就越多。因此我继续对恶意软件作者让其恶意软件无法被所有已知的杀毒软件客户端所检测的过程进行了演示。由于这个特定的病毒只是被一家杀毒软件供应商所检测到,要做出的努力也不会太多。
代码模拟的工作原理是在杀毒软件应用程序里创建一个微型虚拟机,在这个微型虚拟机里,可疑的恶意软件可以安全地被执行。模拟器会记录这个可疑的恶意软件所实施的一切操作,并使用启发式行为模式来确定这些行动是否代表恶意代码。比如,如果在微型虚拟机里执行一个文件时,模拟机注意到它被设计为添加一个指向回收站里的一个可执行文件的‘自启动’注册表项,它便可以较为准确地认为可疑的文件实际上就是一个恶意软件。这是因为恶意软件经常会添加自启动表项。一个正规的自启动表项绝不会指向回收站里的任何东西,因为这些文件并不能够保证长期存在。另一方面,如果在执行可疑的恶意软件之后,所观察到的行动只是一些拥有很多动画的对话,杀毒软件可能会认为这是一个游戏,不太可能是恶意的。
检测到我特意编写的病毒的这家杀毒软件供应商确实采用了代码模拟。当它观察到我特意编写的病毒被放到系统上之后,它自动在其代码模拟环境中对其进行了执行并对其将要采取的行动进行了分析。由于这是一个病毒,它自然而然地需要编写注册表项、下载文件、隐藏文件等等,而杀毒软件则正确地将此行为认定为恶意行为。
不过,恶意软件作者是很聪明的,他们一直在适应新的检测策略。在遵循恶意软件创造过程的前提下,我接着开始琢磨如何让代码模拟器认为文件不是恶意的。
这一过程涉及了对杀毒软件客户端进行的一些琐碎的逆向工程。我不是说要对二进制进行拆解,也不是说要对内存进行查看,而是一个简单的真假实验和误差检测方法。该方法涉及在恶意软件中额外添加一些代码,以试图检测该恶意软件是否被模拟,并且如果是的话,让该恶意软件在做出任何可疑举动之前放弃行动。如果对模拟器的检测能够正常工作的话,杀毒软件客户端就不会将文件报告为恶意文件。如果检测失败的话,杀毒软件客户端就会将文件报告为恶意文件。
整个过程花了大概一个小时左右的时间,直到第一个成功的躲避策略被识别出来。在此过程中我了解到,这家杀毒软件供应商的代码模拟器在认定程序可以安全运行之前只愿意模拟有限数量的指令和时间。为了利用这一限制,我对测试恶意软件的代码进行了修改,从而让其在运行恶意代码之前运行一个由八万个指令组成的循环。由此一来,这个杀毒软件客户端就会耗费整个的时间限度尝试通过病毒顶端的一个忙碌循环,因而没有足够的时间到达真正具有恶意行为的代码行数。结果就是恶意软件没有被检测出来。
我只利用了一种检测方式来检测我特意编写的恶意软件是否是在一个模拟器中运行,不过我还知道至少六种绕过防护的独立方法。这七种技术使得恶意软件能够躲避杀毒软件供应商的检测。我不是说这些技术代表了突破研究或零日漏洞。事实上,这些技术以及成百上千的技术在近五年来恶意软件作者所使用的论坛中都有很好的记录。
我之所以进行这次研究,之所以要向大家展示这次研究,就是希望大家能够关注可能出现的最初附带损害。我发现,要想让任何已有或新出现的恶意软件变成当今市面上所有杀毒软件客户端都无法检测出的恶意软件是非常简单的事情。我希望这能够增强人们的意识,那就是杀毒软件不是万能的。尽管杀毒软件在防止恶意软件长期传播方面有着巨大价值,但它却无法保护网络免受即便是稍微聪明一点的恶意软件作者的攻击。
那么,当网络管理员发现他们多年以来依赖的工具并不能真正防止攻击者对他们的公司造成重大损害时,他们应当做些什么呢?首先,继续使用客户端杀毒软件。尽管杀毒软件不能检测到一个全新的病毒或一个精心设计的病毒变体,但杀毒软件是病毒出现几天后防止病毒大规模扩散的唯一一道防线。要考虑到损害控制,而不是损害预防。
实际上,对新出现威胁的最佳防御要在与将更多的高级解决方案叠加在一起。新出现的恶意软件检测方面的新创新能够在不使用签名的情况下对恶意软件进行检测。这意味着它们不需要事先知道威胁。与代码模拟最为相似但又比代码模拟更加强大、更难以躲避的是沙箱这一理念。沙箱解决方案的设计旨在一个逼真的客户端环境中对可疑文件进行执行。由此一来,恶意软件将无法将测试环境和真实用户目标区分开来。这使得沙箱能够更加准确地对可疑文件进行分析,从而观察它将在终端用户的系统上做些什么。此外,文件和URL信誉跟踪以及机器学习策略等解决方案将增添更多的效率。
此外,利用包含快速实时情报共享的产品也很重要,这样能够尽可能地缩短恶意软件发布和签名保护之间的时间。云安全服务是关键。如果恶意软件作者不得不在杀毒软件供应商自己寄存的黑盒检测解决方案中对他们的恶意软件进行测试,那么他们在识别成功的躲避策略方面要变得困难的多。
通过将客户端杀毒软件、网络杀毒软件、沙箱、代码模拟以及声誉服务组合在一起,管理员能够构建一个更加强劲的防护策略。拥有一个强劲的反恶意软件解决方案可能真的能够阻止未来的定向恶意软件攻击。尽管如此,管理员还是要留心网络中的恶意软件检测率,以便对定向攻击进行早期识别和严密监控。如果一个攻击者真的是攻击某家公司,要想防止攻击者成功实施攻击,就不得不进行大量人工干预,而关键就在于要知道什么时候需要进行人工干预。
一切都还来得及,不过这场战争会一直打下去。如果我们希望在未来不被打败,那么我们就必须保持勤奋,根据威胁对我们的保护策略进行改进。而那些跟不上战争节奏的人们将一次又一次地遭受重创。