μthenticode:一款用于验证 Windows 文件签名的跨平台工具,用于在没有Windows设备的情况下在Windows PE二进制文件上验证Authenticode签名。开发人员还将其集成到Winchecksec的最新版本中,以便你日后可以使用它来验证Windows可执行文件上的签名。

μthenticode旨在轻松集成,它是用跨平台的现代C ++编写的,避免了它所取代的CryptoAPI接口的复杂性(即WinVerifyTrust和CertVerifyCertificateChainPolicy)。你现在可以使用它来代替SignTool的许多功能,并且还有更多功能正在使用中。

Authenticode快速入门

Authenticode是Microsoft的代码签名技术,其功能与Apple Gatekeeper相当。Authenticode为已签名的程序提供许多属性:

1. 真实性:具有有效Authenticode签名的程序包含足以验证该签名的证书链,所述链最终植根于存储在用户的受信任发布者存储中的证书,从而防止了未经用户明确选择就无法自行签名的证书。

2. 完整性:每个Authenticode签名都包含已签名二进制文件的加密哈希,将此哈希与加载时二进制文件的内存表示形式进行比较,以防止恶意修改。

3. Authenticode还可以为每页内存嵌入加密哈希,它们与强制完整性签名一起使用,这对于Windows内核驱动程序是必需的,并且需要一个特殊的Microsoft交叉签名的“软件发布者证书”,而不是自签名或独立受信任的证书颁发机构(CA)。

4. 时效性:Authenticode支持嵌入来自时间戳授权(TSA)的反签名,从而使二进制文件上的签名有可能超过其签名证书的到期日期。这样的签名也可以防止有效签名的回溯,从而使攻击者更难以重用过期的签名证书。

像所有代码签名技术一样,Authenticode不能对程序做出某些保证:

1. 也有漏洞:任何人都可以编写有漏洞的软件并使用自签名证书或通过从Microsoft交叉签名的CA购买证书来对其进行签名。

2. 它只运行自身的代码,众所周知,Windows执行契约是出了名的宽松(例如,桌面应用程序的DLL加载规则),许多应用程序支持某种形式的代码执行作为一种特性(脚本、插件、生病的WinAMP皮肤,等等)。Authenticode无法验证在初始签名二进制文件之外执行的代码的完整性或意图。

因此,Authenticode与所有PKI实现一样,容易受到以下因素影响:

1. 错位的信任:CA希望出售尽可能多的证书,因此对检查从其购买的实体的合法性的动机有限,任何人都可以花几百美元在美国建立有限责任公司。

2. 证书被盗:代码签名和HTTPS证书是盗窃的主要目标,许多真实的活动利用窃取的证书欺骗用户相信恶意代码。公司定期到源代码控制系统检查他们的秘密材料,代码签名证书也不例外。

3. 欺诈性证书:臭名昭著的Flame利用了对MD5的一种新颖的选择前缀攻击来模拟一个意外被信任用于代码签名的Microsoft证书。对SHA-1的类似攻击现在在价格上对民族国家和有组织犯罪都是合理的。

总而言之,Authenticode(以及所有其他形式的代码签名)为二进制文件添加了有用的真实性和完整性检查,前提是你信任签名者及其存储密钥材料的能力。

解析Authenticode签名:PKCS#7

PKCS#7,也叫做加密消息的语法标准,由RSA安全体系在公钥加密系统中交换数字证书产生的一种加密标准。PKCS#7描述数字证书的语法和其他加密消息——尤其是,数据加密和数字签名的方法,也包含了算法。当使用PKCS#7进行数字签名时,结果包含签名证书(一列相关证书撤回列表)和已证明路径上任何其他证书。如果使用PKCS#7加密数据,通常包含发行者的参考消息和证书的序列号,它与用于解密已加密数据的公共密钥相关。

对于2000年代的Microsoft而言,这是一个不寻常的举动,大多数Authenticode格式实际上都已记录在案并可以下载。少数部分明显定义不足或标记为“超出范围”:我们将在下面介绍其中的一些。

Authenticode的核心包括两个组件:

证书表:其中包含一个或多个条目,每个条目可以是一个SignedData。

SignedData对象:通常是普通的PKCS#7容器(根据RFC 2315标有SignedData的内容类型)。

证书表

证书表是将Authenticode签名嵌入到PE文件中的机制,它具有一些有趣的属性:

