自6月27日以来我们一直在调查新Petya-like恶意软件配备了类似“想哭”的感染病毒。从第一天开始,各种相互矛盾的理论开始出现。一些人认为这个恶意软件是对原始Petya的剽窃,而另一些人则认为这是Petya进化的又一步。然而,这些只是不同的观点,没有一个有足够的证据支持。在这篇文章中,我们将通过逐步比较当前内核和它所基于的内核(《黄金眼》在内的邦德系列多么凄厉).

样品分析:

为什么知道代码是否被重新编译很重要?

回答这个问题并收集足够的证据对于进一步讨论归因至关重要。原始Petya的源代码从未被公开泄露过,所以如果重新编译,就证明原始Petya的作者Janus与当前的疫情有某种联系(这要么是他的作品,要么是他把代码卖给了另一个演员)。

在这个分析中,我们希望确定这个恶意软件是否可以从原始代码重新编译,或者它只是一个具有适当技能的人修改现成的二进制文件的工作。这样做不会完全否定Janus作为创造者,但他的参与变得不太可能。

不管怎样,让我们看看代码。

行业

看看这些区域,我们可以发现EternalPetya和Goldeneye的布局是一样的。完整的比较:

彼佳内核:

  • 彼佳:1区
  • Petya永恒:第1区

数据部门:

  • 彼佳白颊鸭:32
  • 彼佳永恒:32

验证部门:

  • 彼佳白颊鸭:33
  • 彼佳永恒:33

原MBR (xered 7)

  • 彼佳白颊鸭:34
  • 彼佳永恒:34

十六进制的比较

比较两种内核在十六进制层次上的差异,我们可以看到在不同的点上有微小的差异。然而,在这两个版本中,有很大一部分代码是相同的。

下面的截图显示了(当前的)EternalPetya的碎片在左边,Goldeneye在右边。

有趣的是,在某个点上,相同字符串在内存中的布局发生了变化:

如前所述,在这两种情况下,数据扇区从相同的偏移量开始。这个区域存储随机的Salsa20密钥和nonce,每个受害者都会生成,这两种情况都是一样的。然而,在Goldeneye中,受害者的ID要长得多,考虑到过去它被认为是Salsa密钥的加密备份,而现在它只是一个任意字符串,所以它的长度并不重要,这一点也不奇怪。

引导装载程序

让我印象最深刻的是引导加载程序。hexdump的片段(如前所述:EternalPetya在左边,Goldeneye在右边):

在功能方面,这两种情况是相同的。从扇区1开始,它从磁盘读取32个扇区(0x20),并将它们加载到地址0x8000的内存中。然而,在这两种情况下执行相同操作所使用的操作码有一点不同。

这是Goldeneye中使用的旧引导加载程序:

这是EternalPetya版本中使用的引导加载程序:

我看到这个的第一印象是,代码被重新编译了不同的设置,然而,另一种可能性也存在。不同片段的总长度是相同的——因此,我们不能排除有人在预编译的二进制文件中手动编辑它们的可能性。

优化——以及为什么它很重要

到目前为止,我们已经看到了一些有趣的变化,但它们还不足以证明代码是否被重新编译。然而,这项研究的突破可能在于大卫·布坎南

他的理论基于编译器优化,确保相同的字符不需要加载到内存两次。我们可以看到该规则应用于检查负责在内存中存储字符串的代码。在Goldeneye的关键扩展函数中,我们可以发现这种优化绝对会发生——每个角色都是唯一的,没有角色被加载两次:

但是在当前内核的相应片段中,我们可以发现这个规则被打破了。字符' d '重复和优化没有应用:

如果编译器生成了相同的代码,则该片段看起来与其他重复字符相同:

mov [bp+var_B], al

这是一个非常有力的论据,反对重新编译代码的理论。但不管怎样,让我们继续分析,看看能否找到更多的证据。

仔细看看这些变化

