mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
224 lines
16 KiB
Markdown
224 lines
16 KiB
Markdown
# OAuth 到账户接管
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
## 基本信息 <a href="#d4a8" id="d4a8"></a>
|
||
|
||
OAuth 提供了多种版本,基础信息可在 [OAuth 2.0 documentation](https://oauth.net/2/) 中获取。本讨论主要集中在广泛使用的 [OAuth 2.0 授权码授权类型](https://oauth.net/2/grant-types/authorization-code/),提供一个 **授权框架,使应用程序能够访问或在另一个应用程序中执行用户账户的操作**(授权服务器)。
|
||
|
||
考虑一个假设的网站 _**https://example.com**_,旨在 **展示您所有的社交媒体帖子**,包括私人帖子。为此,采用 OAuth 2.0。_https://example.com_ 将请求您 **访问您的社交媒体帖子** 的权限。因此,_https://socialmedia.com_ 上会出现一个同意屏幕,概述 **请求的权限和发起请求的开发者**。在您授权后,_https://example.com_ 获得 **代表您访问您的帖子** 的能力。
|
||
|
||
理解 OAuth 2.0 框架中的以下组件至关重要:
|
||
|
||
- **资源拥有者**:您,作为 **用户/实体**,授权访问您的资源,例如您的社交媒体账户帖子。
|
||
- **资源服务器**:在应用程序代表 `资源拥有者` 获取 `access token` 后,**管理经过身份验证请求的服务器**,例如 **https://socialmedia.com**。
|
||
- **客户端应用程序**:向 `资源拥有者` 请求授权的 **应用程序**,例如 **https://example.com**。
|
||
- **授权服务器**:在成功验证 `资源拥有者` 并获得授权后,**向 `客户端应用程序` 发放 `access tokens` 的服务器**,例如 **https://socialmedia.com**。
|
||
- **client_id**:应用程序的公共唯一标识符。
|
||
- **client_secret**:仅为应用程序和授权服务器所知的机密密钥,用于生成 `access_tokens`。
|
||
- **response_type**:指定 **请求的令牌类型** 的值,例如 `code`。
|
||
- **scope**:`客户端应用程序` 请求的 **访问级别**。
|
||
- **redirect_uri**:用户在授权后被重定向的 **URL**。这通常必须与预注册的重定向 URL 对齐。
|
||
- **state**:一个参数,用于 **在用户重定向到授权服务器及返回时维护数据**。其唯一性对于作为 **CSRF 保护机制** 至关重要。
|
||
- **grant_type**:指示 **授权类型和要返回的令牌类型** 的参数。
|
||
- **code**:来自 `授权服务器` 的授权码,客户端应用程序与 `client_id` 和 `client_secret` 一起使用以获取 `access_token`。
|
||
- **access_token**:客户端应用程序代表 `资源拥有者` 用于 API 请求的 **令牌**。
|
||
- **refresh_token**:使应用程序能够 **在不重新提示用户的情况下获取新的 `access_token`**。
|
||
|
||
### 流程
|
||
|
||
**实际的 OAuth 流程** 如下:
|
||
|
||
1. 您导航到 [https://example.com](https://example.com) 并选择“与社交媒体集成”按钮。
|
||
2. 然后该网站向 [https://socialmedia.com](https://socialmedia.com) 发送请求,请求您的授权以让 https://example.com 的应用程序访问您的帖子。请求结构如下:
|
||
```
|
||
https://socialmedia.com/auth
|
||
?response_type=code
|
||
&client_id=example_clientId
|
||
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
|
||
&scope=readPosts
|
||
&state=randomString123
|
||
```
|
||
3. 然后您会看到一个同意页面。
|
||
4. 在您批准后,社交媒体会向 `redirect_uri` 发送包含 `code` 和 `state` 参数的响应:
|
||
```
|
||
https://example.com?code=uniqueCode123&state=randomString123
|
||
```
|
||
5. https://example.com 利用这个 `code`,连同它的 `client_id` 和 `client_secret`,向服务器发起请求以代表您获取 `access_token`,从而访问您同意的权限:
|
||
```
|
||
POST /oauth/access_token
|
||
Host: socialmedia.com
|
||
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
|
||
```
|
||
6. 最后,过程结束时 https://example.com 使用您的 `access_token` 进行 API 调用以访问
|
||
|
||
## 漏洞 <a href="#id-323a" id="id-323a"></a>
|
||
|
||
### 开放的 redirect_uri <a href="#cc36" id="cc36"></a>
|
||
|
||
`redirect_uri` 对于 OAuth 和 OpenID 实现的安全性至关重要,因为它指示在授权后敏感数据(如授权代码)发送到何处。如果配置错误,可能会允许攻击者将这些请求重定向到恶意服务器,从而实现账户接管。
|
||
|
||
利用技术根据授权服务器的验证逻辑而异。它们可以从严格的路径匹配到接受指定域或子目录内的任何 URL。常见的利用方法包括开放重定向、路径遍历、利用弱正则表达式和 HTML 注入进行令牌窃取。
|
||
|
||
除了 `redirect_uri`,其他 OAuth 和 OpenID 参数如 `client_uri`、`policy_uri`、`tos_uri` 和 `initiate_login_uri` 也容易受到重定向攻击。这些参数是可选的,其支持在不同服务器之间有所不同。
|
||
|
||
对于那些针对 OpenID 服务器的攻击者,发现端点(`**.well-known/openid-configuration**`)通常列出有价值的配置细节,如 `registration_endpoint`、`request_uri_parameter_supported` 和 "`require_request_uri_registration`。这些细节可以帮助识别注册端点和服务器的其他配置细节。
|
||
|
||
### 重定向实现中的 XSS <a href="#bda5" id="bda5"></a>
|
||
|
||
正如在这个漏洞赏金报告中提到的 [https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html](https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html),重定向 **URL 可能在用户认证后被反射在服务器的响应中**,因此 **容易受到 XSS 攻击**。可能的测试有效载荷:
|
||
```
|
||
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
|
||
```
|
||
### CSRF - 不当处理状态参数 <a href="#bda5" id="bda5"></a>
|
||
|
||
在OAuth实现中,**`state`参数**的误用或遗漏会显著增加**跨站请求伪造(CSRF)**攻击的风险。当`state`参数**未使用、作为静态值使用或未正确验证**时,攻击者可以绕过CSRF保护。
|
||
|
||
攻击者可以通过拦截授权过程,将他们的账户与受害者的账户链接,从而导致潜在的**账户接管**。在使用OAuth进行**身份验证**的应用程序中,这尤其关键。
|
||
|
||
在各种**CTF挑战**和**黑客平台**中记录了此漏洞的真实案例,突显了其实际影响。该问题还扩展到与第三方服务的集成,如**Slack**、**Stripe**和**PayPal**,攻击者可以将通知或付款重定向到他们的账户。
|
||
|
||
正确处理和验证**`state`参数**对于防范CSRF和保护OAuth流程至关重要。
|
||
|
||
### 预账户接管 <a href="#ebe4" id="ebe4"></a>
|
||
|
||
1. **在账户创建时未进行电子邮件验证**:攻击者可以预先使用受害者的电子邮件创建账户。如果受害者稍后使用第三方服务登录,应用程序可能会不经意地将此第三方账户链接到攻击者预先创建的账户,从而导致未经授权的访问。
|
||
2. **利用宽松的OAuth电子邮件验证**:攻击者可能会利用不验证电子邮件的OAuth服务,通过注册其服务并将账户电子邮件更改为受害者的电子邮件来进行攻击。这种方法同样存在未经授权的账户访问风险,类似于第一种情况,但通过不同的攻击向量。
|
||
|
||
### 秘密泄露 <a href="#e177" id="e177"></a>
|
||
|
||
识别和保护秘密OAuth参数至关重要。虽然**`client_id`**可以安全披露,但泄露**`client_secret`**会带来重大风险。如果`client_secret`被泄露,攻击者可以利用应用程序的身份和信任来**窃取用户的`access_tokens`**和私人信息。
|
||
|
||
一个常见的漏洞出现在应用程序错误地在客户端而非服务器端处理授权`code`与`access_token`的交换。这一错误导致`client_secret`的暴露,使攻击者能够以应用程序的名义生成`access_tokens`。此外,通过社会工程学,攻击者可以通过向OAuth授权添加额外的范围来提升权限,进一步利用应用程序的信任状态。
|
||
|
||
### 客户端密钥暴力破解
|
||
|
||
您可以尝试通过身份提供者**暴力破解服务提供者的client_secret**以窃取账户。\
|
||
暴力破解的请求可能类似于:
|
||
```
|
||
POST /token HTTP/1.1
|
||
content-type: application/x-www-form-urlencoded
|
||
host: 10.10.10.10:3000
|
||
content-length: 135
|
||
Connection: close
|
||
|
||
code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]
|
||
```
|
||
### Referer Header leaking Code + State
|
||
|
||
一旦客户端拥有了 **code 和 state**,如果它们在浏览到不同页面时 **反映在 Referer 头中**,那么就存在漏洞。
|
||
|
||
### Access Token Stored in Browser History
|
||
|
||
前往 **浏览器历史记录,检查访问令牌是否保存在其中**。
|
||
|
||
### Everlasting Authorization Code
|
||
|
||
**授权代码应该只存在一段时间,以限制攻击者可以窃取和使用它的时间窗口**。
|
||
|
||
### Authorization/Refresh Token not bound to client
|
||
|
||
如果你可以获取 **授权代码并在不同的客户端上使用它,那么你可以接管其他账户**。
|
||
|
||
### Happy Paths, XSS, Iframes & Post Messages to leak code & state values
|
||
|
||
[**查看此帖子**](https://labs.detectify.com/writeups/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-2-xss-on-sandbox-third-party-domain-that-gets-the-url)
|
||
|
||
### AWS Cognito <a href="#bda5" id="bda5"></a>
|
||
|
||
在这个漏洞赏金报告中:[**https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/**](https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/) 你可以看到 **AWS Cognito** 返回给用户的 **token** 可能具有 **足够的权限来覆盖用户数据**。因此,如果你可以 **将用户邮箱更改为其他用户邮箱**,你可能能够 **接管** 其他账户。
|
||
```bash
|
||
# Read info of the user
|
||
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]
|
||
|
||
# Change email address
|
||
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
|
||
{
|
||
"CodeDeliveryDetailsList": [
|
||
{
|
||
"Destination": "i***@f***.com",
|
||
"DeliveryMedium": "EMAIL",
|
||
"AttributeName": "email"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
对于如何滥用 AWS cognito 的更详细信息,请查看:
|
||
|
||
{{#ref}}
|
||
https://cloud.hacktricks.wiki/en/pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum.html
|
||
{{#endref}}
|
||
|
||
### 滥用其他应用程序令牌 <a href="#bda5" id="bda5"></a>
|
||
|
||
正如 [**在这篇文章中提到的**](https://salt.security/blog/oh-auth-abusing-oauth-to-take-over-millions-of-accounts),期望接收 **token**(而不是代码)的 OAuth 流程可能会受到攻击,如果它们没有检查该 token 是否属于该应用程序。
|
||
|
||
这是因为 **攻击者** 可以在自己的应用程序中创建一个 **支持 OAuth 并使用 Facebook 登录的应用程序**(例如)。然后,一旦受害者在 **攻击者的应用程序** 中使用 Facebook 登录,攻击者就可以获取 **分配给其应用程序的用户的 OAuth token,并使用它在受害者的 OAuth 应用程序中登录,使用受害者的用户 token**。
|
||
|
||
> [!CAUTION]
|
||
> 因此,如果攻击者设法让用户访问自己的 OAuth 应用程序,他将能够在期望 token 且未检查 token 是否授予其应用程序 ID 的应用程序中接管受害者的帐户。
|
||
|
||
### 两个链接和 cookie <a href="#bda5" id="bda5"></a>
|
||
|
||
根据 [**这篇文章**](https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f),可以让受害者打开一个指向攻击者主机的 **returnUrl** 的页面。此信息将被 **存储在 cookie (RU)** 中,在 **后续步骤** 中,**提示** 将 **询问** **用户** 是否希望授予对该攻击者主机的访问权限。
|
||
|
||
为了绕过此提示,可以打开一个选项卡以启动 **Oauth 流程**,该流程将使用 **returnUrl** 设置此 RU cookie,在提示显示之前关闭选项卡,然后打开一个没有该值的新选项卡。然后,**提示不会通知攻击者的主机**,但 cookie 将被设置为它,因此 **token 将在重定向中发送到攻击者的主机**。
|
||
|
||
### 提示交互绕过 <a href="#bda5" id="bda5"></a>
|
||
|
||
正如 [**在这段视频中解释的**](https://www.youtube.com/watch?v=n9x7_J_a_7Q),某些 OAuth 实现允许将 **`prompt`** GET 参数指示为 None (**`&prompt=none`**) 以 **防止用户在已登录平台时被要求确认** 在网页上授予的访问权限。
|
||
|
||
### response_mode
|
||
|
||
正如 [**在这段视频中解释的**](https://www.youtube.com/watch?v=n9x7_J_a_7Q),可能可以指示参数 **`response_mode`** 以指示希望在最终 URL 中提供代码的位置:
|
||
|
||
- `response_mode=query` -> 代码在 GET 参数中提供: `?code=2397rf3gu93f`
|
||
- `response_mode=fragment` -> 代码在 URL 片段参数中提供 `#code=2397rf3gu93f`
|
||
- `response_mode=form_post` -> 代码在一个名为 `code` 的 POST 表单中提供,并带有值
|
||
- `response_mode=web_message` -> 代码通过 post 消息发送: `window.opener.postMessage({"code": "asdasdasd...`
|
||
|
||
### OAuth ROPC 流程 - 2 FA 绕过 <a href="#b440" id="b440"></a>
|
||
|
||
根据 [**这篇博客文章**](https://cybxis.medium.com/a-bypass-on-gitlabs-login-email-verification-via-oauth-ropc-flow-e194242cad96),这是一个允许通过 **用户名** 和 **密码** 登录 OAuth 的 OAuth 流程。如果在这个简单流程中返回一个具有用户可以执行的所有操作的访问权限的 **token**,那么就可以使用该 token 绕过 2FA。
|
||
|
||
### 基于开放重定向到引用者的网页重定向 ATO <a href="#bda5" id="bda5"></a>
|
||
|
||
这篇 [**博客文章**](https://blog.voorivex.team/oauth-non-happy-path-to-ato) 评论了如何利用 **开放重定向** 从 **引用者** 的值滥用 OAuth 进行 ATO。攻击步骤如下:
|
||
|
||
1. 受害者访问攻击者的网页
|
||
2. 受害者打开恶意链接,打开者开始使用 `response_type=id_token,code&prompt=none` 作为附加参数的 Google OAuth 流程,引用者为 **攻击者网站**。
|
||
3. 在打开者中,提供者在授权受害者后,将他们发送回 `redirect_uri` 参数的值(受害者网站),并带有 30X 代码,这仍然保持攻击者网站在引用者中。
|
||
4. 受害者 **网站根据引用者触发开放重定向**,将受害者用户重定向到攻击者网站,因为 **`respose_type`** 是 **`id_token,code`**,代码将通过 URL 的 **片段** 返回给攻击者,从而使他能够通过 Google 在受害者网站上接管用户的帐户。
|
||
|
||
### SSRFs 参数 <a href="#bda5" id="bda5"></a>
|
||
|
||
[**查看这项研究**](https://portswigger.net/research/hidden-oauth-attack-vectors) **以获取此技术的更多详细信息。**
|
||
|
||
OAuth 中的动态客户端注册作为一个不太明显但关键的安全漏洞向量,特别是针对 **服务器端请求伪造 (SSRF)** 攻击。此端点允许 OAuth 服务器接收有关客户端应用程序的详细信息,包括可能被利用的敏感 URL。
|
||
|
||
**关键点:**
|
||
|
||
- **动态客户端注册** 通常映射到 `/register`,并接受如 `client_name`、`client_secret`、`redirect_uris` 和通过 POST 请求的 logo 或 JSON Web Key Sets (JWKs) 的 URL 等详细信息。
|
||
- 此功能遵循 **RFC7591** 和 **OpenID Connect Registration 1.0** 中列出的规范,其中包括可能对 SSRF 易受攻击的参数。
|
||
- 注册过程可能会以多种方式无意中使服务器暴露于 SSRF:
|
||
- **`logo_uri`**:客户端应用程序 logo 的 URL,服务器可能会获取该 URL,从而触发 SSRF 或导致 XSS(如果 URL 处理不当)。
|
||
- **`jwks_uri`**:客户端 JWK 文档的 URL,如果恶意构造,可能导致服务器向攻击者控制的服务器发出外部请求。
|
||
- **`sector_identifier_uri`**:引用 `redirect_uris` 的 JSON 数组,服务器可能会获取该数组,从而创建 SSRF 机会。
|
||
- **`request_uris`**:列出客户端允许的请求 URI,如果服务器在授权过程开始时获取这些 URI,则可能被利用。
|
||
|
||
**利用策略:**
|
||
|
||
- 通过在 `logo_uri`、`jwks_uri` 或 `sector_identifier_uri` 等参数中注册带有恶意 URL 的新客户端,可以触发 SSRF。
|
||
- 尽管通过白名单控制可能会减轻直接通过 `request_uris` 的利用,但提供一个预注册的、攻击者控制的 `request_uri` 可以在授权阶段促进 SSRF。
|
||
|
||
## OAuth 提供者竞争条件
|
||
|
||
如果您正在测试的平台是 OAuth 提供者 [**请阅读此内容以测试可能的竞争条件**](race-condition.md)。
|
||
|
||
## 参考文献
|
||
|
||
- [**https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1**](https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1)
|
||
- [**https://portswigger.net/research/hidden-oauth-attack-vectors**](https://portswigger.net/research/hidden-oauth-attack-vectors)
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|