回归最本质的信息安全

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

2016年9月5日发布

3,044
0
0

导语:为了验证PE文件的来源和完整性,常常会为PE文件添加数字证书。Windows系统下默认会对一些重要文件添加微软的数字签名,如ntdll.dll。

前言

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

简介

来自Deep Instinct Research Team的Tom Nipravsky在BlackHat2016的议题《Certificate Bypass: Hiding and Executing Malware from a DigitallySigned Executable》介绍了这个方法,并且实现了一个Reflective PE Loader,用来加载隐藏在PE文件数字证书中的Payload,值得学习。本文将会更加详细的介绍如何实现在保证数字签名有效的前提下,向PE文件中隐藏Payload。

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

签名过程:

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

计算文件hash的步骤:

Load the image header into memory.
Initialize a hash algorithm context.
Hash the image header from its base toimmediately before the start of the checksum address, as specified in OptionalHeader Windows-Specific Fields.
Skip over the checksum, which is a 4-bytefield.
Hash everything from the end of thechecksum field to immediately before the start of the Certificate Table entry,as specified in Optional Header Data Directories.
Get the Attribute Certificate Table addressand size from the Certificate Table entry. For details, see section 5.7 of thePE/COFF specification.
Exclude the Certificate Table entry fromthe calculation and hash everything from the end of the Certificate Table entryto the end of image header, including Section Table (headers).The CertificateTable entry is 8 bytes long, as specified in Optional Header Data Directories.
Create a counter calledSUM_OF_BYTES_HASHED, which is not part of the signature. Set this counter tothe SizeOfHeaders field, as specified in Optional Header Windows-SpecificField.
Build a temporary table of pointers to allof the section headers in the image. The NumberOfSections field of COFF FileHeader indicates how big the table should be. Do not include any sectionheaders in the table whose SizeOfRawData field is zero.
Using the PointerToRawData field (offset20) in the referenced SectionHeader structure as a key, arrange the table’selements in ascending order. In other words, sort the section headers inascending order according to the disk-file offset of the sections.
Walk through the sorted table, load thecorresponding section into memory, and hash the entire section. Use theSizeOfRawData field in the SectionHeader structure to determine the amount ofdata to hash.
Add the section’s SizeOfRawData value toSUM_OF_BYTES_HASHED.
Repeat steps 11 and 12 for all of thesections in the sorted table.
Create a value called FILE_SIZE, which isnot part of the signature. Set this value to the image’s file size, acquiredfrom the underlying file system. If FILE_SIZE is greater thanSUM_OF_BYTES_HASHED, the file contains extra data that must be added to thehash. This data begins at the SUM_OF_BYTES_HASHED file offset, and its lengthis: (File Size) – ((Size of AttributeCertificateTable) + SUM_OF_BYTES_HASHED)

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

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

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

注:这个思路早在2009年由AymericBarthe@bartheph提出

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

演示一

测试文件:ntdll.dll

Win7 x64下默认位置为:C:WindowsSysWOW64

使用工具:

CFF Explorer
Hex Editor
LordPE

1、定位CertificateSize in Certificate Table

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

可获得如下信息:

File Size: 1292592 bytes
PE Size: 1277952 bytes

推断出:

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

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

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

2、修改CertificateSize in Certificate Table

测试待添加的payload为:1111111111,长度为10,显然,

New Size = Old Size + Payload Size
             = 14640 +10
             = 14650
             = 393aH

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

3、定位CertificateSize in Optional Header

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

4、修改CertificateSize in Optional Header

00003930修改为0000393A,如图

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

5、添加payload

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

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

6、修改PE文件校验和

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

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

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

原校验和为0013E00E,如图

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

使用LordPE验证校验和,成功

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

演示二

测试文件:aliide.sys

1、定位CertificateSize in Certificate Table

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

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

Certificate Size为00001c50H

2、修改CertificateSize in Certificate Table

添加的payload为BBBBBBBBBB,10字节

00001c50H+10=00001c5AH

修改为5A1C0000,如图

3、定位CertificateSize in Optional Header

4、修改CertificateSize in Optional Header

00001C50改为00001C5A

5、添加payload

尾部添加BBBBBBBBBB

6、修改PE文件校验和

000065ED改为0000B156

添加成功

程序实现

1、AymericBarthe@bartheph的实现方法

开发语言:c++

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

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

AppendPayLoad.exe ntdll.dll payload.txtnewntdll.dll

参数说明:

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

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

1.payload尾部包含多余数据

如图,多了6个’00’

2.未修改PE文件校验和

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

3、Joakim Schicht的实现方法

开发语言:Autoit

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

界面如图

小结

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

本文为3gstudent原创稿件,授权嘶吼独家发布,未经许可禁止转载,如若转载,请联系嘶吼编辑: http://www.4hou.com/technology/2248.html

点赞 0
取消

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

扫码支持

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

3gstudent

3gstudent

嘶吼特约作者

发私信

发表评论