OAuth 到账户接管
Reading time: 20 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
基本信息
OAuth 提供了多种版本,基础信息可在 OAuth 2.0 documentation 中获取。本讨论主要集中在广泛使用的 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 调用以访问
漏洞
开放的 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,重定向 URL 可能在用户认证后被反射在服务器的响应中,因此 容易受到 XSS 攻击。可能的测试有效载荷:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - 不当处理状态参数
在OAuth实现中,state
参数的误用或遗漏会显著增加跨站请求伪造(CSRF)攻击的风险。当state
参数未使用、作为静态值使用或未正确验证时,攻击者可以绕过CSRF保护。
攻击者可以通过拦截授权过程,将他们的账户与受害者的账户链接,从而导致潜在的账户接管。在使用OAuth进行身份验证的应用程序中,这尤其关键。
在各种CTF挑战和黑客平台中记录了此漏洞的真实案例,突显了其实际影响。该问题还扩展到与第三方服务的集成,如Slack、Stripe和PayPal,攻击者可以将通知或付款重定向到他们的账户。
正确处理和验证**state
参数**对于防范CSRF和保护OAuth流程至关重要。
预账户接管
- 在账户创建时未进行电子邮件验证:攻击者可以预先使用受害者的电子邮件创建账户。如果受害者稍后使用第三方服务登录,应用程序可能会不经意地将此第三方账户链接到攻击者预先创建的账户,从而导致未经授权的访问。
- 利用宽松的OAuth电子邮件验证:攻击者可能会利用不验证电子邮件的OAuth服务,通过注册其服务并将账户电子邮件更改为受害者的电子邮件来进行攻击。这种方法同样存在未经授权的账户访问风险,类似于第一种情况,但通过不同的攻击向量。
秘密泄露
识别和保护秘密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
AWS Cognito
在这个漏洞赏金报告中:https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ 你可以看到 AWS Cognito 返回给用户的 token 可能具有 足够的权限来覆盖用户数据。因此,如果你可以 将用户邮箱更改为其他用户邮箱,你可能能够 接管 其他账户。
# 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 的更详细信息,请查看:
AWS - Cognito Unauthenticated Enum - HackTricks Cloud
滥用其他应用程序令牌
正如 在这篇文章中提到的,期望接收 token(而不是代码)的 OAuth 流程可能会受到攻击,如果它们没有检查该 token 是否属于该应用程序。
这是因为 攻击者 可以在自己的应用程序中创建一个 支持 OAuth 并使用 Facebook 登录的应用程序(例如)。然后,一旦受害者在 攻击者的应用程序 中使用 Facebook 登录,攻击者就可以获取 分配给其应用程序的用户的 OAuth token,并使用它在受害者的 OAuth 应用程序中登录,使用受害者的用户 token。
caution
因此,如果攻击者设法让用户访问自己的 OAuth 应用程序,他将能够在期望 token 且未检查 token 是否授予其应用程序 ID 的应用程序中接管受害者的帐户。
两个链接和 cookie
根据 这篇文章,可以让受害者打开一个指向攻击者主机的 returnUrl 的页面。此信息将被 存储在 cookie (RU) 中,在 后续步骤 中,提示 将 询问 用户 是否希望授予对该攻击者主机的访问权限。
为了绕过此提示,可以打开一个选项卡以启动 Oauth 流程,该流程将使用 returnUrl 设置此 RU cookie,在提示显示之前关闭选项卡,然后打开一个没有该值的新选项卡。然后,提示不会通知攻击者的主机,但 cookie 将被设置为它,因此 token 将在重定向中发送到攻击者的主机。
提示交互绕过
正如 在这段视频中解释的,某些 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 流程 - 2 FA 绕过
根据 这篇博客文章,这是一个允许通过 用户名 和 密码 登录 OAuth 的 OAuth 流程。如果在这个简单流程中返回一个具有用户可以执行的所有操作的访问权限的 token,那么就可以使用该 token 绕过 2FA。
基于开放重定向到引用者的网页重定向 ATO
这篇 博客文章 评论了如何利用 开放重定向 从 引用者 的值滥用 OAuth 进行 ATO。攻击步骤如下:
- 受害者访问攻击者的网页
- 受害者打开恶意链接,打开者开始使用
response_type=id_token,code&prompt=none
作为附加参数的 Google OAuth 流程,引用者为 攻击者网站。 - 在打开者中,提供者在授权受害者后,将他们发送回
redirect_uri
参数的值(受害者网站),并带有 30X 代码,这仍然保持攻击者网站在引用者中。 - 受害者 网站根据引用者触发开放重定向,将受害者用户重定向到攻击者网站,因为
respose_type
是id_token,code
,代码将通过 URL 的 片段 返回给攻击者,从而使他能够通过 Google 在受害者网站上接管用户的帐户。
SSRFs 参数
查看这项研究 以获取此技术的更多详细信息。
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 提供者 请阅读此内容以测试可能的竞争条件。
参考文献
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。