前言
本文是关于如何在安全断言标记语言(Security Assertion Markup Language,SAML)中查找Bug的系列文章中的第二篇。本文将研究SAML漏洞,以及如何使用BurpSuite插件SAML Raider测试这些漏洞。如果您对于SAML和XML签名还没有一个大体的知识脉络,那么请查看我们介绍基础知识的第I部分。
SAML RAIDER
本文的第一个知识点是学习SAML Raider。SAML Raider是一款具有强大功能的SAML测试工具。SAML Raider的创建者Roland Bischofberger和Emanuel Duss将该插件描述为用于测试SAML基础架构的Burp Suite扩展。它包含两个核心功能:操作SAML消息以及X.509证书管理系统的能力。
在本文中,我们将使用SAML Raider演示如何测试每个漏洞。我们将从安装开始。
如果您已经熟悉如何使用SAML Raider,请直接跳到XML签名包装。
安装SAML RAIDER
打开Burp Suite并单击Extender选项卡
单击BApp Store子选项卡
向下滚动并单击扩展列表中的SAML Raider
单击“安装”按钮
安装完成后,我们将看到一个名为“SAML Raider Certificates”的新选项卡。
上面提到的选项卡是SAML Raider执行证书管理的地方,我们下一步将对此进行讨论。
X.509证书管理器
内置在SAML Raider中的证书管理器非常好用。它允许我们执行以下操作:
导入和导出X.509证书
显示X.509证书信息
导入和导出私钥
克隆X.509证书和证书链
编辑和自签署现有的X.509证书
我们花点时间测试一下这些功能。
首先,我们需要X.509证书。我们可以使用OpenSSL快速地生成一个。
openssl req -x509 -newkey rsa:4096 -keyout /tmp/key.pem -out /tmp/cert.pem -days 365 -nodes
═══════════════════════════════════════════════════════════════════════════════════════════
Generating a 4096 bit RSA private key
...........++
...........................................................................................................................++
writing new private key to '/tmp/key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
现在我们有了证书,让我们按照下面描述的步骤将其导入SAML Raider。
完成后,我们将在顶部窗格中看到导入的证书,在底部窗格中看到有关证书的所有相关信息。
导出就像导入一样简单,所以我们不会花时间进行演示。让我们来看看克隆和编辑。克隆证书非常简单。我们需要做的就是突出显示要克隆的证书,然后单击上面窗格左侧的“Clone(克隆)”按钮。完成后,我们同时拥有导入的证书和原始版本的几乎完全相同的副本。原始和克隆之间只有两个不同点——模块和签名。我们可以通过首先导出克隆的证书,然后运行下面的diff命令来进行验证。
diff <(openssl x509 -in /tmp/cloned-cert.pem -text -noout) <(openssl x509 -in /tmp/cert.pem -text -noout)
除了克隆功能,我们可以根据自己的喜好更改证书的字段,然后单击“Save and Self-Sign”。自签名操作的功能类似于“克隆”(Clone),但需要注意的是,新证书包含了之前更改的字段。
在流程完成后,我们拥有一个有效期为1000年的证书。在执行下面讨论的一些攻击时,管理证书的能力开始发挥作用。
SAML消息编辑器
除了证书管理器之外,SAML Raider还提供了动态操作SAML消息的能力。在本节中,我们将研究截取请求,以及截取请求后该如何处理它们。
SAML Raider的创建者捆绑了一个方便的脚本来对扩展进行一些轻量级测试。我们将使用该脚本生成SAML响应,方便我们可以在burp中检查和操作。
首先,我们需要脚本。即使我们已经通过burp安装了SAML Raider,我们需要的脚本也在repo中。当我们的测试完成时,克隆repo并将其全部删除是最简单的。
git clone https://github.com/SAMLRaider/SAMLRaider.git
克隆了repo后,我们可以转到脚本目录。
cd SAMLRaider/scripts/samltest
在那之后,随着burp运行和拦截,我们可以运行samltest。
./samltest
如果burp处于运行状态并进行拦截,我们将在burp中看到等待我们的SAML响应。
截获后,我们可以在SAML Raider选项卡中查看SAML响应。
我们试着篡改一些数据。我们将拉到到SAML响应的底部,找到AttributeValue标签中包含的bowser@saml.lan值。
我们将bowser改为mario
篡改完成后,我们将在响应上进行转发。一旦它被转发,我们会看到它返回给我们的侦听器-先前启动的samltest脚本。脚本打印出XML,我们可以看到Mario@saml.lan。
...
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn">
<AttributeValue>bowser@saml.lan</AttributeValue>
</Attribute>
<Attribute Name="http://schemas.xmlsoap.org/claims/Group">
<AttributeValue>Domänen-Benutzer</AttributeValue>
</Attribute>
<Attribute Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<AttributeValue>mario@saml.lan</AttributeValue>
</Attribute>
</AttributeStatement>
...
编辑SAML消息时,Ctrl+Z不能撤消错误。有一个“Reset Message”按钮,用于将SAML消息恢复到其原始值。
SAML中继器
最后一点值得注意的是,SAML Raider在Burp的Repeater选项卡中添加了一个选项卡。在Repeater选项卡中操作SAML消息对于不断修改同一消息非常有用。
XML签名包装
我们将讨论的第一个攻击是XML签名包装(XSW)。这里有一份白皮书概述了攻击的详细情况。巧合的是,这篇论文也系统地介绍了SAML Raider插件。如果你想深入了解更多信息,白皮书相信是你的第一选择。
XSW基本前提是,包含XML签名的XML文档可以分两步处理:一步用于数字签名的验证,另一步用于使用XML数据的实际应用程序。考虑以下两个步骤以及用于获取单个XML元素的方法:
XML签名验证:
应用程序定位<ds:Signature>
的<ds:Reference>
元素。
应用程序使用<ds:Reference>
的URL属性来确定对哪个XML元素进行了签名。
应用程序验证签名的xml元素。
验证后,同一应用程序尝试使用签名数据作为其正常操作的一部分。
应用程序的XML解析器使用自上而下的基于树的导航来定位其所需的XML元素
通常,这两种方法都应该定位到相同的XML元素,但在签名包装的情况下,攻击者会将签名的内容移动到不同的位置,并将其替换为攻击者控制的XML元素,该元素不会使XML文档无效。我们希望XML解析器找到攻击者控制的元素,而不是经过验证的元素。
现在我们已经了解了XSW的基本概念,让我们看看执行XSW的不同方法。下面介绍的每个XML签名包装攻击都与打包到SAML Raider中的8个攻击直接对应。了解了这一点,我们将了解攻击是如何工作的,以及如何使用SAML Raider执行攻击。
简要回顾
在开始之前,让我们回顾一下正常的SAML响应的简化结构。这里的关键组件是响应及其ID、签名及其引用的URL属性以及断言的主题。
<?xml version="1.0" encoding="UTF-8"?>
<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>
<ds:KeyInfo>...</ds:KeyInfo>
</ds:Signature>
<samlp:Status>...</samlp:Status>
<saml:Assertion ...>
<saml:Issuer>...</saml:Issuer>
<ds:Signature ... >...</ds:Signature>
<saml:Subject>
<saml:NameID ...>...</saml:NameID>
<saml:SubjectConfirmation ...>
<saml:SubjectConfirmationData .../>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions ...>...</saml:Conditions>
<saml:AuthnStatement ...>...</saml:AuthnStatement>
<saml:AttributeStatement>...</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
回想一下,当标识提供者(IDP)返回服务提供者(SP)时,我们会收到SAML响应(下面流程图中的步骤6)。
XML签名包装攻击-1
XSW-1处理SAML响应。它复制SAML响应和断言,然后将原始签名作为复制的响应的子元素插入到XML中。假设XML解析器在签名验证后在文档顶部找到并使用复制的响应,而不是原始的签名响应.
XML签名包装攻击-2
与XSW-1类似,XSW-2处理SAML响应。XSW-1和XSW-2是唯一处理响应的两种攻击方式。-1和-2之间的关键区别在于,XSW-2使用的签名类型是分离的签名,其中XSW-1使用封装签名。恶意响应的位置保持不变。
XML签名包装攻击-3
XSW-3是包装断言元素的XSW的第一个示例。SAML Raider将复制的Assertion作为根Response元素的第一个子元素插入。原始断言是复制的断言的兄弟节点。
XML签名包装攻击-4
XSW-4类似于-3,除了在这种情况下,原始断言成为复制的断言的子节点。
XML签名包装攻击-5
XSW-5是断言包装的第一个实例,我们看到签名和原始断言不在三种标准配置中的任何一个(封装/分离)。在这种情况下,复制的断言封装签名。
XML签名包装攻击-6
XSW-6将其复制的断言插入到与-4和-5相同的位置。这里有趣的一点是,复制的断言封装了签名,而签名又封装了原始断言。
XML签名包装攻击-7
XSW-7插入一个扩展元素,并将复制的断言作为子元素添加。扩展是具有限制性较小的架构定义的有效XML元素。本白皮书的作者针对OpenSAML库开发了此方法。OOpenSAML使用模式验证来正确地将签名验证期间使用的ID与处理的断言的ID进行比较。作者发现,在复制的断言与原始断言的ID相同的情况下,如果复制的断言是具有较少限制的模式定义的元素的子元素,则可以绕过此特定对策。
XML签名包装攻击#8
XSW-8使用另一个限制性较小的XML元素来执行XSW#7中使用的攻击模式的变体。这一次,原始断言是限制较少的元素的子元素,而不是复制的断言。
XML签名包装方法
SAML Raider可以很容易地执行签名包装攻击。第一步是制定拦截规则拦截SAML消息。首先转到Proxy
选项卡,然后是Options
子选项卡。然后,创建或编辑具有与下面的参数匹配的规则。
有了规则,我们就可以开始拦截了,而且我们只捕获包含SAMLResponse参数的http请求。
一旦拦截了SAML响应,我们将通过按Ctrl+r或右键单击请求并使用上下文菜单单击Send to Repeater,将请求发送到Burp的Repeater。
要执行多个XSW攻击,我们需要保留原始请求。在某些情况下,中继器中的SAML Raider选项卡无法使用“重置消息”按钮将已被篡改的SAML响应恢复到其原始状态。这就是为什么我们将原始文件保存在代理中,并继续将原始文件发送到Repeater。
一旦我们在Repeater中收到请求,我们就可以打开SAML Raider选项卡。
接下来,使用SAML Raider选项卡中的下拉列表并实现其中一种XSW攻击就变得毫不费力。
在使用签名包装攻击后,可以单击go发送更改后的SAML响应。
如果要尝试其他XSW攻击,则需要将原始消息重新发送到中继器。然后应用我们想要尝试的下一个XSW攻击。我们这样做是为了确保基本消息保持一致,并且在执行其他攻击时不会留下以前攻击的痕迹。
如果尝试XSW的过程中导致访问服务提供商,请立即注销并重复此过程。使用有效的XSW,尝试篡改任何看起来像用户标识的可能参数的属性(例如,将user1更改为admin,等等)。
未完待续:
原文:https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/