54

二维码劫持原理及恶意行为分析

 4 years ago
source link: https://www.freebuf.com/articles/web/199057.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

*严正声明:本文仅用于教育和技术讨论目的,严禁用于非法用途。

*本文作者:VoltCary,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

之前看过其他的二维码登陆劫持漏洞,有的地方写的不是很详细,花了不少时间去研究二维码的原理,才弄懂漏洞。为了照顾更多入门新手,以本人的理解重新总结一遍,二维码登陆原理不是这里的主题,不过有必要熟悉一下流程。

1.打开登陆地方,选择扫描二维码登陆,此时加载二维码;
2.客户端开始轮询,即与服务器建立长连接,来检测二维码状态;
3.用户打开手机扫描二维码,此时二维码为“scan”状态,网页向服务器不断向授权服务器轮询授权码;
4.用户手机看到“确认登陆”按钮,点击此按钮向授权服务器申请授权,允许此二维码授权,二维码为“confirm”状态(如果超时失效,为“timeout”状态);
5.用户点击“确认登陆”后,网页轮询到授权码,此时带授权码申请凭证,成功登陆网站,进入个人中心。

问题解构

利用长轮询实现微信网页版扫码登录:

https://blog.csdn.net/x2145637/article/details/52795809 

这里有个疑问,二维码几十秒就会过期,怎么办?可以自己写个浏览器插件实时提取出请求里面返回的状态参数,二维码会有一定的过期时间,过期会有对应的状态,监控此状态即可,比如状态参数securityId和二维码字符barcode,并更新securityId状态到本地,若timeout则刷新二维码;攻击者从本地将barcode当字符串生成自己的二维码图片放在自己的网站上,js一直轮询本地的securityId状态

这里用微信二维码作为例子,查看二维码状态情况;

访问 https://wx2.qq.com/ ,页面如下:

iIrUJrv.jpg!web

访问此页面时,其实浏览器与服务器之间会建立一个长连接,用于监控二维码状态。

监控接口为:

https://login.wx2.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=YZm-nRUSFQ==&tip=1&r=-104081975&_=1550587274887

m2yyQvq.jpg!web 201相当于“scan”状态,手机扫描成功时二维码的状态,手机上点击后监控状态返回如下:

FjQBziI.jpg!web

200相当于“confirm”状态,即用户点击确认返回的状态。并且直接返回凭证window.redirect_uri,此时只要复制此凭证到其它浏览器访问,直接可登陆网页版微信。

二维码链接为:

https://login.weixin.qq.com/qrcode/Qe3ev-uOPg==

即二维码字符为Qe3ev-uOPg==,当二维码过期,只需更新此字符Qe3ev-uOPg==即可,更新二维码字符接口:

https://login.weixin.qq.com/jslogin

appid=wx782c26e4c19acffb&fun=new&lang=zh_CN

Jv2eInq.jpg!web

通过上述可实时更新二维码到自己网站,不用担心过期问题。

无“确认登陆”按钮

第一种漏洞,用户扫描二维码直接登陆,没有任何提示,大家都知道,一般扫描二维码会有“确认登陆”等提示,如果没有此提示,容易被攻击者钓鱼伪造,诱导用户扫描,比如某APP扫描二维码有红包领取,用户只要扫描则被劫持,导致账号被攻击者登陆。这里用乌云的案例演示。。

可以欺骗劫持进入来往用户的帐号: http://www.anquan.us/static/bugs/wooyun-2013-040673.html

来往登陆二维码扫描时无任何提示,伪装为加好友的二维码,用户以为是加好友的二维码,,其实是登陆的二维码,当用户扫描时,攻击者那边可直接登陆用户账号,目前这种漏洞不多了,扫码时基本上都会有登陆等提示

登陆票据盗取

这个漏洞刚开始看的时候,以为是CSRF,,因为大佬们把它归类为CSRF类型,但是我看的时候发现与传统的CSRF完全不一样,导致一直以CSRF的思维去研究,被误导了。其实就是票据盗取,构造凭证URL,从而劫持用户的账号。

登陆确认票据盗取,如果没有任何签名保护,攻击者可以直接点击获取的票据拼接链接进行登陆,其实这里应该是在轮询步骤出现漏洞,用户扫描二维码后,客户端不断轮询请求服务器,而此次只是验证某个令牌等参数来确认用户,只要获取此令牌参数值,则可以冒充用户。

取个乌云上的例子,比如 登陆确认请求如下:

http://szsupport.weixin.qq.com/cgi-bin/mmsupport-bin/qrcodelogin?username=*********&key=*************&clientversion=25030133&devicetype=android8&lan=zh_CN&uuid=AXBIICc4sUSDsFnefkNP&pass_ticket=DebNjGnP2dJnq1bMvHvgL%2BezqqE70Ry9iWB625%2FRT8RRnwCD3tlq3qxuxG5YPzhx

其中uuid为二维码字符,usename为微信号,uuid值怎么获取,文章前面部分已经讲过,usename改为要劫持用户的微信号,key值是未知的,这里只要知道key的值可通过此链接登陆目标微信号。

Referer获取key思路:URL跳转、引用站外图片处,把跳转的URL、图片改为攻击者自己网站的URL,只要受害用户点击 构造好的URL,会跳转到攻击者网站,此时在攻击者服务器请求包的Referer里,就会看到key值,当然如果跳转处URL有key才可以,否则就去寻找带有key传递的地方,进行构造,只要能构造出向攻击者服务器发送一个请求即可。

上述获取key值之后,拼接登陆请求的链接,在浏览器里访问如下: fmAbae7.jpg!web

点击“确认登陆”直接登陆受害用户微信账号。

二维码CSRF漏洞

为啥这里是CSRF?上面却只是票据盗取,因为上面的“登陆确认”是不需要用户触发,构造URL后由攻击者直接触发。这里的CSRF漏洞是因为攻击者无法代替用户直接触发“登陆确认“按钮,必须以用户自己的身份触发,类似平常的增加、删除的CSRF,此处只是针对“登陆确认”的CSRF,当然,这里还需要用户先扫描二维码,而不能让用户直接触发“登陆确认”的请求,如果点击二维码链接就相当于扫描二维码的话,可直接构造POC。

当用户扫描二维码,构造一个隐藏iframe表单CSRF POC,用户扫描二维码时,此POC自动提交“确认登陆”的请求,造成CSRF漏洞,这样说大家都能看懂吧。这里我网上找了个例子做演示。

挖洞经验 | Facebook的手机扫码登录漏洞 https://cloud.tencent.com/developer/article/1044256

解释一下这个案例,洞主把“确认登陆”的链接抓包出来,用浏览器打开此链接,点击“Allow Login”抓包,构造CSRF的POC,此为第一个POC,由于缺少用户扫码步骤,文章前面我提到过,用户要先扫描二维码,再触发“Allow Login”的CSRF,因此才有了第二个POC,增加了扫码的步骤。

*本文作者:VoltCary,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK