# OAuth 转账户接管
从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)!
支持 HackTricks 的其他方式:
- 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版本的 HackTricks**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
- 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
- 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
- **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live) 上**关注**我们。
- 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) 的 github 仓库提交 PR 来**分享您的黑客技巧**。
{% embed url="https://websec.nl/" %}
## 基本信息
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 框架中理解以下组件至关重要:
- **资源所有者**:您作为**用户/实体**,授权访问您的资源,如您的社交媒体帐户帖子。
- **资源服务器**:在应用程序代表`资源所有者`获得`访问令牌`后,**管理经过身份验证的请求的服务器**,例如**https://socialmedia.com**。
- **客户端应用程序**:从`资源所有者`那里**寻求授权的应用程序**,例如**https://example.com**。
- **授权服务器**:在`资源所有者`成功验证并获得授权后,**向`客户端应用程序`发放`访问令牌`的服务器**,例如**https://socialmedia.com**。
- **client\_id**:应用程序的公共唯一标识符。
- **client\_secret**:应用程序和授权服务器独有的机密密钥,用于生成`访问令牌`。
- **response\_type**:指定**请求的令牌类型**的值,如`code`。
- **scope**:`客户端应用程序`从`资源所有者`请求的**访问级别**。
- **redirect\_uri**:**授权后用户被重定向到的 URL**。通常必须与预注册的重定向 URL 保持一致。
- **state**:一个参数,用于**在用户重定向到授权服务器和从授权服务器返回时保持数据**。其唯一性对于作为**CSRF 保护机制**至关重要。
- **grant\_type**:指示**授权类型和要返回的令牌类型**的参数。
- **code**:来自`授权服务器`的授权码,由客户端应用程序与`client_id`和`client_secret`一起使用,以获取`访问令牌`。
- **access\_token**:`客户端应用程序`用于代表`资源所有者`进行 API 请求的**令牌**。
- **refresh\_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 调用到社交媒体以访问
## 漏洞
### 开放式重定向 `redirect_uri`
`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
正如在此漏洞赏金报告中提到的 [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
test
```
### CSRF - Improper handling of state parameter
在OAuth实现中,**`state`参数** 的错误使用或省略会显著增加**跨站请求伪造(CSRF)** 攻击的风险。当 `state` 参数未被使用、被用作静态值或未经适当验证时,就会出现这种漏洞,使攻击者能够绕过CSRF保护。
攻击者可以通过拦截授权过程来利用这一点,将他们的账户与受害者的账户关联起来,从而导致潜在的**账户接管**。这在OAuth用于**认证目的**的应用程序中尤为关键。
这种漏洞的实际案例已在各种**CTF挑战**和**黑客平台**中有所记录,突显了其实际影响。这个问题还延伸到与第三方服务如**Slack**、**Stripe**和**PayPal**的集成,攻击者可以将通知或付款重定向到他们的账户。
对**`state`参数**的正确处理和验证对于防范CSRF攻击并保护OAuth流程至关重要。
### Pre Account Takeover
1. **在账户创建时没有进行电子邮件验证**:攻击者可以预先使用受害者的电子邮件创建一个账户。如果受害者后来使用第三方服务进行登录,应用程序可能会无意中将这个第三方账户与攻击者预先创建的账户关联起来,导致未经授权的访问。
2. **利用宽松的OAuth电子邮件验证**:攻击者可能会利用不验证电子邮件的OAuth服务,通过注册其服务然后将账户电子邮件更改为受害者的电子邮件。这种方法类似于第一种情况,但通过不同的攻击向量,同样存在未经授权的账户访问风险。
### 揭示秘密
识别和保护秘密的OAuth参数至关重要。虽然**`client_id`**可以安全地公开,但透露**`client_secret`**会带来重大风险。如果`client_secret`泄露,攻击者可以利用应用程序的身份和信任来**窃取用户的`access_tokens`**和私人信息。
当应用程序错误地在客户端而不是服务器端处理授权`code`以换取`access_token`时,就会出现常见的漏洞。这个错误导致`client_secret`暴露,使攻击者能够在应用程序的名义下生成`access_tokens`。此外,通过社会工程学,攻击者可以通过向OAuth授权添加额外的范围来提升权限,进一步利用应用程序的受信任状态。
### 客户端密钥暴力破解
您可以尝试使用身份提供者**暴力破解服务提供商的client\_secret**,以尝试窃取账户。\
BF请求可能类似于:
```
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
在这份漏洞赏金报告中:[**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"
}
]
}
```
### 滥用其他应用程序的令牌
正如[**在这篇文章中提到的**](https://salt.security/blog/oh-auth-abusing-oauth-to-take-over-millions-of-accounts),期望接收**令牌**(而不是代码)的OAuth流程可能存在漏洞,如果它们不检查令牌是否属于该应用程序。
这是因为攻击者可以创建一个**支持OAuth并使用Facebook登录**(例如)的应用程序。然后,一旦受害者在**攻击者的应用程序**中使用Facebook登录,攻击者就可以获取**用户授予其应用程序的OAuth令牌,并使用它登录受害者OAuth应用程序,使用受害者的用户令牌**。
{% hint style="danger" %}
因此,如果攻击者成功让用户访问自己的OAuth应用程序,他将能够接管期望令牌的应用程序中的受害者帐户,并且不检查令牌是否授予其应用程序ID。
{% endhint %}
### 两个链接和cookie
根据[**这篇文章**](https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f),可以让受害者打开一个带有指向攻击者主机的**returnUrl**的页面。这些信息将被**存储在一个cookie(RU)**中,在**后续步骤**中,**提示**将**询问用户**是否愿意授予该攻击者主机访问权限。
为了绕过此提示,可以打开一个标签页来启动**Oauth流程**,该流程将使用**returnUrl**设置此RU cookie,然后在显示提示之前关闭标签页,并打开一个不带该值的新标签页。然后,**提示不会提及攻击者主机**,但cookie将被设置为该主机,因此**令牌将被发送到攻击者主机**进行重定向。
### SSRF参数
**[查看此研究](https://portswigger.net/research/hidden-oauth-attack-vectors) 以获取此技术的更多详细信息。**
OAuth中的动态客户端注册作为安全漏洞的一个不太明显但关键的向量,特别是用于**服务器端请求伪造(SSRF)**攻击。此端点允许OAuth服务器接收有关客户端应用程序的详细信息,包括可能被利用的敏感URL。
**关键点:**
- **动态客户端注册**通常映射到`/register`,通过POST请求接受诸如`client_name`、`client_secret`、`redirect_uris`和用于logo或JSON Web Key Sets(JWKs)的URL等详细信息。
- 此功能遵循**RFC7591**和**OpenID Connect Registration 1.0**中规定的规范,其中包括可能容易受到SSRF攻击的参数。
- 注册过程可能会以几种方式无意中使服务器暴露于SSRF:
- **`logo_uri`**:客户端应用程序的logo的URL,服务器可能会获取该URL,触发SSRF或如果URL处理不当可能导致XSS。
- **`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。