独家连载 | 零日漏洞:震网病毒全揭秘(44)
作者: 日期:2015年11月11日 阅:4,528

640.webp

想破解攻击PLC的代码,首先要将二进制机器语言反汇编,得到用PL7语言编写的代码,再将其反编译成STL语言编写的代码,再解析出其中各个函数的功能。但是,钱哥他们既看不懂PL7,也看不懂STL,西门子和朗纳还不搭理他。这可怎么办?……

第十三章 数字弹头

连续伏案工作了两个小时,莫楚又累又烦。他不知疲倦的把一片又一片虚拟硬件“插进”Step 7模拟器中,孤注一掷的努力找出震网的攻击目标,但不幸的是,他一无所获。

这是2010年10月初,几周之前,拉尔夫·朗纳已经成功识别出,震网是针对单一特定目标的精确制导武器。此刻,德国汉堡和美国加州的两个团队仍然没有任何交集,也不知道对方的存在,却在同时埋头研究同一个问题:震网的目标到底是谁?

赛门铁克的研究员发现,震网在将具有破坏力的载荷释放到315型PLC之前,会对集成在PLC内部的数据段进行搜索,寻找3个由数字和字母组成的“神秘数值”(16进制值)。震网感染PLC后,先在这些数据段中寻找“2C CB 00 01”“7050h”和“9500h”,只有同时找到这3个值,才会确认这就是它要找的目标。

钱哥在Google上搜了一下,但没有发现它们和震网之间有什么联系。他们怀疑,第一个值可能是与PLC连接(受其控制)的某个硬件设备的序列号,莫楚为此专门搭建了一套Step 7 PLC的模拟环境,想要确定这个未知设备的身份。Step 7系统具有内置的模拟器,可以在PC上构建一个虚拟的PLC网络,这样,用户就可以在构建工厂中的真实环境之前,对不同的硬件配置进行测试。模拟器中有一个很长的硬件设备清单,用户可以通过点击菜单中硬件名称的方式,对虚拟设备进行“插拔”操作。用户每选中一个选项,相应设备的ID号就会显示在屏幕上。但是,两个小时过去了,他们按照列表上的顺序,依次插拔了100多种设备,还是没有找到与这个值相匹配的设备。莫楚开始感觉有点不对了。幸好他没放弃。当他点到一大堆“现场总线卡”和“现场以太网卡”(用于PLC和受其控制设备之间通信)时,运气终于来了。莫楚在“现场总线CP 342-5卡”的条目上,看到了这个值。

然而,确定现场总线卡还远远不够。他还是不清楚PLC控制的是什么设备。在这个进展的鼓舞下,他快速的把清单中剩余的所有设备都“插拔”了一遍,不过第二个和第三个值没有出现。不要紧。反正已经有所斩获了。他们现在已经知道,震网正在寻找一个插着6块现场总线卡的系统,还知道胜利就前方不远处,向他们招手。

640.webp (47)

现场总线CP 342-5卡

震网曝光3个月后,公众已经知道这段代码的目标位于伊朗境内。但是,至于目标到底是不是纳坦兹铀浓缩项目,仍然只是个假说。赛门铁克的3人组就快要从代码中找到相关证据了。但首先,他们得先上一个关于PLC的蓝翔速成班。

对于法里尔和他的同事来说,对震网意在破坏西门子PLC的发现绝对称得上是个重大突破。但朗纳的猜测是对的,他们在接下来的研究中碰钉子,这钉子就是PLC。“我们发现,根本什么都看不懂!”钱哥着急的说。

这时,法里尔发现,震网的载荷不是一个,而是两个!震网像特战突击队员一样,手握“双枪”,每一把枪瞄准一个PLC。一个目标是西门子S7-315型PLC,一个是S7-417型PLC。

侵入每个PLC的恶意代码只有区区几千字节,却是破解震网最大谜题的关键。挡在他们面前的只有一个问题——他们谁都看不懂这段代码的语言和格式。震网导弹部分代码,用的是最常见的C和C++语言,适用于因特尔的x86系列计算机。但这两个数字弹头,用的却是一种名为STL的西门子PLC专用编程语言,晦涩难懂。工程师要对PLC编程,首先要用STL语言编码,然后将其编译为一种名为PL7的汇编语言,最后在汇编成PLC可以直接执行的二进制机器语言。这意味着,即便法里尔把这些二进制代码经过反汇编,转换成PL7语言,仍然无法理解它的意义。这有点像破解中情局著名的克里普托斯(Kryptos)雕塑上用希腊语写出的密文。赛门铁克在8月17日发出的声明中明确提出,希望具有PLC和STL语言方面知识的人与公司取得联系、合作破解震网,但没有人回应。

640.webp (48)

中情局克里普托斯雕塑上的密文

如果西门子公司愿意帮忙,他们就不用向公众寻求支援了。但现实并不如意。之前,在他们分析破解震网的几个月里,钱哥曾联系过西门子公司。但每当他问到与Step 7系统如何工作有关的问题时,回复就变得异常缓慢,少则几天,多则几周。通常,等不到西门子回复,赛门铁克就已经把问题解决了。

实际上,还有另外一个团队可以给他们提供帮助,那就是朗纳团队。如果他们两家联手,可以说是天下无敌——赛门铁克最擅长在Windows系统上对恶意代码进行逆向工程,而朗纳团队在西门子工控软件和PLC方面具有最丰富的知识技能。但是,一封简短的邮件和几番博客上的互动,却让他们对彼此产生了误会,合作也无从谈起了。实际上,造成误会的只是沟通过程中的某次小小失言,一个电话就能挽回局面,但这两家都是傲气冲天,谁都不愿意打这个电话。

在没有外界援助的情况下,赛门铁克的研究员们别无选择,只好去买回来一大堆STL语言的书,硬着头皮自己啃。他们觉得,破解STL代码的最好办法,就是先学会怎么用这种语言编码。

每天早晚乘地铁时,法里尔都会埋头苦读,想要尽快看懂STL代码,但成效甚微。几天后,他偶然间发现了一种在线的开源工具,可以用来替代Step 7软件对西门子PLC编程。法里尔利用这种工具,可以看到STL在编译成MC7语言之后的状态,并通过这种方式,在STL语言和MC7语言之间搭建一个双向转换的桥梁,并借此反编译震网中用MC7语言编写的代码。

法里尔花了几个星期的时间,完成了对这段代码的反编译。震网注入PLC区区几千字节的二进制代码,暴涨为用于攻击315型PLC的4000多行指令,和用于攻击417型PLC的13000多行指令。对于法里尔来说,庞大的规模、复杂的结构和生僻的格式不仅难以阅读,而且几乎无法理解。于是,他决定把这些代码翻译成他能看懂的语言,比如C语言。但是,翻译过来后,他只能对代码进行静态分析,而不能把它加载到PLC上进行动态分析。因此,他又编写了一个小程序,在Windows系统上模拟PLC,然后载入翻译后的代码。经过此番折腾,法里尔总算回到了自己熟悉的套路上,并顺利完成了弹头代码的破解。

代码中最令法里尔印象深刻的是,它包含一个由6个步骤组成的循环体,这个循环会反复执行几周甚至几个月。一旦感染成功,循环立即启动。这意味着,震网要做的,并非一击致命,而是长期而隐蔽的实施破坏。这完全超出了他们的预料。隐蔽的破坏,加上对监控系统的中间人攻击已经封死了向管理人员通风报信的渠道,让故障变得更加难以探测,确定故障原因更是难上加难。这时,法里尔意识到,攻击者希望暗中破坏可以一直持续至少几个月的时间,而且,他们真的做到了。

攻击的第一个步骤,是为期13天的侦察。期间,震网只是安静的记录着PLC的正常运行状态,以便在破坏开始后把“正确的数据”发送给管理员。震网记录的频率为每分钟1次,在完成约110万次记录之后,才会转入下一个阶段。

数据记录完毕后,将开始长达2小时的倒计时。倒计时结束,破坏正式开始。不过,破坏仅仅会持续15分钟。时间一到,破坏就会暂停,受PLC控制的设备重回正常运行状态。5小时后,攻击行动再次回到起点。这一次,震网会蛰伏大约26天,记下两倍于上次的数据。破坏再次启动,这次的持续时间是50分钟。之后,破坏持续时间在15分钟和50分钟之间交替变化,而侦察蛰伏期则始终是26天。

法里尔完全看不懂,为什么要给破坏持续时间设定为两个不同的值:15分钟和50分钟呢?而且,在弄清楚遭震网破坏的到底是什么设备之前,根本没办法找到答案。这就像是,在夜空中看到子弹呼啸而过,却不知道它打向何方。(待续)

译者:李云凡

 

关键词:

申明:本文系厂商投稿收录,所涉观点不代表安全牛立场!


相关文章