隐写技巧——在 PE 文件的数字证书中隐藏 Payload

发布于 2024-10-08 05:10:41 字数 10618 浏览 25 评论 0

0x00 前言

为了验证 PE 文件的来源和完整性,常常会为 PE 文件添加数字证书。Windows 系统下默认会对一些重要文件添加微软的数字签名,如 ntdll.dll。恶意文件分析系统在对 PE 文件的静态分析过程中,如果 PE 文件有数字签名,则对签名进行验证。若数字签名验证通过,则不再对其进行后续分析。这样做主要考虑的是降低误报,以及减少服务器资源消耗。如果能在保证数字签名有效的前提下,在 PE 文件中隐藏 Payload,那么这种隐写方式将会非常隐蔽。

0x01 简介

来自 Deep Instinct Research Team 的 Tom Nipravsky 在 BlackHat2016 的议题 《Certificate Bypass: Hiding and Executing Malware from a Digitally Signed Executable》 介绍了这个方法,并且实现了一个 Reflective PE Loader,用来加载隐藏在 PE 文件数字证书中的 Payload,值得学习。

议题 PDF 下载地址:https://www.blackhat.com/docs/us-16/materials/us-16-Nipravsky-Certificate-Bypass-Hiding-And-Executing-Malware-From-A-Digitally-Signed-Executable-wp.pdf

本文将会更加详细的介绍如何实现在保证数字签名有效的前提下,向 PE 文件中隐藏 Payload。

0x02 PE 文件格式和数字签名格式

Alt text

图 1 引用自 Windows Authenticode Portable Executable Signature Format https://msdn.microsoft.com/en-us/windows/hardware/gg463180.aspx

签名过程:

  • 计算 PE 文件 hash
  • 根据 hash 生成数字证书
  • 数字签名添加在文件末尾,这部分称作 Certificate Table

计算文件 hash 的步骤:

  1. Load the image header into memory.
  2. Initialize a hash algorithm context.
  3. Hash the image header from its base to immediately before the start of the checksum address, as specified in Optional Header Windows-Specific Fields.
  4. Skip over the checksum, which is a 4-byte field.
  5. Hash everything from the end of the checksum field to immediately before the start of the Certificate Table entry, as specified in Optional Header Data Directories.
  6. Get the Attribute Certificate Table address and size from the Certificate Table entry. For details, see section 5.7 of the PE/COFF specification.
  7. Exclude the Certificate Table entry from the calculation and hash everything from the end of the Certificate Table entry to the end of image header, including Section Table (headers).The Certificate Table entry is 8 bytes long, as specified in Optional Header Data Directories.
  8. Create a counter called SUM_OF_BYTES_HASHED, which is not part of the signature. Set this counter to the SizeOfHeaders field, as specified in Optional Header Windows-Specific Field.
  9. Build a temporary table of pointers to all of the section headers in the image. The NumberOfSections field of COFF File Header indicates how big the table should be. Do not include any section headers in the table whose SizeOfRawData field is zero.
  10. Using the PointerToRawData field (offset 20) in the referenced SectionHeader structure as a key, arrange the table's elements in ascending order. In other words, sort the section headers in ascending order according to the disk-file offset of the sections.
  11. Walk through the sorted table, load the corresponding section into memory, and hash the entire section. Use the SizeOfRawData field in the SectionHeader structure to determine the amount of data to hash.
  12. Add the section’s SizeOfRawData value to SUM_OF_BYTES_HASHED.
  13. Repeat steps 11 and 12 for all of the sections in the sorted table.
  14. Create a value called FILE_SIZE, which is not part of the signature. Set this value to the image’s file size, acquired from the underlying file system. If FILE_SIZE is greater than SUM_OF_BYTES_HASHED, the file contains extra data that must be added to the hash. This data begins at the SUM_OF_BYTES_HASHED file offset, and its length is: (File Size) – ((Size of AttributeCertificateTable) + SUM_OF_BYTES_HASHED)

引用自 Windows Authenticode Portable Executable Signature Format https://msdn.microsoft.com/en-us/windows/hardware/gg463180.aspx

如果修改了文件内容,那么计算出的文件 hash 就会改变,导致数字证书无法通过验证,所以数字证书能够保证签名文件的完整性,但是在计算文件 hash 的算法上 存在一个不足:

计算文件 hash 并非对整个文件内容作计算(如计算文件 hash 的步骤 4,以及图 1 中灰色背景的部分,目的是避免绑定的证书文件影响到 hash 值)

更值得注意的是:

在 Certificate Table 的尾部添加数据并不会影响计算出的文件 hash,也就是说在 Certificate Table 尾部添加数据不会导致证书失效

注: 这个思路早在 2009 年由 Aymeric Barthe@bartheph 提出: https://blog.barthe.ph/2009/02/22/change-signed-executable/

