mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-15 01:17:36 +00:00
247 lines
18 KiB
Markdown
247 lines
18 KiB
Markdown
# OAuth to Account takeover
|
||
|
||
{% hint style="success" %}
|
||
学习与实践 AWS 黑客技术:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks 培训 AWS 红队专家 (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
学习与实践 GCP 黑客技术:<img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks 培训 GCP 红队专家 (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>支持 HackTricks</summary>
|
||
|
||
* 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass) 或 **在 Twitter 上关注** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 分享黑客技巧。
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
||
|
||
{% embed url="https://websec.nl/" %}
|
||
|
||
## 基本信息 <a href="#d4a8" id="d4a8"></a>
|
||
|
||
OAuth 提供多种版本,基础信息可在 [OAuth 2.0 文档](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 调用以访问
|
||
|
||
## Vulnerabilities <a href="#id-323a" id="id-323a"></a>
|
||
|
||
### Open 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 in redirect implementation <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 - Improper handling of state parameter <a href="#bda5" id="bda5"></a>
|
||
|
||
在OAuth实现中,**`state`参数**的误用或遗漏会显著增加**跨站请求伪造(CSRF)**攻击的风险。当`state`参数**未使用、作为静态值使用或未正确验证**时,攻击者可以绕过CSRF保护,从而产生此漏洞。
|
||
|
||
攻击者可以通过拦截授权过程,将他们的账户与受害者的账户关联,从而导致潜在的**账户接管**。在使用OAuth进行**身份验证**的应用程序中,这一点尤其关键。
|
||
|
||
在各种**CTF挑战**和**黑客平台**中记录了此漏洞的真实案例,突显了其实际影响。该问题还扩展到与第三方服务的集成,如**Slack**、**Stripe**和**PayPal**,攻击者可以将通知或付款重定向到他们的账户。
|
||
|
||
正确处理和验证**`state`参数**对于防范CSRF和保护OAuth流程至关重要。
|
||
|
||
### Pre Account Takeover <a href="#ebe4" id="ebe4"></a>
|
||
|
||
1. **在账户创建时未进行电子邮件验证**:攻击者可以预先使用受害者的电子邮件创建账户。如果受害者稍后使用第三方服务登录,应用程序可能会不经意地将此第三方账户与攻击者预先创建的账户关联,从而导致未经授权的访问。
|
||
2. **利用宽松的OAuth电子邮件验证**:攻击者可能会利用不验证电子邮件的OAuth服务,通过注册其服务并将账户电子邮件更改为受害者的电子邮件来进行攻击。这种方法同样存在未经授权的账户访问风险,类似于第一种情况,但通过不同的攻击向量。
|
||
|
||
### Disclosure of Secrets <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 Bruteforce
|
||
|
||
您可以尝试**暴力破解服务提供商的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** 返回给用户的 **令牌** 可能具有 **足够的权限来覆盖用户数据**。因此,如果你可以 **将用户电子邮件更改为其他用户的电子邮件**,你可能能够 **接管** 其他账户。
|
||
```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"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
For more detailed info about how to abuse AWS cognito check:
|
||
|
||
{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}
|
||
|
||
### Abusing other Apps tokens <a href="#bda5" id="bda5"></a>
|
||
|
||
正如[**在这篇文章中提到的**](https://salt.security/blog/oh-auth-abusing-oauth-to-take-over-millions-of-accounts),如果OAuth流程期望接收**token**(而不是代码),而没有检查token是否属于该应用程序,则可能会受到攻击。
|
||
|
||
这是因为**攻击者**可以在自己的应用程序中创建一个**支持OAuth并使用Facebook登录的应用程序**(例如)。然后,一旦受害者在**攻击者的应用程序**中使用Facebook登录,攻击者就可以获取**分配给其应用程序的用户的OAuth token,并使用该token在受害者的OAuth应用程序中登录**。
|
||
|
||
{% hint style="danger" %}
|
||
因此,如果攻击者设法让用户访问自己的OAuth应用程序,他将能够在期望token且未检查token是否授予其应用程序ID的应用程序中接管受害者的账户。
|
||
{% endhint %}
|
||
|
||
### Two links & 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将在重定向中发送到攻击者的主机**。
|
||
|
||
### Prompt Interaction Bypass <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 flow - 2 FA bypass <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。
|
||
|
||
### SSRFs parameters <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密钥集(JWKs)等详细信息。
|
||
* 此功能遵循**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 providers Race Conditions
|
||
|
||
如果您正在测试的平台是OAuth提供者[**请阅读此内容以测试可能的竞争条件**](race-condition.md)。
|
||
|
||
## References
|
||
|
||
* [**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)
|
||
|
||
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
|
||
|
||
{% embed url="https://websec.nl/" %}
|
||
|
||
{% hint style="success" %}
|
||
Learn & practice AWS Hacking:<img src="../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
Learn & practice GCP Hacking: <img src="../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>Support HackTricks</summary>
|
||
|
||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||
|
||
</details>
|
||
{% endhint %}
|