1. 访问证书表涉及读取数据目录表中的证书表目录,与数据目录表中的所有其他条目不同,证书目录的RVA字段不是虚拟地址,而是直接文件偏移量。这反映了Windows加载程序的行为,它实际上并未将证书加载到程序的地址空间中。

2. 尽管如此,现实世界中的工具在证书表的放置和后续解析方面似乎并不灵活。 Microsoft的工具始终将证书表放在PE的末尾,许多第三方工具会天真地寻求证书表的偏移量并进行解析直到EOF,从而使攻击者可以轻易附加附加证书。

一旦定位,解析证书表就很简单了,它是一个8字节对齐的WIN_CERTIFICATE结构的Blob:

有一些有趣的域:

1.wRevision:WIN_CERTIFICATE的“修订”。MSDN最近才修复了这个字段的文档:WIN_CERT_REVISION_2_0=0x0200是Authenticode签名的当前版本。 WIN_CERT_REVISION_1_0 = 0x0100用于“旧版”签名,我无法在野外找到后者。

2.wCertificateType:封装的证书数据的种类。MSDN记录了wCertificateType的四个可能值,但开发人员只对其中一个感兴趣:WIN_CERT_TYPE_PKCS_SIGNED_DATA。

3.bCertificate:实际的证书数据。对于WIN_CERT_TYPE_PKCS_SIGNED_DATA,这是上面提到的PKCS#7 SignedData。

如你所料,证书表的结构允许多个独立的Authenticode签名。这对于跨多个Windows版本部署程序很有用,尤其是那些可能在受信任发布者存储中具有旧证书或由于某种原因不信任特定CA的版本。

Authenticode的SignedData

微软提供了可视化的签名数据结构:

这几乎是一个正常的PKCS#7 SignedData,但有几个关键的偏差:

1. Authenticode SignedData的contentInfo类型不是RFC 2315内容类型之一,而是SPC_INDIRECT_DATA_OBJID类型,微软将其定义为1.3.6.1.4.1.311.2.1.43。

2. 与此对象标识符(OID)对应的结构被记录为SpcIndirectDataContent,微软也提供了它的ASN.1定义:

请注意,自定义AlgorithmIdentifier实际上只是X.509的AlgorithmIdentifier,详细情况,请参阅RFC 3279及其更新。

根据上面的ASN.1定义,开发人员可以使用OpenSSL的(软硬且完全未记录的)ASN.1宏来解析Microsoft的自定义结构:

检查实际签名

有了适当的结构后,开发人员可以使用OpenSSL的)奇热未记录的PKCS#7 API来解析SignedData和间接数据内容:

然后验证它们:

开发人员通过了PKCS7_NOVERIFY,因为开发人员不一定有权访问整个证书链,只有在其受信任的发布者存储区中具有相关证书的Windows用户才能访问整个证书链。

计算并检查Authenticode哈希

现在开发人员有了真实性(以根证书为模),让开发人员进行完整性检查。

首先,让我们获取嵌入在Authenticode签名中的哈希,以进行最终比较:

接下来,开发人员需要计算二进制文件的实际哈希值,这有点复杂。

1. 每个PE都有一个32位的校验和字段,用于基本完整性目的(即意外损坏)。计算哈希值时,该字段需要跳过,因为它是对整个文件计算得出的,并且会随着证书的添加而变化。

2. 需要跳过证书数据目录条目本身,因为重新定位或修改证书表的大小不需要对现有签名进行任何更改。

3. 当然,证书表和组成签名本身不能作为哈希的输入的一部分。

4. 为了确保一致的哈希,Authenticode规定按升序根据每个节标头的PointerToRawData的值对节进行哈希,而不是按照节标头本身的顺序。这不是特别麻烦,但需要一些额外的操作。

μthenticode对Authenticode哈希过程的实现时间太长,无法在下面重复,但使用伪代码:

1. 从空缓冲区开始;

2. 将所有PE头(DOS、COFF、可选、节)插入缓冲区;

3. 按顺序从缓冲区中删除证书表目录条目和校验和字段,以避免重新计算前者的偏移量。

4. 使用pe-parse的IterSec API构造节缓冲区列表,从#129开始,IterSec以文件偏移顺序生成节。

5. 跳过证书表并将尾随数据添加到缓冲区(如果存在的话);

6. 使用从签名中检索到的NID创建并初始化新的OpenSSL消息摘要上下文;