当然,在证书尾部添加数据虽然不会影响计算出的文件 hash,但会改变证书长度,所以在 PE 文件结构中保存证书长度的位置需要作相应修改(共 2 处),下面实例演示一种最直观的添加 payload 并修改证书长度的方法

0x03 演示一

测试文件:

ntdll.dll

Win7 x64 下默认位置为:C:\Windows\SysWOW64

使用工具:

CFF Explorer

Hex Editor

LordPE

1、定位 Certificate Size in Certificate Table

使用 CFF Explorer 查看 dll 结构,如图

Alt text

可获得如下信息:

File Size: 1292592 bytes

PE Size: 1277952 bytes

推断出:

Certificate Table 的偏移地址为 138000H(1277952)

Certificate Table 的前四字节保存长度,大小应该为 14640 bytes(1292592-1277952)

现在跳到偏移地址 138000H,查看前四字节,验证推断

如图,前四字节为 30390000,转换成实际长度为 00003930H,即 14640 bytes

Alt text

2、修改 Certificate Size in Certificate Table

测试待添加的 payload 为:1111111111,长度为 10,显然,New Size = Old Size + Payload Size

     = 14640 +10

     = 14650

     = 393aH

对应偏移地址 138000H-138003 的数据修改为 3A390000,如图

Alt text

3、定位 Certificate Size in Optional Header

使用 CFF Explorer 查看 dll 结构,选择 Nt Headers-Optional Header-Data Directories [x],找到 Security Directory Size 项,如图

Alt text

4、修改 Certificate Size in Optional Header

00003930 修改为 0000393A,如图

Alt text

保存文件,查看文件信息,签名失效(因为还没有添加 payload)

如图

Alt text

5、添加 payload

使用 Hex Editor 在文件尾部添加 payload

如图

Alt text

保存后,签名成功识别,如图

Alt text

6、修改 PE 文件校验和

使用 LordPE 打开 PE 文件,如图,原文件的校验和为 0013E00E

Alt text

点击"?"对其更新,如图,新的校验和为 00142672

Alt text

使用 CFF Explorer 打开 PE 文件,选择 Nt Headers-Optional Header,找到 CheckSum 项

原校验和为 0013E00E,如图

Alt text

修改为 00142672,保存为 ntdll(AddPayload).dll

使用 LordPE 验证校验和,成功

至此,在保证 PE 文件数字证书有效的前提下,成功在 PE 文件尾部添加 Payload

注:

添加的 payload 长度需要满足为 8 的整数倍,否则会显示数字签名状态无效

0x04 演示二

测试文件:aliide.sys

1、定位 Certificate Size in Certificate Table

如图,偏移地址 2000H(8192)

Alt text

跳到偏移地址 2000H,查看前四字节,如图

Alt text

Certificate Size 为 00001c50H

2、修改 Certificate Size in Certificate Table

添加的 payload 为 BBBBBBBBBB,10 字节

00001c50H+10=00001c5AH

修改为 5A1C0000,如图

Alt text

3、定位 Certificate Size in Optional Header

如图

Alt text

4、修改 Certificate Size in Optional Header

00001C50 改为 00001C5A

5、添加 payload

尾部添加 BBBBBBBBBB

如图

Alt text

6、修改 PE 文件校验和

000065ED 改为 0000B156

添加成功

注:

添加的 payload 长度需要满足为 8 的整数倍,否则会显示数字签名状态无效

0x05 程序实现

1、Aymeric Barthe@bartheph 的实现方法

开发语言: c++

下载地址:https://blog.barthe.ph/download/2009/AppendPayLoad.tar.bz2

编译成功后,命令行执行:

AppendPayLoad.exe ntdll.dll payload.txt newntdll.dll

参数说明:

  • ntdll.dll:原 PE 文件
  • payload.txt:存储待添加的 payload
  • newntdll.dll:新生成的文件

测试 Payload 添加成功,新生成文件的数字签名成功识别,程序有 如下特点:

1.payload 在尾部自动填 0 补齐 payload 长度为 8 的倍数

如图,多了 6 个'00',补齐长度

Alt text

2.未修改 PE 文件校验和

如图,PE 文件校验和实际应该为 00142684

Alt text

2、Joakim Schicht 的实现方法

开发语言: Autoit

下载地址:http://reboot.pro/files/file/85-digitalsignaturetweaker/

界面如图

Alt text

0x06 小结

本文介绍了如何利用工具实现在保证数字签名有效的前提下,向 PE 文件中隐藏 Payload。在掌握了修改方法后,编写程序实现自动修改不会很难。对于带有数字签名的 PE 文件,建议不要盲目相信。

更新

对添加 payload 的长度限制做了修正,payload 长度需要满足是 8 的倍数,否则数字签名状态无效。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

尾戒

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文