Cyril François

解密 ICEDID

Elastic Security Labs 开源工具的综合教程

阅读时间:14 分钟工具
ICEDID 简介

前言

ICEDID 是 IBM X-force 研究人员于 2017 发现的一个恶意软件家族,与登录凭据、银行信息和其他个人信息的盗窃有关。 ICEDID 一直是一个普遍存在的家族,但自 2021 年初 EMOTET 暂时中断以来,取得了更大的增长。 ICEDID 与几种不同的恶意软件家族的传播有关,包括DarkVNCCOBALT STRIKE 。 定期的行业报告(包括像这样的研究出版物)有助于减轻这种威胁。

众所周知,ICEDID 使用自定义文件格式和自定义加密方案来打包其有效载荷。 遵循我们最新的ICEDID 研究,该研究涵盖了 GZip 变体执行链。

在本教程中,我们将通过解压最近的 ICEDID 样本来介绍这些工具,首先下载一份假的 GZip 二进制文件的副本:

分析恶意软件对系统来说可能很危险,因此只能由经验丰富的专业人员在受控环境(如隔离的虚拟机或分析沙箱)中尝试进行。 恶意软件可以被设计来逃避检测并感染其他系统,因此采取一切必要的预防措施并使用专门的工具来保护您自己和您的系统非常重要。

54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f

环境设置

在本教程中,我们使用 Windows 10 和 Python 3.10。

Elastic Security Labs 正在发布一套工具来自动化解包过程并帮助分析师和社区应对 ICEDID。

脚本描述兼容性
解密文件.py解密ICEDID加密文件Windows 和其他(未测试)
gzip_variant/extract_gzip.py从 ICEDID 伪造 GZip 文件中提取有效载荷Windows 和其他(未测试)
gzip_variant/extract_payload_from_core.py从重建的 ICEDID 核心二进制文件中提取并解密有效载荷Windows 和其他(未测试)
gzip_variant/load_core.py加载并执行核心自定义 PE 二进制文件仅限 Windows
gzip_variant/read_configuration.py读取伪造 GZip 中包含的 ICEDID 配置文件Windows 和其他(未测试)
重建_pe.py从 ICEDID 自定义 PE 文件重建 PEWindows 和其他(未测试)

为了使用这些工具,请克隆Elastic Security Lab 发布存储库并安装 nightMARE 模块。

git clone https://github.com/elastic/labs-releases
cd labs-release
pip install .\nightMARE\

本教程中的所有工具均使用nightMARE模块,该库实现了我们解压 ICEDID 中嵌入的各种有效载荷所需的不同算法。 我们发布 nightMARE 是因为它是 ICEDID 分析所必需的,但请继续关注 - 随着我们继续开发和完善这个框架,还会有更多内容。

解密伪造的 GZip

ICEDID 假 GZip 是一个伪装成有效 GZip 文件的文件,通过使用GZip 文件头和页脚封装真实数据来进行格式化。

GZip 魔法字节以红色显示。
GZip 标头以绿色呈现。
虚拟文件名值为蓝色。

GZip 标头之后是真正的数据结构,我们将在下面进行描述。

我们将使用labs-releases\tools\icedid\gzip-variant\extract_gzip.py脚本来解压这个欺诈性的 GZip。

usage: extract_gzip.py [--help] input output

positional arguments:
  input       Input file
  output      Output directory

options:
  -h, --help  show this help message and exit

我们将在上面链接的 ICEDID 示例上使用 extract_gzip.py,并将内容存储到我们创建的名为“ extract ”的文件夹中(您可以使用任何现有的输出文件夹)。

python extract_gzip.py 54d064799115f302a66220b3d0920c1158608a5ba76277666c4ac532b53e855f extract

============================================================
Fake Gzip
============================================================
is_dll: True
core: UponBetter/license.dat (354282 bytes)
stage_2: lake_x32.tmp (292352 bytes)

extract\configuration.bin
extract\license.dat
extract\lake_x32.tmp

该脚本返回三个单独的文件,包括:

  • 加密配置文件: configuration.bin
  • 加密的核心二进制文件: license.dat
  • 持久性加载器: lake_x32.tmp

解密核心二进制文件和配置文件

我们提取的配置和核心二进制文件使用 ICEDID 的自定义加密方案进行加密。 我们可以使用labs-releases\tools\icedid\decrypt_file.py脚本对其进行解密。

