一个信息偷窃软件的研究案例(二)

      一个信息偷窃软件的研究案例(二)无评论

介绍

在这第二部分的分析中,我们将会研究Pony如何偷窃数据,并且如何发送给C&C服务器。我们同样对Pony在结束执行之前是否做了痕迹清除很感兴趣。

前一部分,我们研究到一个单词列表的解密过程,我们看看样本接下来会干什么。

准备窃取信息

在真正开始调用从硬盘中收集软件信息的函数之前,Pony调用了WSAStartup函数来初始化Winsock DLL。然后它申请了一个OLE stream(与我们在第一部分看到相似),这个stream会用来存储某些类型的数据。调用位于0×00410772处的函数,并把stream的指针作为参数传入。

样本下一步做的事情很有趣,它把字符串“PWDFILE0”和“1.0”保存到了stream中。这两个字符串作为这个缓冲区的头部,在每次对缓冲区进行加密的时候,这个头会变化,以标识这个缓冲区里的内容。Pony使用的缓冲区头部如下:

   PWDFILE0

    PKDFILE0

    CRYPTED0

在保存完数据前面的头部之后,Pony会仔细地搜索系统中的口令。在这之前,Pony还会使用IsDebuggerPresent的inlined版本来检查是否有调试器。

一个信息偷窃软件的研究案例(二)

如果检测到了调试器,将会调用0×00401026处的函数,它会抛出一个异常。这是非常容易实现和绕过的技术。因此,它不会给我们造成任何问题。

现在,样本会把回调函数表的地址加载到EDI寄存器,然后进入一个循环,一个一个地迭代调用里面所有的函数。回调函数表位于0x00417D03处,包含134个函数。

一个信息偷窃软件的研究案例(二)

回调函数表里面的第一个函数

值得一提的是,这里面每一个回调函数都需要一个参数,这个参数不是其它,就是之前分配的stream的指针。现在,我们可以肯定得说,这里面的每一个函数都会往stream里面写某些东西。我们可以随机得查看看表里的函数,这些回调函数的功能实际上是从硬盘中偷窃数据并把他们保存在stream中。

一个信息偷窃软件的研究案例(二)

回调表中函数的反汇编代码

正如我在第一部分提到的,我们不会深入研究这里的每一个函数。但是,我们会仔细查看表里的第一个函数,因为它在stream中保存了一些我们感兴趣的信息。这个函数位于0x004044A0处。

查看0x004044A0函数(Callbacks[0](stream))

这段程序首先拷贝8个字节到stream中(02 00 4D 4F 44 55 01 01)。之后,它会单独添加4个字节(01 00 EF BE)。接下来,它调用了两个API函数GetVersionExA和GetLocalInfoA,并且把他们的返回结果保存到stream中。

在保存了Windows的版本和位置信息之后,它尝试通过收集机器的硬件ID来标识这台机器。这对于跟踪信息来源于哪个机器很有用,因为使用非特殊的标识,比如IP地址,是不可靠的。

为了获取硬件ID,样本首先检查机器是否安装了Winrar,然后从注册表键:HKEY_CURRENT_USER/Software/WinRAR中读取HWID键值,因为Winrar把机器的HWID保存在了注册表中。

如果机器没有安装Winrar怎么办,这是个问题。样本会获取当前用户的AppData/Temp目录,搜索一个名为HWID的文件。如果文件找到了,Pony就会读取其中内容并当做机器唯一的硬件ID。然而,在我测试样本的机器上没有这个文件,Pony选择了最后一种方案,生成一个随机的唯一的GUID来标识这个机器。用来生成GUID函数是CoGreateGuid。之后,样本拷贝HWID(或者前面的尝试都失败的情况下,为GUID)到stream中,这个stream中的内容会在做完所有窃取工作后发给服务器。

窃取信息

在这个阶段。恶意软件按预先设计工作,窃取信息。它迭代调用我们看到的回调函数表中的每一个函数,直到遍历完整个数组。Pony中回调函数的特征为:

检查要窃取信息的软件是否安装,如果没有则返回。

从文件和注册表键中收集信息。

把信息和应用程序的详细信息写入到stream中。

压缩数据

在调用完所有的回调函数之后,所有窃取的数据(如果有的话)都被保存在了一个全局数据stream中。在这个阶段,Pony获取将要发往服务器的数据,在这之前它还要完成一系列任务。首先,它压缩数据使之变小,这样就能更快地发往服务器。为了实现这一目标,它使用了aPLib v1.01库。它实际上是一个基于aPACK中的算法的压缩库。这个库是由原aPLib的作者创建的。

在压缩完数据之后,样本删除未打包压缩的数据并且把打包之后的数据写入到stream中。在这第二部分的第一节,我提到了数据之前有不同的头。它们被用于说明在stream中存储的数据是什么类型:是明文,还是打包或者加密的数据?

之前的头部指明了后面的数据是明文数据(PWDFILE01),现在数据被压缩了。所以,Pony所做的是插入另一个头,定义数据被打包压缩了(PKDFILE0),在内存中就像这样:

一个信息偷窃软件的研究案例(二)

准备加密数据

数据压缩完成之后就该加密了。负责执行加密数据过程的所有任务的函数位于0x004019E0处。

它所做的第一件事情是,把stream里的数据(以PDKEILE0头开始)拷贝到一个单独动态申请的内存中。Pony并不立刻处理拷贝的数据,所以我们稍后再回头看它。Pony所做的是计算一个硬编码的字符串“babajay@1234”的长度,实际上,我们在第一部分中已经看到Pony从字符串“dcdclc{B3456”中将之解密了出来,并且我们对这一行为的本质进行了猜测。

然后,一个257字节的数组被创建,并且通过下列方式被初始化。

buffer[0] = buffer[1] = 0;

for (int i=2;i<257;i++)

    {

        buffer[i] = i;

    }

在这一阶段,利用字符串“babajay@1234”通过类似于下列代码来加密字节序列:

UCHAR* key = “babajay@1234”,Sum = 0,Character;

         int j=0,i;

         for(i=2;i<257;i++)

         {

             Old = buffer[i];

             Sum += Old;

             Character = key[j];

             Sum += Character;

             buffer[i] = buffer[Sum];

             buffer[Sum] = Old;

             if (++j == strlen(key))

                 j = 0;

         }

最终生成的序列会被用来加密stream中的已打包压缩的数据。

010816_2003_ACaseStudyo5.png

用来加密stream中数据的字节序列

结论

在这第二部分中,我们看到了Pony是如何准备(位置,Windows版本和唯一的机器标识)并实施窃取信息任务的。我们同样揭露了它压缩和准备加密的具体细节。

在下一部分我们将真正看到Pony如何加密数据,如何发送数据,以及在完成目标之后还执行了什么任务。

样本链接,压缩包的密码是:pony

* 翻译自:resources.infosecinstitute ,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

8篇文章等级:4

这家伙太懒,还未填写个人描述!