自6月27日以来我们一直在调查新Petya-like恶意软件配备了类似“想哭”的感染病毒。从第一天开始,各种相互矛盾的理论开始出现。一些人认为这个恶意软件是对原始Petya的剽窃,而另一些人则认为这是Petya进化的又一步。然而,这些只是不同的观点,没有一个有足够的证据支持。在这篇文章中,我们将通过逐步比较当前内核和它所基于的内核(《黄金眼》在内的邦德系列多么凄厉).
样品分析:
- 71年b6a493388e7d0b40c83ce903bc6b04-主DLL
- f3471d609077479891218b0f93a77ceb-底层部分(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版本中使用的引导加载程序:
我看到这个的第一印象是,代码被重新编译了不同的设置,然而,另一种可能性也存在。不同片段的总长度是相同的——因此,我们不能排除有人在预编译的二进制文件中手动编辑它们的可能性。
优化——以及为什么它很重要
到目前为止,我们已经看到了一些有趣的变化,但它们还不足以证明代码是否被重新编译。然而,这项研究的突破可能在于大卫·布坎南.
萨尔萨20键的扩展是用魔法编辑器修改的,而不是修改源pic.twitter.com/Q06ZEle8k9
——大卫·布坎南(@David3141593)2017年6月29日
他的理论基于编译器优化,确保相同的字符不需要加载到内存两次。我们可以看到该规则应用于检查负责在内存中存储字符串的代码。在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代码,我们几乎可以肯定这个函数是在编译后打了补丁,而不是重新编译。第一次跳转,本应导致循环直接导致函数结束:
原始代码仍然在二进制文件中,但它永远不会被引用(死代码)。
补丁是可逆的吗?
我认为,作为这项研究的最后一笔,逆转这些变化并让死去的代码起死回生会很有趣。作为输入,我使用转储代码:
- EternalPetya内核+引导加载程序(f3471d609077479891218b0f93a77ceb).
我的版本(反向补丁):(7957520271 edf003742db63fc250c231).
事实上,在应用补丁后,我们又看到了同样的闪烁屏幕,只是头骨不见了(相应的字符串被覆盖了):
结论
我认为现在提供的证据足以证明,代码不是从原始源代码重新编译的(与我最初怀疑的相反)。因此,最初的彼佳作者的参与,雅努斯,似乎是不可能的。在这种情况下,他似乎只是被某个不同的演员选为替罪羊。
在代码中进行的编辑都是精心制作的——编写这些代码的人对汇编很熟练,并且确切地知道要修改什么以及为什么要修改。因此,它给人的第一印象是非常整洁和干净的修改,这可能是代码重新编译的结果。然而,在做了更深入的分析之后,我们发现了许多不同的细微差别。
EternalPetya似乎是由从各种来源窃取的代码拼接而成的。除了GoldenEye Petya内核的修改版本外,我们还可以从“Eternal”系列中找到泄露的NSA漏洞,以及PsExec等合法应用程序。
在没有经验的参与者(scriptkiddies)中,窃取和重新使用别人的代码是一种常见的做法。然而,在这种情况下,合成是由一个具有良好技术知识和细心执行的人或团队完成的。使用这么多偷来的元素的一个可能原因,除了节省演员的时间,可能是为了摆脱任何明显的归因迹象。
关于这个恶意软件仍然有许多谜题需要解决,它创造了许多理论,直到被证明是正确的,不过是猜测。
附录
读也:
这是一篇由Hasherezade撰写的客座文章,他是一个对InfoSec有浓厚兴趣的独立研究员和程序员。她喜欢详细介绍恶意软件,并与社区分享威胁信息。看看她的推特@hasherezade以及她的个人博客:https://hshrzd.wordp
评论