PAYATHON 2026

WDAC 为什么仍阻止使用自签名证书签名的 .exe 运行?

数据小陈

WDAC 可以通过显式配置的签名者规则,允许运行使用自签名证书签名的普通用户模式 .exe。仅凭证书是自签名的,无法确定程序被阻止的原因;把证书导入证书存储区,也不代表文件已经满足 WDAC 策略。Microsoft 的 PowerShell App Control 指南提供了创建自签名代码签名证书并将其加入策略的示例。参考:Microsoft PowerShell App Control 指南

现有信息还无法确定唯一原因。建议先查看此次阻止对应的 CodeIntegrity 事件,再核对文件实际使用的证书和策略规则。

先从阻止事件确定检查方向

重新运行一次 test.exe,然后在事件查看器中打开以下日志:

Applications and Services Logs
  Microsoft
    Windows
      CodeIntegrity
        Operational

找到与执行时间对应的 3077 阻止事件,再通过 XML 视图中的 Correlation ActivityID 找到与之关联的 3089 签名信息事件。确认 File Name 指向的是 test.exe 还是程序加载的 DLL,并记录 PolicyId,以确定是哪份策略阻止了文件。参考:App Control 故障排查指南

重点查看 3089 中的这些字段:

  • TotalSignatureCount:是否识别到签名。
  • PublisherName、IssuerName:实际识别到的证书信息。
  • PublisherTBSHash、IssuerTBSHash:用于与策略中的证书规则核对。
  • VerificationError:签名验证或策略匹配失败的原因。

例如,VerificationError = 23 可能与文件或签名问题有关,ECC 签名是其中一种明确的触发情形;21 表示未通过 App Control 策略,26 表示被显式拒绝。不能仅凭“文件已签名”或“证书已安装”就判断规则应当命中。参考:App Control 事件字段说明

检查证书算法,SHA256 不代表 RSA

签名命令中的 /fd sha256 指定的是文件摘要算法,不能说明证书的公钥算法。

Microsoft 文档说明,App Control 的签名者规则支持 RSA,密钥长度最大为 4096 位;不支持 ECDSA 等 ECC 签名。如果证书使用 ECC,即使 TBS 值正确,也不能依靠该签名者规则放行。参考:App Control 文件规则及算法限制

如果确认使用了不支持的算法,可以换用兼容的 RSA 代码签名证书重新签名,并更新策略中的证书规则。只修改 /fd 不会改变证书算法。

核对文件实际使用的签名证书

先对发生故障的那一份文件执行:

signtool verify /pa /all /v "test.exe"

/pa 使用默认 Authenticode 验证策略,/all 检查文件中的所有签名。查看输出中的证书链、有效期和验证错误。这个结果用于检查 Authenticode 签名,不等同于 WDAC 的策略判定。参考:SignTool 参数说明

也可以在 PowerShell 中查看签名证书:

$sig = Get-AuthenticodeSignature -FilePath .\test.exe
$sig | Format-List Status, StatusMessage
$sig.SignerCertificate |
    Format-List Subject, Issuer, Thumbprint, NotBefore, NotAfter

原命令通过 /n "mycert" 按证书主题名称查找证书。需要确认选中的证书与生成 WDAC 规则时使用的是同一张,特别是在续期或重新生成过同名证书的情况下。

如需明确指定证书,可在签名前将下面的占位符替换为实际证书指纹:

signtool sign /s My /sha1 "CERTIFICATE_THUMBPRINT" /fd sha256 /ph /v "test.exe"

默认搜索当前用户的 My 存储区;只有私钥位于计算机存储区,并且当前进程有权使用它时,才使用 /sm:

signtool sign /sm /s My /sha1 "CERTIFICATE_THUMBPRINT" /fd sha256 /ph /v "test.exe"

这里的 /sha1 用于按证书指纹选择证书,文件摘要仍由 /fd sha256 指定。/ph 用于生成 page hashes,不是自签名证书的信任开关。参考:SignTool 签名选项

用证书生成用户模式规则,核对手写配置

你的 SigningScenario Value="12" 对应用户模式场景,适用于此处讨论的普通 .exe。仅凭这两个 XML 片段,无法判断完整策略是否具备所有必要配置。

可以在现有策略的工作副本上,使用 Add-SignerRule 根据实际签名证书生成规则,再与手写配置比较。下面假设 signer.cer 是从该文件实际使用的签名证书导出的公钥证书:

Add-SignerRule `
    -FilePath .\Policy.xml `
    -CertificatePath .\signer.cer `
    -User

-User 表示将签名者加入用户模式场景;-Update 用于策略更新签名者,不能代替应用程序放行规则。参考:Add-SignerRule

证书 Thumbprint、证书 TBS 哈希和可执行文件哈希是三个不同的值,不能互相替代。即使此前已核对过 TBS,也要确认核对的是 test.exe 当前签名中使用的证书。

确认修改的是实际阻止文件的策略

更新了策略文件,并不能单独证明本次执行由预期策略放行。根据 3077 中的 PolicyId 核对实际生效的策略。如果系统提供 CiTool.exe,可以用它列出策略:

CiTool.exe -lp -json

如果没有该工具,可以查看 CodeIntegrity 日志中的策略激活事件。重点检查是否有其他策略阻止了同一文件,以及被阻止的文件是否是依赖 DLL。参考:生效策略与阻止事件排查

另外,原描述中的 Certification Authority 没有明确指向哪个证书存储区,因此不能断定它是 Trusted Root Certification Authorities。如果 Authenticode 验证报告证书链错误,应核对具体存储位置;如果签名验证正常,再根据 WDAC 日志检查规则匹配情况。

修复后,重新签名并验证最终文件,按现有部署流程重新生成和部署策略,再执行一次程序并检查新事件。当前最需要补充的证据是关联 3089 的 VerificationError、实际签名证书算法,以及 3077 中的文件路径和 PolicyId。

备注:内容仅供参考。