7. 将缓冲区放入EVP_DigestUpdate中,并使用EVP_DigestFinal结束。

8. 将结果与Authenticode提供的哈希进行比较。

现在,我们将接着讨论Authenticode剩下的两个主要功能:页面哈希和时间戳签名。

页面哈希

如上所述,页面哈希明显没有在Authenticode规范中记录,并且被描述为存储在“[…]二进制结构中[这]不在本文的讨论范围内”。

有关上述结构的在线信息仅限于以下几种资源:

VirtualBox源代码引用了两个不同版本的页面哈希结构的OID:

SPC_PE_IMAGE_PAGE_HASHES_V1_OBJID:1.3.6.1.4.1.311.2.3.1

SPC_PE_IMAGE_PAGE_HASHES_V2_OBJID:1.3.6.1.4.1.311.2.3.2

尽管这些OID确实出现在Wintrust.h中,但未在Microsoft的OID参考或OID存储库中列出。

osslsigncode至少有一个分支支持生成和验证页面哈希,并授予我们进一步的洞察力:

V1 OID表示SHA-1页面哈希值; V2代表SHA2-256。

每个SpcSerializedObject的serializedData是一个ASN.1集合,其中的每个成员都是一个ASN.1序列,其作用如下所示:

上面的定义是我根据get_page_hash_link的主体进行的重构; osslsigncode混淆地将SpcAttributeTypeAndOptionalValue类型重用于Impl_SpcPageHash并手动构造SpcSerializedObject的其余内容。

据我所知,osslsigncode只为整个PE插入一个Impl_SpcPageHash,它在pe_calc_page_hash中计算该值。该函数中的代码非常密集,但似乎会生成如下结构表:

其中IMPL_PAGE_HASH_SIZE由所使用的哈希算法(即,由Impl_SpcPageHash.type)确定,并且表中的第一个条目是仅对具有page_offset = 0的PE标头进行空填充的“页面哈希”。此表未分配ASN.1定义,而是直接插入Impl_SpcPageHash.pageHashes中。

时间戳签名

与页面哈希不同,Authenticode的时间戳签名格式在官方来源和第三方来源中都有相对较好的记录。

就像Authenticode SignedData主要是一个正常的PKCS#7签名数据一样,Authenticode的时间戳格式主要是正常的PKCS#9签名。

向时间戳颁发机构(TSA)发出时间戳请求(TSR)时,该请求采用HTTP 1.1 POST的形式,其中包含DER编码,然后是base64编码的ASN.1消息:

其中countersignatureType是自定义的Microsoft OID 1.3.6.1.4.1.311.3.2.1(即SPC_TIME_STAMP_REQUEST_OBJID),内容是原始的Authenticode PKCS#7 ContentInfo。

TSA响应是PKCS#7 SignedData,从中提取SignerInfo并将其嵌入到主Authenticode SignedData中。来自TSA响应的证书类似地作为未经身份验证的属性嵌入到证书列表中。

总结

我们已经讨论了Authenticode的四个主要组件:验证签名,对照已验证的哈希值检查文件的完整性,计算页面哈希值以及验证时间戳的签名。

μthenticode本身仍在开发中,目前仅支持签名和主要的Authenticode哈希。你可以通过提供对页面哈希解析和验证以及时间戳签名验证的支持来帮助开发人员!

μthenticode的API已被完全记录和托管,并且大多数可以立即与peparse :: parsed_pe *:一起使用:

请查看svcli命令行工具中的应用示例,包括检索嵌入式Authenticode哈希。

Μthenticode工具是完全从头编写的,并使用Microsoft提供的官方Authenticode文档作为底本。

μthenticode:一款用于验证 Windows 文件签名的跨平台工具相关推荐

  1. 11 款用于优化、分析源代码的Java工具

    本文将提供一些工具,帮助你优化代码以及检查源代码中的潜在问题. 1. PMD from http://pmd.sourceforge.net/ PMD能够扫描Java 源代码,查找类似以下的潜在问题: ...

  2. windows文件鼠标右键添加工具快捷方式

    1.将使用频率较高的软件添加到鼠标右键的下拉选项菜单中,可以很便捷地打开相关的文件,而不用很费力地去寻找打开这种文件对应的软件所在的位置. 2.例如将Notepad++.exe添加到右键快捷方式中: ...

  3. basic 重命名_用于重命名文件的Visual Basic工具。

    basic 重命名 Applications concerned with document scanning and archiving, and other automatic file gene ...

  4. Windows文件自动增量备份工具,解放你的双手!

    上次给大家讲了完全备份,后来有人问想了解增量备份!首先跟大家科普下这两个的区别: 完全备份: 完全备份就是每次自动备份都会将源目录里面的文件都备份,比如源文件夹里面有A.B.C三个文件,首次备份目标文 ...

  5. 5款不妨一试的硬盘碎片整理工具

    几十年来Windows操作系统中都一直有碎片整理功能.不过也有大量第三方应用中有Windows原生工具中不具备的功能.本文列出了5款商用的碎片整体应用. 1.PerfectDisk Professio ...

  6. 基于NMAP日志文件的暴力破解工具BruteSpray

    基于NMAP日志文件的暴力破解工具BruteSpray 使用NMAP的-sV选项进行扫描,可以识别目标主机的端口对应的服务.用户可以针对这些服务进行认证爆破.为了方便渗透测试人员使用,Kali Lin ...

  7. 计算机无法验证签名,电脑提示“无法验证此文件的数字签名”的修复方法

    近期,一位小伙伴反馈说电脑总弹出"无法验证此文件的数字签名"的错误提示,由于一个错误,造成系统无法正常运行,怎么办?真是急死人,特别是着急的要使用电脑的情况,针对此疑问,小编分享一 ...

  8. Windows 无法验证此文件的数字签名。原来是这个原因。解决方案1: 关闭Secure Boot

    Windows 无法验证此文件的数字签名.某软件或硬件最近有所更改,可能安装了签名错误或损毁的文件,或者安装的文件可能是来路不明的恶意软件. 原因: 有部分Windows10  OEM 版本会出现此问 ...

  9. Windows 无法验证此文件的数字签名。

    项目场景: 提示:这里简述项目相关背景:Windows 无法验证此文件的数字签名.某软件或硬件最近有所更改,可能安装了签名错误或损毁的文件,或者安装的文件可能是来路不明的恶意软件 问题描述 `提示:这 ...

最新文章

  1. 清华校友斩获ACM博士论文奖!相关研究为自动驾驶新算法奠定基础
  2. 03 | AOF 日志:宕机了, Redis 如何避免数据丢失?
  3. php生成网页按钮,JavaScript实现自动生成网页元素功能(按钮、文本等)_javascript技巧...
  4. 【数学】Floating-Point Hazard
  5. 【iCore4 双核心板_uC/OS-II】例程一:认识 uC/OS-II
  6. 个人课中所学vlan相关知识整理
  7. eXtremeComponents 中文参考文档
  8. 武田2020财年第三季度业绩彰显增长加速和持续的韧性;确认了2020财年全年管理层指引,并上调了自由现金流以及列报每股盈利的预测
  9. 互联网产品经理好书推荐
  10. ecilpse写html图片,eclipse怎么导入图片
  11. linux操作系统adsl 上网设置,Linux操作系统上ADSL拨号上网的方法详解
  12. android如何释放资源文件,Android中的垃圾资源如何清理?
  13. keras导入weights方式
  14. 中国服务器连通状态,ppp服务器连通状态显示失败怎么办?
  15. 2020南京大学软件学院夏令营模拟机试题集
  16. java 输入一串字符串 字符串长度不超过100
  17. 世界是平的读后感(转,整理)
  18. 锐捷(一)清除三层交换机配置
  19. 【趋势科技实习录】 PIT testing with OSCE11
  20. 切片、切块、钻取和旋转

热门文章

  1. 企业为何选择企业云盘而不是个人云盘呢?
  2. 写一篇1500字的积极分子思想汇报,分别从思想,学习,工作,生活方面写
  3. 京东物流、日日顺供应链、顺丰们能否在“疫”下找到物流的最优解?
  4. ESP32 经典蓝牙 连接 Xbox ONE 手柄
  5. go每日新闻(2021-08-02)——互联网架构大会(GIAC)摘录
  6. 聚小宝 微商管家 php源码,聚小宝管家
  7. iPhone4最新降级教程(iOS5.1.1)
  8. Android中四大组件(四大天王)
  9. nrf52832之定时器
  10. 【短临预报系列第一篇】Convolutional LSTM Network: A Machine LearningApproach for Precipitation Nowcasting