在一个以前的文章在IDA插件BinDiff的帮助下,我给出了当前内核与Goldeneye的快速比较:

我们可以看到,仅在与显示信息屏幕相关的功能上进行了重大修改。让我们检查一下这些更改是如何应用的。

main_info_screen(抵消0 x8426):

BinDiff指出main_info_screen的变化(左:current,右:Goldeneye):

正如我们所看到的,对0x008848E上的函数的调用被nop (No Operation)替换了。这是一种常见的做法,用于在为已编译的二进制文件打补丁时删除不需要的函数。然而,有时它也可以通过#Ifdefs引入。即使使用相同的偏移量,其余的代码也与以前的版本匹配。但是,显示字符串的地址在两个二进制文件中都是不同的。

未引用的函数仍然存在于当前二进制文件中:

在代码的其他地方调用:

与Goldeneye的呼叫图相比,它缺少一个参考点,但其他参考点是一致的:

sub_86E0(抵消0 x86e0):

第二个变化是另一个函数,它也是信息屏幕的一部分。它不会从代码中的任何其他地方引用:

正如我们所看到的,它在前面讨论的函数的开头被调用:

在Goldeneye内核中,相应的函数负责印刷头骨

第一次跳转将导致负责显示骷髅并等待用户按下按键的循环。代码片段:

查看EternalPetya代码,我们几乎可以肯定这个函数是在编译后打了补丁,而不是重新编译。第一次跳转,本应导致循环直接导致函数结束:

原始代码仍然在二进制文件中,但它永远不会被引用(死代码)。

补丁是可逆的吗?

我认为,作为这项研究的最后一笔,逆转这些变化并让死去的代码起死回生会很有趣。作为输入,我使用转储代码:

我的版本(反向补丁):(7957520271 edf003742db63fc250c231).

事实上,在应用补丁后,我们又看到了同样的闪烁屏幕,只是头骨不见了(相应的字符串被覆盖了):

结论

我认为现在提供的证据足以证明,代码不是从原始源代码重新编译的(与我最初怀疑的相反)。因此,最初的彼佳作者的参与,雅努斯,似乎是不可能的。在这种情况下,他似乎只是被某个不同的演员选为替罪羊。

在代码中进行的编辑都是精心制作的——编写这些代码的人对汇编很熟练,并且确切地知道要修改什么以及为什么要修改。因此,它给人的第一印象是非常整洁和干净的修改,这可能是代码重新编译的结果。然而,在做了更深入的分析之后,我们发现了许多不同的细微差别。

EternalPetya似乎是由从各种来源窃取的代码拼接而成的。除了GoldenEye Petya内核的修改版本外,我们还可以从“Eternal”系列中找到泄露的NSA漏洞,以及PsExec等合法应用程序。

在没有经验的参与者(scriptkiddies)中,窃取和重新使用别人的代码是一种常见的做法。然而,在这种情况下,合成是由一个具有良好技术知识和细心执行的人或团队完成的。使用这么多偷来的元素的一个可能原因,除了节省演员的时间,可能是为了摆脱任何明显的归因迹象。

关于这个恶意软件仍然有许多谜题需要解决,它创造了许多理论,直到被证明是正确的,不过是猜测。

附录

读也:

永恒的彼佳和丢失的萨尔萨20钥匙

此视频无法显示,因为您的功能性饼干目前禁用。

请访问我们的隐私政策并搜索cookie部分。选择“点击这里”打开隐私偏好中心并选择“功能性饼干”在菜单。您可以将选项卡切换回“活跃”或通过移动TAB来禁用“不活跃”。点击“保存设置”。


这是一篇由Hasherezade撰写的客座文章,他是一个对InfoSec有浓厚兴趣的独立研究员和程序员。她喜欢详细介绍恶意软件,并与社区分享威胁信息。看看她的推特@hasherezade以及她的个人博客:https://hshrzd.wordp