18 KiB
OAuth to Account takeover
{% hint style="success" %}
学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 上关注 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 分享黑客技巧。
{% embed url="https://websec.nl/" %}
基本信息
OAuth 提供多种版本,基础信息可在 OAuth 2.0 文档 中获取。本讨论主要集中在广泛使用的 OAuth 2.0 授权码授权类型,提供一个 授权框架,使应用程序能够访问或在另一个应用程序中执行用户帐户的操作(授权服务器)。
考虑一个假设的网站 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 流程如下:
- 您导航到 https://example.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
- 然后您将看到一个同意页面。
- 在您批准后,社交媒体会向
redirect_uri
发送一个包含code
和state
参数的响应:
https://example.com?code=uniqueCode123&state=randomString123
- 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"}
- 最后,过程结束时,https://example.com 使用你的
access_token
向社交媒体发起 API 调用以访问
Vulnerabilities
Open 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 in redirect implementation
正如在这个漏洞赏金报告中提到的 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
在OAuth实现中,state
参数的误用或遗漏会显著增加跨站请求伪造(CSRF)攻击的风险。当state
参数未使用、作为静态值使用或未正确验证时,攻击者可以绕过CSRF保护,从而产生此漏洞。
攻击者可以通过拦截授权过程,将他们的账户与受害者的账户关联,从而导致潜在的账户接管。在使用OAuth进行身份验证的应用程序中,这一点尤其关键。
在各种CTF挑战和黑客平台中记录了此漏洞的真实案例,突显了其实际影响。该问题还扩展到与第三方服务的集成,如Slack、Stripe和PayPal,攻击者可以将通知或付款重定向到他们的账户。
正确处理和验证**state
参数**对于防范CSRF和保护OAuth流程至关重要。
Pre Account Takeover
- 在账户创建时未进行电子邮件验证:攻击者可以预先使用受害者的电子邮件创建账户。如果受害者稍后使用第三方服务登录,应用程序可能会不经意地将此第三方账户与攻击者预先创建的账户关联,从而导致未经授权的访问。
- 利用宽松的OAuth电子邮件验证:攻击者可能会利用不验证电子邮件的OAuth服务,通过注册其服务并将账户电子邮件更改为受害者的电子邮件来进行攻击。这种方法同样存在未经授权的账户访问风险,类似于第一种情况,但通过不同的攻击向量。
Disclosure of Secrets
识别和保护秘密的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
AWS Cognito
在这个漏洞赏金报告中:https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ 你可以看到 AWS Cognito 返回给用户的 令牌 可能具有 足够的权限来覆盖用户数据。因此,如果你可以 将用户电子邮件更改为其他用户的电子邮件,你可能能够 接管 其他账户。
# 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
正如在这篇文章中提到的,如果OAuth流程期望接收token(而不是代码),而没有检查token是否属于该应用程序,则可能会受到攻击。
这是因为攻击者可以在自己的应用程序中创建一个支持OAuth并使用Facebook登录的应用程序(例如)。然后,一旦受害者在攻击者的应用程序中使用Facebook登录,攻击者就可以获取分配给其应用程序的用户的OAuth token,并使用该token在受害者的OAuth应用程序中登录。
{% hint style="danger" %} 因此,如果攻击者设法让用户访问自己的OAuth应用程序,他将能够在期望token且未检查token是否授予其应用程序ID的应用程序中接管受害者的账户。 {% endhint %}
Two links & cookie
根据这篇文章,可以让受害者打开一个returnUrl指向攻击者主机的页面。这些信息将被存储在cookie(RU)中,在后续步骤中,提示将询问用户是否希望授予对该攻击者主机的访问权限。
为了绕过此提示,可以打开一个选项卡以启动Oauth流程,该流程将使用returnUrl设置此RU cookie,在提示显示之前关闭选项卡,然后打开一个没有该值的新选项卡。然后,提示不会通知攻击者的主机,但cookie将被设置为它,因此token将在重定向中发送到攻击者的主机。
Prompt Interaction Bypass
正如在这段视频中解释的,一些OAuth实现允许将**prompt
** GET参数指示为None(&prompt=none
),以防止用户在已登录平台时被要求确认所授予的访问权限。
response_mode
正如在这段视频中解释的,可能可以指示参数**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
根据这篇博客文章,这是一个允许通过用户名和密码在OAuth中登录的OAuth流程。如果在这个简单流程中返回一个具有用户可以执行的所有操作的访问权限的token,那么就可以使用该token绕过2FA。
SSRFs parameters
查看这项研究 以获取此技术的更多详细信息。
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提供者请阅读此内容以测试可能的竞争条件。
References
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
{% embed url="https://websec.nl/" %}
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.