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

7.1 KiB
Raw Blame History

从零开始学习AWS黑客技术成为 htARTEHackTricks AWS红队专家

支持HackTricks的其他方式

SAML概述

**安全断言标记语言SAML**使身份提供者IdP能够向服务提供者SP发送授权凭据实现单点登录SSO。这种方法通过允许在多个网站之间使用一组凭据来简化多个登录的管理。它利用XML在IdP和SP之间进行标准化通信将用户身份的认证与服务授权联系起来。

SAML和OAuth的比较

  • SAML旨在为企业提供更大的SSO登录安全控制。
  • OAuth旨在更适合移动设备使用JSON并是来自Google和Twitter等公司的协作努力。

SAML认证流程

有关更多详细信息,请查看来自https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/的完整文章。这是一个摘要:

SAML认证过程涉及多个步骤如图示

https://epi052.gitlab.io/notes-to-self/img/saml/saml-flow.jpg

  1. 资源访问尝试:用户尝试访问受保护的资源。
  2. 生成SAML请求SP未识别用户并生成SAML请求。
  3. 重定向到IdP用户被重定向到IdPSAML请求通过用户的浏览器传递。
  4. IdP接收请求IdP接收SAML请求。
  5. IdP身份验证IdP对用户进行身份验证。
  6. 用户验证IdP验证用户是否有权访问请求的资源。
  7. 生成SAML响应IdP生成包含必要断言的SAML响应。
  8. 重定向到SP的ACS URL用户被重定向到SP的断言消费者服务ACSURL。
  9. 验证SAML响应ACS验证SAML响应。
  10. 授予资源访问权限:授予对最初请求的资源的访问权限。

SAML请求示例

考虑这样一个场景:用户请求访问https://shibdemo-sp1.test.edu/secure/上的安全资源。SP识别到缺乏身份验证并生成一个SAML请求

GET /secure/ HTTP/1.1
Host: shibdemo-sp1.test.edu
...

原始的 SAML 请求如下所示:

<?xml version="1.0"?>
<samlp:AuthnRequest ...
</samlp:AuthnRequest>

以下是此请求的关键要素:

  • AssertionConsumerServiceURL:指定 IdP 在身份验证后应将 SAML 响应发送到的位置。
  • Destination:发送请求的 IdP 地址。
  • ProtocolBinding:定义 SAML 协议消息的传输方法。
  • saml:Issuer:标识发起请求的实体。

在生成 SAML 请求后SP 会以 302 重定向 响应,将浏览器重定向到 IdP并在 HTTP 响应的 Location 标头中编码 SAML 请求。 RelayState 参数在整个交易过程中保持状态信息,确保 SP 在接收 SAML 响应时能识别最初的资源请求。 SAMLRequest 参数是原始 XML 片段的压缩和编码版本,使用 Deflate 压缩和 base64 编码。

SAML 响应示例

您可以在此处找到完整的 SAML 响应。响应的关键组件包括:

  • ds:Signature:这部分是 XML 签名,确保断言的发出者的完整性和真实性。示例中的 SAML 响应包含两个 ds:Signature 元素,一个用于消息,另一个用于断言。
  • saml:Assertion:此部分包含有关用户身份以及可能的其他属性的信息。
  • saml:Subject:指定断言中所有语句的主体主题。
  • saml:StatusCode:表示响应对应请求的操作状态。
  • saml:Conditions:详细说明断言的有效时间和指定的服务提供商等条件。
  • saml:AuthnStatement:确认 IdP 对断言的主体进行了身份验证。
  • saml:AttributeStatement:包含描述断言主体的属性。

在 SAML 响应之后,流程包括 IdP 发出的 302 重定向。这导致向服务提供商的 Assertion Consumer Service (ACS) URL 发送 POST 请求。POST 请求包括 RelayStateSAMLResponse 参数。ACS 负责处理和验证 SAML 响应。

收到 POST 请求并验证 SAML 响应后,将授予用户最初请求的受保护资源的访问权限。这通过向 /secure/ 端点发出 GET 请求和 200 OK 响应来说明,表示成功访问资源。

XML 签名

XML 签名具有多功能性,能够签署整个 XML 树或其中的特定元素。它们可以应用于任何 XML 对象,而不仅仅是响应元素。以下是 XML 签名的关键类型:

XML 签名的基本结构

XML 签名由如下基本元素组成:

<Signature>
<SignedInfo>
<CanonicalizationMethod />
<SignatureMethod />
<Reference>
<Transforms />
<DigestMethod />
<DigestValue />
</Reference>
...
</SignedInfo>
<SignatureValue />
<KeyInfo />
<Object />
</Signature>

每个Reference元素表示一个特定的资源被签名可通过URI属性进行识别。

XML签名类型

  1. 包含签名这种类型的签名是资源的后代意味着签名包含在与签名内容相同的XML结构中。

示例:

<samlp:Response ... ID="..." ... >
...
<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
</ds:Signature>
...
</samlp:Response>

在包含签名中,ds:Transform元素指定通过enveloped-signature算法进行包含。

  1. 包裹签名:与包含签名相反,包裹签名将被签名的资源包装起来。

示例:

<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
<samlp:Response ... ID="..." ... >
...
</samlp:Response>
</ds:Signature>
  1. 分离签名:这种类型与其签名的内容是分离的。签名和内容是独立存在的,但两者之间保持链接。

示例:

<samlp:Response ... ID="..." ... >
...
</samlp:Response>
<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
</ds:Signature>

总之XML签名提供了灵活的方式来保护XML文档每种类型都满足不同的结构和安全需求。

参考资料