PE文件数字签名

PE文件数字签名及验证过程

签名:

  • 软件发布者使用散列算法(如MD5或SHA)计算PE文件的散列值。
  • 软件发布者使用私钥对散列值进行签名得到签名数据。
  • 将签名私钥对应的公钥和签名数据等以证书的形式附加在PE文件之中,形成经过数字签名的PE文件。
  • 软件发布者将经过数字签名的PE文件进行发布。

验证:

  • 从PE文件证书中提取软件发布者的公钥、使用的散列算法、签名算法、原始散列值的签名数据。
  • 使用提取的公钥和对应签名验证算法将签名数据还原为原始PE文件的原始散列值。
  • 对现有PE文件使用同样的散列算法计算出对应的散列值。
  • 对比两个散列值是否一致,从而判断数据是否被破坏和篡改。

部分系统文件会包含微软的签名,例如C:\Windows\explorer.exe,在文件的属性中可以看到

image-20220519142715621

也可以通过PowerShell的Get-AuthenticodeSignature命令看到

image-20220519142953496

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

preview

使用CFF Explorer查看文件结构

屏幕截图

1
2
File Size: 5114880 bytes
PE Size: 5060608 bytes

可知

1
2
Certificate Table的偏移地址为004D3800(5060608)
Certificate Table的前四字节保存长度,大小应该为0000D400(5114880-5060608=54272)

如下图,PE头中的安全表(Certificate Table)信息

屏幕截图

Certificate Table内容

屏幕截图

1
2
3
4
5
6
typedef struct WIN_CERTIFICATE {
DWORD dwLength; //指定属性证书条目的长度
WORD wRevision; //包含证书版本号
WORD wCertificateType; //指定 bCertificate 中内容类型
BYTE bCertificate[]; //包含证书,例如验证码签名
} WIN_CERTIFICATE, *LPWIN_CERTIFICATE;

详见https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-attribute-certificate-table-image-only

image-20220520104829178

可以看到explorer.exe的bCertificate内容类型为0x0002,即证书内容 PKCS#7 SignedData 结构( 微软官方文档:Windows Authenticode Portable Executable Signature Format )

bCertificate(证书内容)从Certificate Table的偏移地址+8开始,格式是ASN.1,可以通过ASN1View进行查看

image-20220520105811145

要注意的是,在Certificate Table的尾部添加数据并不会影响计算出的文件hash,也就是说在Certificate Table尾部添加数据不会导致证书失效,所以可以在数字证书中隐藏Payload。

数字签名的盗用和复制

SigThief可自动实现保存复制Certificate Table

1
python sigthief.py -i C:\Windows\explorer.exe -t test.exe
image-20220519154725489

但是文件hash已经改变,所以证书无法通过验证,显示无效

有一种通过验证的方法是SIP劫持,通过修改注册表中调用的证书验证方法,默认返回TRUE来使程序通过验证。详见参考链接1

反正我没成功 = =!

参考

https://zhuanlan.zhihu.com/p/30157991?from_voters_page=true

https://zhuanlan.zhihu.com/p/23512363

https://blog.csdn.net/Eastmount/article/details/113774264


PE文件数字签名
http://wangchenchina.github.io/2022/05/20/PE文件数字签名/
作者
Demo
发布于
2022年5月20日
许可协议