刚才,卡巴斯基实验室发现了我们之前本应该发现的一些情况—-老版本的Stuxnet包含一个文件(atmpsvcn.ocx)而这个文件在本质上同样是Flamer的插件。除此以外,Stuxnet和Flamer在代码上难道就完全不同么?

我正在查看Stuxnet PLC的钩子dll,s7otbxdx.dll,因为我需要提取出PLC MC7的字节码对象并用于其他工作。出于娱乐的目的我在IDA中又运行了在我前一篇博客中提到的Flamer解码脚本,令我格外惊讶的是,解码脚本发现Flamer的字符串解码函数也在s7otbxdx.dll中。

flamedec: IDAPython Flamer decryption tool.
flamedec: (C) 2012 Snorre Fagerland, Norman ASA.
------------------------------------------------
flamedec: ANSI string decoder found at 10010bbf

来看一下代码,它们的相似性很明显了。Stuxnet的解码部分与Flamer都使用了同样的字符串存储格式,在偏移量8的位置是字节长度的加密标记,在偏移量9的位置是字长度的字符串长度,而字符串存储在偏移量为11的位置。在汇编语言中他们只有极小的差异,比如在解码后使用MOV代替AND来清除加密标记,但是从功能上来说他们是相同的。

点击图片查看完整对比图

跟进到解码循环的内部,我们看到它们在解码的功能实现上也是相同的。这是Stuxnet的版本:

void __cdecl Stuxnet__DecodeString(int a1, unsigned int a2)
{
unsigned int v2; // edi@1
v2 = 0;
if ( a2 )
{
do
{
*(_BYTE *)(v2 + a1) -= Stuxnet__GetKey(v2);
++v2;
}
while ( v2 < a2 );
}
}

下面是Flamer的解码部分:

void __cdecl Flamer__SOAPR32_DecodeString(int a1, unsigned int a2)
{
unsigned int v2; // edi@1
v2 = 0;
if ( a2 )
{
do
{
*(_BYTE *)(v2 + a1) -= Flamer__SOAPR_GetKey(v2);
++v2;
}
while ( v2 < a2 );
}
}

生成Key的函数对比如下:

点击图片查看完整对比图

它们看起来不同,但是事实上它们非常相似并且会生成相同的输出。为了这个例子,我升级了我的Flamer解码器并使用它对Stuxnet的一个组件进行解码:

flamedec: ANSI string decoder found at 10010bbf
flamedec: Found decoding algorithm type 6
flamedec: New decryption loop. Using decryption function at 10010bbf
flamedec: ------------------------------------------------------------
1004206c : DP_RECV
10042088 : s7otbxsx.dll
100420cc : 6ES7 417
100420ac : 6ES7 315-2
10042c64 : s7otbxdx.dll
10042c88 : CCRtsLoader.exe
10042dfc : SOFTWARE\SIEMENS\SINEC\LogDevices
10042e34 : CP_TYPE
10043574 : advapi32.dll
10043540 : InitializeSecurityDescriptor
10043510 : SetSecurityDescriptorDacl

事实上Stuxnet和Flamer并不只在文件组件上相似,它们还包含非常多的相似功能的实现,可以猜测这两个项目共享着一份相同的源代码。他们也许由不同的团队开发,但是如果真是这样,这些组织应该也能够使用公有资源。

小编:工业级的黑客攻击要逐渐走上舞台了,随着各国对网络安全的重视,越来越多的正规军开始出现,看来信息战已经成为各国国防发展中不可缺少的一部分了。

源链接

Hacking more

...