恶意软件开发档案解密之根据PDB路径和其他调试细节来推测相关的恶意活动(上)

luochicun 恶意软件 2019年9月16日发布
Favorite收藏

导语:本文将讨论通过PDB路径展示出的异常和其他恶意行为。

timg.jpg

你是否想过恶意软件开发者在开发时的最初想法是什么?他们如何构建他们的工具?他们如何组织他们的开发项目?他们使用什么样的计算机和软件?

通过探索恶意软件调试信息,我们尝试回答其中的一些问题。首先,我们发现恶意软件开发人员为所开发的文件夹和代码所起的名称,通常都明确的表明了其所包含的功能。因此,当使用符号调试信息编译恶意软件项目时,这些描述性名称将显示在PDB路径中。通过调试信息可以让我们深入了解恶意软件开发环境,虽然这些信息不显眼,但只要最够细心,我们可以使用PDB路径和其他调试细节来检测相关的恶意活动。

人机协议

数字存储系统彻底改变了我们的世界,但为了利用我们存储的数据并以有效的方式检索它,我们必须合理地组织它。为此,用户要仔细构建目录,并为文件和文件夹提供唯一的描述性名称。用户通常根据文件内容命名文件夹和文件,而计算机会强制用户根据数据类型,功能和目的标记和注释其数据。这种人机协议意味着大多数存储的数数据会具有一些明确的描述文件,同样,恶意文件也不例外。对于PDB路径尤其如此,它是恶意软件中描述开发环境的工具标记。

PDB

在编译时生成的程序数据库(PDB)文件,通常称为“符号文件”,它会存储关于程序的单个构建的调试信息。 PDB可以存储符号、地址、函数和资源的名称以及可以帮助调试程序找到异常或错误的确切来源的其他信息。

恶意软件就是软件,恶意软件开发人员就是软件开发人员。与任何软件开发人员一样,恶意软件开发者通常必须调试他们的代码,有时还必须在开发过程中创建PDB。如果他们没有花时间调试他们的恶意软件,他们的恶意软件就有可能无法在目标主机上正常运行,或者无法成功地与他们的恶意软件进行远程通信。

PDB路径是如何生成的?

但PDB如何创建并连接到程序呢?让我们通过恶意软件开发人员的视角来研究一个PDB路径的形成(以Smiller为例)。

Smiller有很多编程项目,并在他的计算机上以适当标记的文件夹结构进行组织。此项目用于嵌入在HTML应用程序(HTA)文件中的shellcode加载程序,可以看出,开发人员把它很有逻辑地存储在文件夹中:

D:\smiller\projects\super_evil_stuff\shellcode\

1.png

简单的“Test”项目代码文件“Program.cs”,它将一段shellcode和一个可执行的启动程序嵌入到HTML应用程序(HTA)文件中

2.png

通过Windows资源管理器看到的恶意Visual Studio解决方案HtaDotnet和对应的“Test”项目文件夹,文件夹和文件的名称则明确描述了它们的功能

恶意软件开发者然后在默认的“Debug”配置中编译他们的“Test”项目Visual Studio(图3),并将Test.exe和Test.pdb写入子文件夹(图4)。

3.png

默认编译配置的Visual Studio输出

4.png

Test.exe和Test.pdb被写入代码项目文件夹的默认子文件夹

在Test.pdb文件(图5)中,引用了源代码文件的原始路径以及用于调试的其他二进制信息。

5.png

Test.pdb包含二进制调试信息和对原始源代码文件的引用,以便在调试时使用

在编译期间,链接程序通过在IMAGE_DEBUG_DIRECTORY中添加一个指定调试信息类型的条目,将PDB文件与构建的可执行文件相关联。在本文的示例中,调试类型是CodeView,因此PDB路径嵌入在文件的IMAGE_DEBUG_TYPE_CODEVIEW部分下。这使调试器能够在调试Test.exe时找到正确的PDB文件Test.pdb。

6.png

PEview实用程序中显示的Test.exe,它可以轻松地从可执行文件的IMAGE_DEBUG_TYPE_CODEVIEW部分解析出PDB路径

CodeView调试信息中的PDB路径

CodeView结构

调试信息的确切格式可能因编译器和链接器以及软件开发工具的现代化程度而异。CodeView调试信息存储在IMAGE_DEBUG_TYPE_CODEVIEW下面的结构中:

7.jpg

图7:CodeView调试目录信息的结构

完整与部分PDB路径

通常有两种CodeView PDB路径,一种是完全限定的目录路径,另一种是部分限定的目录路径,它们只指定PDB文件的名称。在这两种情况下,都包含扩展名为. PDB的PDB文件的名称,以确保调试器为程序找到正确的PDB。