usage: decompress_file.py [--help] input output

positional arguments:
  input       Input file
  output      Output file

options:
  -h, --help  show this help message and exit

如下图所示(请注意,解密的文件可以写入任何有效的目的地):

python .\decrypt_file.py .\extract\license.dat .\extract\license.dat.decrypted

python .\decrypt_file.py .\extract\configuration.bin .\extract\configuration.bin.decrypted

核心二进制文件和配置现在已经准备好由附加工具进行处理了。 请参阅以下屏幕截图中显示的解密配置的数据:

读取配置

配置文件格式如下所示。

可以使用labs-releases\tools\icedid\gzip-variant\read_configuration.py脚本读取配置。

usage: read_configuration.py [--help] input

positional arguments:
  input       Input file

options:
  -h, --help  show this help message and exit

我们将使用read_configuration.py脚本来读取我们在上一步中收集的configuration.bin.decrypted文件。

python .\gzip-variant\read_configuration.py .\extract\configuration.bin.decrypted

============================================================
Configuration
============================================================
botnet_id: 0x3B7D6BA4
auth_var: 0x00000038
uri: /news/
domains:
        alishaskainz.com
        villageskaier.com

此配置包含两个 C2 域:

  • alishaskainz[.]com
  • villageskaier[.]com

对于此样本,ICEDID 使用的信标 URI 是“ /news/ ”。

重建核心二进制文件以进行静态分析

ICEDID 使用自定义 PE 格式来混淆其有效负载,从而击败那些需要处理普通 Windows 可执行文件的静态或动态分析工具。 自定义PE文件格式如下所述。

如果我们想要分析核心二进制文件,例如使用IDA Pro ,我们需要将其重建为有效的 PE。 我们使用labs-releases\tools\icedid\rebuild_pe.py脚本。

usage: rebuild_pe.py [--help] [-o OFFSET] input output

positional arguments:
  input                 Input file
  output                Output reconstructed PE

options:
  -h, --help            show this help message and exit
  -o OFFSET, --offset OFFSET
                        Offset to real data, skip possible garbage

然而,当尝试在解密的核心二进制文件license.dat.decrypted上使用rebuild_pe.py时,我们收到以下错误消息:

python .\rebuild_pe.py .\extract\license.dat.decrypted .\extract\core.bin
Traceback (most recent call last):
  File "rebuild_pe.py", line 32, in <module>
    main()
  File "rebuild_pe.py", line 28, in main
    custom_pe.CustomPE(data).to_pe().write(args.output)
  File "nightmare\malware\icedid\custom_pe.py", line 86, in __init__
    raise RuntimeError("Failed to parse custom pe")
RuntimeError: Failed to parse custom pe

这里的微妙之处在于自定义 PE 数据并不总是从文件的开头开始。 在这种情况下,例如,如果我们在像HxD这样的十六进制编辑器中打开文件,我们可以在实际数据之前观察到一定数量的垃圾字节。

我们从研究中得知,垃圾的大小为129字节。

考虑到这一点,我们可以跳过垃圾字节并使用带有“-o 129”参数的rebuild_pe.py脚本重建核心二进制文件。 幸运的是,这次我们没有收到错误消息。 core.bin将被保存到输出目录,在我们的示例中为提取

python .\rebuild_pe.py .\extract\license.dat.decrypted .\extract\core.bin -o 129

重建的 PE 对象不能直接执行,但您可以使用所选择的反汇编程序对其进行静态分析。

我们为重建的二进制部分分配了自定义名称( .mare{0,1,2,...} )。

我们要赞扬并感谢Hasherezade 的工作,他的工作给了我们灵感来构建这个工具。

执行核心二进制文件(仅限 Windows)

如果没有能够理解 ICEDID 的自定义 PE 格式以及入口点函数原型的自定义加载器,则核心二进制文件无法执行。

从我们的研究中,我们知道入口点需要一个我们称为上下文结构的结构,其中包含 ICEDID 核心和持久性加载器路径及其加密配置。 上下文结构如下所述。

为了本地执行核心二进制文件,我们使用labs-releases\tools\icedid\gzip-variant\load_core.py脚本,但在使用它之前,我们需要创建context.json文件,其中包含此脚本构建此结构所需的所有信息。

