XML签名HMAC截断绕过漏洞解析与修复指南

本文详细分析了MS10-041漏洞的技术细节,该漏洞存在于.NET Framework的XML签名实现中,允许攻击者通过设置HMACOutputLength为0来篡改受签名保护的数据而不被检测。文章提供了PowerShell检测脚本和修复方案。

MS10-041: XML签名HMAC截断绕过漏洞

今天,我们发布了MS10-041安全更新,解决了.NET Framework中XML签名功能实现的一个问题,该漏洞被评定为“重要”严重等级。我们在此进一步阐明此案例。

我是否面临风险?

没有Microsoft产品受此漏洞影响。但是,使用System.Security.Cryptography.Xml.SignedXml.CheckSignature(KeyedHashAlgorithm macAlg)方法的.NET应用程序容易受到攻击。请注意,只有接受KeyedHashAlgorithm参数的CheckSignature()方法受到影响——其他CheckSignature()方法不受影响。

任何运行调用此方法的应用程序的用户都应尽快安装此更新。该更新无需重新编译这些应用程序即可提供保护。

如果您允许自动安装更新,则无需执行其他操作。一旦安装了更新,您的应用程序将免受此漏洞的影响。此外,经过广泛评估,我们将此漏洞的整体可利用性指数评定为3,这意味着我们认为在不久的将来不太可能出现有效的利用代码。

攻击者能做什么?

如公告所述,此漏洞可能使攻击者能够修改受XML签名保护的数据而不被检测。篡改的影响取决于特定应用程序如何使用受影响的数据,但不太可能导致任意代码执行。

背景信息

XML签名的一个特性是能够在签名中嵌入一个称为HMACOutputLength的值,该值告诉接收方检查签名的位数。然而,规范并未要求规范的实现强制执行此字段的最小值。

在.NET实现以及其他供应商的实现中,没有强制执行最小HMACOutputLength值,因此中间人攻击者可以将此值设置为0,然后篡改XML的内容而不被检测。

更新后的规范现在规定,实现必须验证HMACOutputLength >= MAX(80, HalfOfTheBitsTheSignatureMethodGenerates)

XML签名由W3C在此文档中定义:http://www.w3.org/TR/xmldsig-core/

如何确定计算机上是否有受影响的应用程序

.NET Framework SDK附带了一个反汇编工具,可以从.NET二进制文件中提取IL代码。以下PowerShell脚本为执行脚本的文件夹下的每个.EXE和.DLL文件调用此工具,并检查工具的输出以告诉您是否有任何二进制文件调用了易受攻击的函数。要运行此PowerShell脚本,如果您不使用Windows 7(PowerShell随Windows 7提供),则需要安装PowerShell,并且需要安装.NET Framework SDK或Visual Studio,最后更新脚本的第一行以指向计算机上安装ildasm.exe的位置。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$PathToILDASM = C:\Program Files\Microsoft.NET\SDK\2.0\Bin
$FilesToScan = get-childitem -Filter *.exe -Recurse
$FilesToScan += get-childitem -Filter *.dll -Recurse
Found " + $FilesToScan.Count + " EXE and DLL file(s) to scan
""
Binaries that contain calls to System.Security.Cryptography.Xml.SignedXml.CheckSignature(KeyedHashAlgorithm macAlg):”
foreach($File in $FilesToScan)
{
$FileName = $File.FullName
if (([string]$FileName).Length -gt 0)
{
$Process = New-Object -typeName System.Diagnostics.Process
$Process.StartInfo.WorkingDirectory = (get-location).Path
$Process.StartInfo.UseShellExecute = $false
$Process.StartInfo.RedirectStandardOutput = $true
$Process.StartInfo.RedirectStandardError = $true
$Process.StartInfo.FileName = [System.IO.Path]::Combine($PathToILDASM, ildasm.exe)
$Process.StartInfo.Arguments = /OUT=temp.txt `"$FileName` /NOBAR"
$Process.Start() | out-null
$Process.WaitForExit()
if (Test-Path temp.txt)
{
$Disassembly = Get-Content temp.txt
del temp.txt
if (([string]$Disassembly).Contains(“callvirt instance bool [System.Security]System.Security.Cryptography.Xml.SignedXml::CheckSignature(class [mscorlib]System.Security.Cryptography.KeyedHashAlgorithm)”))
{
$File.FullName
}
}
}
}

致谢

感谢Shawn Farkas、Damian Hasse、Joe Hemmerlein、Alex Lucas和Andrew Roths对此博客文章的帮助!

  • Kevin Brown, MSRC Engineering
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计