部分限定的PDB路径将只列出PDB文件名,例如:

Test.pdb

完全限定的PDB路径通常以卷驱动器号和PDB文件名的目录路径开头,例如:

D:\smiller\projects\super_evil_stuff\shellcode\Test\obj\Debug\Test.pdb

通常,本机Windows可执行程序使用部分限定的PDB路径,因为许多调试PDB文件在Microsoft公共符号服务器上是公开可用的,因此在符号路径(PDB路径)中不需要完全限定的路径。在本文中,我们将主要关注完全限定的PDB路径。

调查恶意软件中的PDB路径

在与APT41有无数连接的Shadowhammer操作中,每个示例都有一个简单但描述性的PDB路径: 

D:\C++\AsusShellCode\Release\AsusShellCode.pdb

可以看出,这个命名非常有意义。该恶意软件旨在伪装成华硕公司的软件,传播恶意的shellcode,恶意软件开发人员根据恶意软件本身的功能和角色为该项目命名。

如果我们接受人机协定的约定,迫使开发人员采用这些命名约定,那么我们认为这些约定将适用于其他攻击者、恶意软件家族和入侵操作。一些研究团队喜欢从入侵集中获取看似无害的特性,并判断这些特性的攻击性。比如什么是正常的,什么是不正常的?什么是全球流行的攻击,什么是罕见的攻击?恶意软件开发者的做法与非恶意软件开发人员的做法有何不同?我们可以做出哪些假设并加以衡量?

出于好奇心,我们将CodeView调试信息结构调整为正则表达式(图8),并开发了Yara规则(图9)来调查数据集。这帮助我们识别共性,并使我们能够仅根据PDB路径字符串中的功能查看哪些威胁参与者和恶意软件系列可“检测”。

8.png

可执行文件中PDB7调试信息的perl兼容正则表达式(PCRE),其中以包含特定的关键字符

9.png

模板Yara规则,用于搜索与关键字匹配的PDB文件的可执行文件

PDB路径展示:恶意软件命名约定

我们在事件响应和恶意软件库中调查了1000多万个样本,发现许多常见的PDB路径关键词似乎来自不同的来源、受害者、受影响地区、受影响行业和参与者动机。为了帮助阐明恶意软件开发人员的广泛共性,我们详细介绍了一些较强的关键字,以及示例PDB路径,其中包含表示恶意软件家族和威胁组,其中至少有一个示例具有适用的关键字。

请注意,示例路径和表示的恶意软件家族和组是从整个数据集中选择的,它们不一定相互关联或以其他方式关联。这是为了说明PDB路径与关键字的广泛存在,以及恶意软件开发人员如何在不考虑来源、目标和动机的情况下,最终在命名中使用一些相同的单词。我们认为,这种共性增加了恶意软件的攻击面,并为检测和搜索带来了新的机会。

PDB路径关键字非常普遍

10.1.jpg

10.2.jpg

10.3.jpg

10.4.jpg

10.5.jpg

10.6.jpg

10.7.jpg

10.8.jpg

10.9.jpg

PDB路径中选择的常见关键字,包括观察到的恶意组和软件家族和示例

PDB路径展示:可疑的开发人员环境术语

通常用于描述恶意软件的关键字的强度足以引起警告,但是PDB路径中还有其他一些常见的术语或特性,它们可能表明可执行文件是在非企业设置中编译的。例如,任何包含“Users”目录的PDB路径都可以告诉你,该可执行文件可能是在Windows Vista/7/10上编译的,并且可能不代表“官方”或“商业”开发环境。术语“用户”在保真度上比“shellcode”弱得多,甚至更低,但正如我们下面所演示的,这些术语确实存在于许多恶意软件中,可以用于微弱的检测信号。

PDB路径术语的普遍性

11.1.jpg

11.2.jpg

PDB路径中常见术语的选择,以及观察到的恶意组和软件家族以及示例

PDB路径展示:探索异常

除了关键字和术语之外,我们还发现了一些不常见的特性,这些特性,可能对未来的研究和检测机会感兴趣。

非ascii字符

在我们的数据集中,任何非ascii字符的PDB路径的恶意软件与非恶意软件的比率都很高,此信号的强弱仅仅是因为我们的恶意软件语料库和客户群中存在数据偏差。但是,如果此数据偏差是一致的,我们可以在PDB路径中使用非ASCII字符作为可执行文件值得进一步审查的信号。在主要使用ASCII的组织中,我们认为这将是一个强烈的信号。下面我们在Yara中表达这种技术的逻辑:

