以自定义格式反转恶意软件|隐藏的蜜蜂元素
摘要: 恶意软件可以由许多组件组成。通常,都会遇到充当恶意下载程序的宏和脚本。一些功能也可以通过与位置无关的代码实现-所谓的shellcode。但是当谈到更复杂的元素或核心模块时,都几乎理所当然地认为它将是一个本机Windows可执行格式的PE文件。
恶意软件可以由许多组件组成。通常,都会遇到充当恶意下载程序的宏和脚本。一些功能也可以通过与位置无关的代码实现-所谓的shellcode。但是当谈到更复杂的元素或核心模块时,都几乎理所当然地认为它将是一个本机Windows可执行格式的PE文件。
原因很简单:在PE文件中提供复杂功能比在shellcode中提供复杂功能要容易得多。PE格式具有明确定义的结构,允许更大的灵活性。有一些标题可以定义应该加载哪些导入,以及应该如何应用重定位的位置。这是为Windows编译应用程序时生成的默认格式,然后Windows Loader使用其结构来加载和执行这些应用程序。即使恶意软件作者编写自定义加载器,它们也主要用于PE格式。
但是,有时就会发现异常。上次,当分析到与Hidden Bee相关的有效负载(由Underminer漏洞利用工具包丢弃)时,就发现了一些不寻常的东西。丢弃了两个没有遵循PE格式的有效负载。然而,他们的结构看起来组织得很好,比经常通常遇到的shellcode片段更复杂。所以决定仔细研究一下,发现这个恶意软件的作者实际上是按照一致的结构创建了自己的可执行格式。
概观
第一个有效载荷:b3eb576e02849218867caefaa0412ccd(扩展名为.wasm,模仿Web Assembly)是一个加载器,下载并解压缩一个Cabinet文件:
第二个有效载荷:11310b509f8bf86daa5577758e9d1eb5,从内阁拆包:
现在首先可以看到,与大多数shellcode相反,它不是从代码开始,而是从一些标头开始。比较两个模块,我们可以看到在两种情况下头部具有相同的结构。
头部
先仔细研究了解读标题中特定字段的含义。
第一个DWORD:0x10000301在两者中是相同的。然而没有找到与该模块中任何部分对应的数字。因此,就假设它是一个神奇的数字,它构成了这种格式的标识符。
接下来,两个WORD是与加载导入相关的元素的偏移量。第一个(0x18)指向DLL列表。第二个块(0x60)起初看起来更神秘。当加载在IDA中模块的时候,可以理解它的含义。就可以看到对这些字段的交叉引用:
然后看到它们被用作IAT-它们应该填充导入函数的地址:
下一个值是DWORD(0x2A62)。如果继续在IDA中遵循它,我们会看到它导致新函数的开始:
任何其他函数都不会引用此函数,因此可以怀疑它是程序的入口点。下一个值(0x509C)的含义很容易猜到,因为它与完整模块的大小相同。然后,还有标题的最后两个DWORD。第二个DWORD(0x4D78)导致结构与PE的重定位非常相似。还可以猜测它必须是模块的重定位表,而前一个DWORD指定它的大小。
这就是如何重建完整的标题:
入口
正如从头部知道的那样,DLL的列表从偏移量0x18开始。可以看到每个DLL的名称前面都有一个数字:
这些数字与DLL名称不对应:在两个不同的模块中,相同的DLL分配了不同的编号。但如果总结所有数字,发现它们的总和与IAT中的DWORD数相同。因此,就可以做出有根据的猜测,这些数字是指定从特定DLL导入的函数数量。
还可以将其描述为以下结构(未指定名称的长度):
然后,IAT作为DWORD列表:
恶意软件中常见的是,当函数的名称不是作为显式字符串给出时,它们是通过校验和导入的。在这种情况下也是如此。猜测用于计算校验和的适当函数可能更困难。幸运的是,在loader组件中找到了它:
知道使用函数的名称配对了适当的校验和:
一旦检索到函数的地址,就将其存储在IAT中以代替校验和。
重新定位
创建重定位表很简单。它由DWORD列表组成,这些DWORD标识代码中的位置的偏移量,应该在其中添加模块已加载的基础。如果不应用重定位,模块将崩溃(因此,它不像典型的shellcode那样与位置无关)。
与PE格式的比较
虽然PE格式很复杂,但有各种标题,这个标题只包含必需品。这里通常完全省略了通常存储在PE头中的大多数信息。
你可以在这里看到Ange Albertini可视化的PE格式。
将其与当前分析格式的可视化进行比较:
静态分析
还可以将此代码作为一大堆原始代码加载到IDA中。但是,还缺少重要信息。由于文件不遵循PE结构,并且其导入表是非标准的,因此是很难理解在哪个偏移量处进行哪些API调用。为了解决这个问题,创建了一个工具,将哈希解析为函数名,并生成一个TAG文件来标记每个函数地址将被填充的偏移量。
可以使用IFL插件将这些标记加载到IDA中 :
标记所有API函数后,更容易理解模块执行的操作。例如,在这里,就可以看到它将与C2服务器建立连接:
动态分析
此格式是自定义的,因此典型的分析工具不支持此格式。但是,在了解它之后,你就可以编写自己的工具,例如头文件和加载器的解析器,它将有助于运行此格式并动态分析它。
与PE相比,该模块没有任何部分。因此,需要使用RWX(读写-执行)访问将其加载到连续的内存区域中。遍历重定位列表,还将添加模块的基础值添加到列出的地址。然后,还必须通过哈希解析导入的函数并填充thunk中的地址。准备好舞台后,只需要跳到模块的入口点即可。
总结
这里描述的元素非常简单-它们作为完整恶意软件包的第一阶段,下载其他部分并将其注入进程。然而,令他们感兴趣的是他们的作者展示了一些创造力,并决定发明一种比完全成熟的PE更简单的自定义格式,但比典型的shellcode更进一步。
与独立的shellcode相比,这样的模块不是自给自足的,不能以微不足道的方式加载,但必须先进行解析。鉴于格式是自定义的,现有工具不支持。对于恶意软件分析师来说,这就是编程技巧派上用场的地方。
幸运的是,完全自定义格式在恶意软件世界中并不常见;通常,作者严重依赖现有格式,不时腐蚀或定制PE标题的选定部分。
(作者:曲速未来安全区,内容来自链得得内容开放平台“得得号”;本文仅代表作者观点,不代表链得得官方立场)
评论(0)
Oh! no
您是否确认要删除该条评论吗?