二维码登陆流程实战分析

0x00 前言

熟悉二维码登陆流程。

0x01 分析QQ空间二维码登陆

首先这个二维码图片是固定URL,所以根据通过cookie信息生成的,每次二维码的内容都不一样。

现在再看看轮询。

轮询URL如下

https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https://qzs.qzone.qq.com/qzone/v5/loginsucc.html?para=izone&ptqrtoken=287729277&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-1526529701371&js_ver=10270&js_type=1&login_sig=UHGwp5N9-7RkaS6Yxi-VVY4JEi6l5J1VzZLc*O56amWQR0BUdHZ9V*ZGjY1WkW-f&pt_uistyle=40&aid=549000912&daid=5&

这里重点关注login_sig这个参数。但是这个参数从何而来尼?

通过chrome可知,这个轮询是由c_login_2.js这个文件发出来的。我们进入这个js脚本分析下,并且再该处下断点。

从这个脚本的函数可以看出来,就是加载js标签,从而加载js。但是明显现在加的URL并不是轮询的URL。一直执行到加载的URL是轮询URL。

通过观察函数堆栈,和变量值,loadScriptqrlogin_submitanonymous(从下图看出仅仅调用qrlogin_submit)这三个函数都已经直接使用login_sig,说明生成这个参数的代码还再前面。

然后分析了一遍qrlogin_submit(因为轮询的url在这里组装的),发现login_sig来自于pt.ptui

在看看i.onload,发现这里居然还是直接使用了pt.ptui的值,所以赋值的函数在堆栈销毁了。

在上图的地方下断,并且重新F5刷新下。最后在init函数发现了赋值操作。

原来就是获取cookie里面的pt_login_sig的值。

最后带上pt_login_sig进行轮询,如果已经授权,就会设置一大堆cookie,用户登陆成功。

那QQ空间二维码的登陆流程是:
1.随机生成cookie中的pt_login_sig,并根据此cookie生成二维码(与二维码关联)。
2.从cookie中获取pt_login_sig,带这个参数进行轮询。
3.我们进行扫码授权,从而使轮询能通过pt_login_sig,获取权限。
4.轮询到授权,于是设置一大堆cookie。从而实现登陆。

0x02 微信扫码登陆流程

首先看到图片使根据qrcode/YZASKKOBxA==生成的,如果我们随意修改qrcode后面的值的话,它使不会显示二维码的。说明首先要获取qrcode

直接ctl+shfit+f全局搜索,发现使用如下url进行获取qrcode。

https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage&fun=new&lang=zh_CN&_=1526537367159

通过qrcode获取二维码。

https://login.weixin.qq.com/qrcode/gfjqfQ51-A==

使用如下带uuid(也就是qrcode)的URL进行轮询

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=gfjqfQ51-A==&tip=0&r=-1824357599&_=1526537721892

进行扫码,但还没进行授权,轮询返回了微信头像。

设置cookie。

0x03 从网上找到的二维码登陆流程

1:打开二维码登录网页index.html
2:index.html调用GetQrCodeServlet
3:GetQrCodeServlet干2件事
a:生成随机的uuid,是一个唯一标识,该标识贯穿整个流程
b:生成二维码图片,二维码信息
4:index页面展示二维码
5:index页面调用LongConnectionCheckServlet进行长连接轮询操作,参数为uuid
6:LongConnectionCheckServlet只干1件事
a:拿到uuid后循环检查loginUserMap中uuid是否不为null。
7:如果为null则代表没有登录,index.html将继续进行轮询
ps: LongConnectionCheckServlet 一个长连接请求检测登录状态
loginUserMap 是一个静态的map结构的登录池,uuid为key , 登录信息为value~

0x04 参考

https://bbs.ichunqiu.com/thread-25923-1-1.html