rule ConventionEngine_Anomaly_NonAscii
{
    meta:
        author = "@stvemillertime"
    strings:
        $pcre = /RSDS[\x00-\xFF]{20}[a-zA-Z]:\\[\x00-\xFF]{0,500}[^\x00-\x7F]{1,}[\x00-\xFF]{0,500}\.pdb\x00/
    condition:
        (uint16(0) == 0x5A4D) and uint32(uint32(0x3C)) == 0x00004550 and $pcre
}

单个文件中的多个路径

每个编译的程序应该只有一个PDB路径。单个对象中存在多个PDB路径表示该对象具有子文件可执行文件,你可以从中推断父对象具有“删除”或“安装”其他文件的能力。虽然作为dropper或安装程序本身并不是恶意的,但是将这些分类应用于文件对象的替代方法可能有助于表现恶意活动。在此示例中,我们还可以使用Yara搜索此功能:

rule ConventionEngine_Anomaly_MultiPDB_Triple
{
    meta:
        author = "@stvemillertime"
    strings:
        $anchor = "RSDS"
        $pcre = /RSDS[\x00-\xFF]{20}[a-zA-Z]:\\[\x00-\xFF]{0,200}\.pdb\x00/
    condition:
        (uint16(0) == 0x5A4D) and uint32(uint32(0x3C)) == 0x00004550 and #anchor == 3 and #pcre == 3
}

在调试部分之外

编译文件时,调试信息的条目位于IMAGE_DEBUG_DIRECTORY中。与在单个文件中看到多个PDB路径类似,当我们在没有调试目录的可执行文件中看到调试信息时,可以推断该文件具有子文件可执行文件,并且可能具有dropper或安装程序功能。在此规则中,我们使用Yara的PE 模块来检查IMAGE_DIRECTORY_ENTRY_DEBUG条目的相对虚拟地址(RVA),如果是零,我们可以假定没有调试条目,因此CodeView PDB路径的存在表明有子文件。

rule ConventionEngine_Anomaly_OutsideOfDebug
{
    meta:
        author = "@stvemillertime"
        description = "Searching for PE files with PDB path keywords, terms or anomalies."
   strings:
        $anchor = "RSDS"
        $pcre = /RSDS[\x00-\xFF]{20}[a-zA-Z]:\\[\x00-\xFF]{0,200}\.pdb\x00/
   condition:
        (uint16(0) == 0x5A4D) and uint32(uint32(0x3C)) == 0x00004550 and $anchor and $pcre and pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_DEBUG].virtual_address == 0
}

含有null的PDB路径

在典型的CodeView部分中,我们将看到“RSDS”标头、16字节的GUID、4字节的“age”和PDB路径字符串。然而,我们已经确定了大量的恶意软件样本,其中嵌入的PDB路径区域为空。在这个例子中,我们可以很容易地看到CodeView调试结构,包括header、GUID和age,然后是段的末尾的null值。

00147880: 52 53 44 53 18 c8 03 4e 8c 0c 4f 46 be b2 ed 9e : RSDS...N..OF....
00147890: c1 9f a3 f4 01 00 00 00 00 00 00 00 00 00 00 00 : ................
001478a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
001478b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
001478c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................

对于如何以及为什么CodeView PDB路径可能为null,有几种可能性,但是在故意篡改的情况下,为了删除工具标记,最简单的方法是用\x00s手动覆盖PDB路径。通过十六进制编辑器手工编辑和覆盖的风险是,这样做很费力,并且可能引入其他静态异常,例如校验和错误。

另一个最简单的方法是使用一个实用程序,该实用程序设计用于删除可执行文件中的调试构件。一个典型的例子是“peupdate”,它不仅用于提取或构造PDB路径信息,还可以重新计算校验和,并删除Rich标头信息。下面我们将会演示如何使用peupdate删除PDB路径。

16.png

使用peupdate删除恶意软件样本中的PDB路径信息

17.png

PEview实用程序中显示的peupdate篡改恶意软件,我们看到CodeView部分仍然存在,但PDB路径值已被删除

PDB路径异常发生率

18.1.jpg

18.2.jpg

观察到的具有恶意组和软件系列的PDB路径中的异常选择和示例

在下一篇文章中,我们讲接着讨论通过PDB路径展示出的异常和其他恶意行为。

本文翻译自:https://www.fireeye.com/blog/threat-research/2019/08/definitive-dossier-of-devilish-debug-details-part-one-pdb-paths-malware.html如若转载,请注明原文地址: https://www.4hou.com/malware/20242.html
点赞 7
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论