对于此示例,我们复制了伪 gzip 中包含的信息,并使用了加密配置文件的路径。 我们在gzip_variant/context.json.example中包含了一个示例。

请注意,在反转样本时必须找到“field_0”“stage_2_export”值。

这里我们使用以前研究的值作为占位符,但我们不能保证样本会 100% 有效。 例如,在这个示例中,我们不知道#1序数导出是否是持久性加载器的实际入口点。

我们还通过创建UponBetter目录并将license.dat文件移入其中来重现第一阶段的行为。

我们使用解密的核心二进制文件: license.dat.decryptedcontext.json文件执行labs-releases\tools\icedid\gzip_variant\load_core.py脚本。

警告:该脚本将本地加载/执行二进制文件,Elastic Security Labs 不对您的系统造成的任何损害负责。 请仅在安全的环境中执行。

usage: load_core.py [--help] [-o OFFSET] core_path ctx_path

positional arguments:
  core_path             Core custom PE
  ctx_path              Path to json file defining core's context

options:
  -h, --help            show this help message and exit
  -o OFFSET, --offset OFFSET
                        Offset to real data, skip possible garbage

因为我们有与上一节所述的相同的垃圾字节问题,所以我们使用“-o 129”参数来跳过垃圾字节。

python .\gzip-variant\load_core.py .\extract\license.dat.decrypted .\gzip-variant\context.example.json -o 129

============================================================
Core Loader
============================================================
Base address: 0x180000000
Entrypoint: 0x180001390

Press a key to call entrypoint...

启动时,脚本将等待用户输入,然后调用入口点。 我们可以轻松地将调试器附加到 Python 进程并在 ICEDID 核心入口点(在此示例中为0x180001390 )上设置断点。

一旦按下键,我们就到达入口点。

如果我们让二进制文件执行,我们会看到正在创建的ICEDID线程(如下面的屏幕截图所示)。

从重建的核心二进制文件中解压并重建有效载荷

为了提取嵌入在核心二进制文件中的任何有效载荷,我们将使用labs-releases\tools\icedid\gzip-variant\extract_payloads_from_core.py脚本

usage: extract_payloads_from_core.py [--help] input output

positional arguments:
  input       Input file
  output      Output directory

options:
  -h, --help  show this help message and exit

我们将在重建的核心二进制文件上使用该脚本。

python .\gzip-variant\extract_payloads_from_core.py .\extract\core.bin core_extract

core_extract\browser_hook_payload_0.cpe
core_extract\browser_hook_payload_1.cpe

从这里,我们输出两个与 ICEDID 有效负载相对应的二进制文件,以实现 Web 浏览器挂钩功能,但是,它们仍然是自定义的 PE 格式。

根据我们的研究,我们知道browser_hook_payload_0.cpe是浏览器钩子负载的x64版本,而browser_hook_payload_1.cpe是x86版本。

为了重建它们,我们再次使用rebuild_pe.py脚本,这次没有垃圾字节需要跳过。

python .\rebuild_pe.py .\core_extract\browser_hook_payload_0.cpe .\core_extract\browser_hook_payload_0.bin

python .\rebuild_pe.py .\core_extract\browser_hook_payload_1.cpe .\core_extract\browser_hook_payload_1.bin

现在我们有两个 PE 二进制文件 ( browser_hook_payload_0.binbrowser_hook_payload_1.bin ) 可以进一步分析。

细心的读者可能会发现,我们跳过了从核心二进制文件中解压VNC 服务器,这是我们有意做出的决定。 我们将在即将开展的研究中与其他工具一起发布它,敬请关注!

结论

在本教程中,我们介绍了 ICEDID GZip 变体的解包,从提取伪 GZip 二进制文件开始,然后重建核心二进制文件并解包其有效负载。

ICEDID 在不断发展,我们将继续监测重大变化并根据研究更新我们的工具。 如果出现问题或者没有按预期工作,请随时提出问题或者向我们发送消息

Elastic Security Labs 是由专业研究人员和安全工程师组成的团队,致力于通过发布详细的检测逻辑、保护措施和应用威胁研究来打击对手。

@elasticseclabs上关注我们并访问我们的研究门户以获取更多资源和研究。

参考资料

上述研究参考了以下内容: