本文编写于 788 天前,最后修改于 737 天前,其中某些信息可能已经过时。
本文部分参考、摘录自LF112巨佬的 在?康康QQ协议 感谢前人对我的启发.

何为Skey?

Skey是腾讯各类业务中鉴权用到的钥匙,早些年有些诈骗/钓鱼手段就是利用各种方法获取到Skey之后模拟用户登录空间或操作其他地方从而欺骗其好友达到想要的目的。

至于为何突然想要获取到skey,是因为最近在折腾腾讯的"家校群"在这其中的作业功能提供了一个基本的在线作业的雏形。但是既然是雏形就肯定有我需要但他没有的功能,便想能不能自己动手实现一个。

简单分析

抓了一下手Q的包,大概结构如下
URL:https://qun.qq.com/cgi-bin/qun/web/hw/get_hw_feedback
这里是获取单个作业的提交情况
POST参数:group_id=QQ群号&hw_id=作业ID&page=数据页数&page_size=每页大小&status=不知干嘛用的状态
cookies:skey=Skey本尊; uin=我的QQ号;

这些是最终测试下来的必须参数,也有一个参数可以获取作业内的单个成员提交的作业,但是那个我觉得没必要就直接去掉了...

模拟登录

我们平时在网页上登陆一次QQ,可以通过扫码的方式登录;这样的方式不仅很快速并且不用验证码这个要增加解决成本的东西,我们便可试着从二维码登陆入手。

  • 以下步骤可通过打开浏览器的console复现
  • 所有请求需要携带所有请求后cookies的交集

    获取二维码

    ​‌‌‌​‌​​​​​‌‌​‌​‍​‌​‌‌‌​​‌‌‌‌​‌​‍​‌​​‌​​​‌​​​‌‌​‍​​‌‌​​​‌​​‌‌​‌​‍​‌‌‌‌‌‌​​​​‌​‌​‌‍‌​‌​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍‌​‌‌‌‌​‌‍‌​​‌​​‌‌‍‌​​‌​​​​‍‌​​‌‌​​​‍​​‌‌​‌​​​​​‌​​‌‍​‌​‌‌‌​‌​‌‌​‌‌​‍​‌‌‌​​​​‌​​​‌​‌‌‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌​‌‌‌‌‌‌‌‌​​​‍​‌‌​​‌‌‌​‌‌​​‌‌‌‍​‌‌​​​‌‌‌​​​‌​‌‍​​‌‌‌‌‌‌‌‌​​‌‌‍​​‌‌​​​‌​​‌‌​‌​‍​​​‌​​​‌‌‌‌​‌​​‍​​​‌​​​‌‌‌‌​‌​​‍​‌​​‌‌​​‌‌‌‌‌​‌‍​‌‌​​​​‌​‌​‌​‌​‍​‌‌‌‌‌​​​‌​​‌​​​‍​‌​‌‌​​​​‌​‌​​‌‍​‌​‌‌​‌‌‌​​‌‌‌‌‍‌​‌​‌‌‌​‍‌​‌​‌‌‌​‍​​​‌​​‌​‌‌‌‌​‌‌‍‌​‌​‌‌​​‍‌​​‌​‌​​‍‌​​‌‌​‌​‍‌​​​​‌‌​‍​‌‌​​​‌​​​‌‌​‌​‍​‌​‌‌​​​​‌‌​‌​‌‍​‌‌‌​​​​​​‌​‌‌‌‌‍​​​‌​‌​‌‌​‌​‌‌‌‍​‌​‌‌​‌‌‌​​‌‌‌‌‍​‌​​‌​​‌​​‌‌​​‌‍​‌‌​​​‌‌​​‌‌‌‌‌‍​‌‌​​​‌‌‌​‌​​‌​‍‌‌​‌​‌‌‌‍​‌‌‌​‌​​​​​‌​​​​‍​​‌‌‌‌‌‌‌‌​​‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​​​‌​‌​‌‌​​‌‌‌​‍‌​​‌​​​​‍‌​​​‌​‌​‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍​‌‌​​​‌​‌‌‌​​​‌‍‌‌​​‌‌​‌‍‌‌​​‌‌‌‌‍‌‌​​‌‌‌​‍‌‌​​​‌‌​‍‌‌​‌​​‌​‍‌‌​​‌‌‌​‍‌‌​​‌‌‌‌‍‌‌​‌​​‌​‍‌‌​​‌‌‌‌‍‌‌​​‌​​‌‍​​‌‌‌​‌‌​‌‌‌‌‌‌‍​‌​‌‌‌​​‌‌​​‌‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌‌​‌​​‌‌‌‌​​​‍​‌​‌​​​‌‌​​‌‌‌‌‍​‌​‌​​​‌​‌‌‌‌‌‌‍​​​​​​​​‌‌‌​​‌​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​​‌‌‌‌‍‌​​​‌‌​​‍‌‌​​​‌​‌‍‌​‌​​​‌‌‍‌​‌​​​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​​‌‌​‌‍‌​​‌‌‌​‌‍‌​​​‌‌‌​‍‌‌​‌​​​‌‍‌​​‌‌‌​​‍‌​​‌​​​‌‍‌​‌​​​‌‌‍‌​​‌‌​‌​‍‌​​​​‌‌‌‍‌​​​‌‌‌‌‍‌​‌​​​‌‌‍‌​​‌‌​​​‍‌​​‌‌​‌​‍‌​​​‌​‌‌‍‌​‌​​​​​‍‌​​​‌‌​​‍‌​​‌​‌​​‍‌​​‌‌​‌​‍‌​​​​‌‌​‍‌‌​‌​​​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​‌​​‌​‍‌​​‌​​‌‌

    请求https://ssl.ptlogin2.qq.com/ptqrshow?appid=715030901
    即可返回一个二维码,一些辅助参数:

  • appid 腾讯业务识别码,一般来说和群有关的内容就用715030901就够了,暂时没有探究APPID不同是否会影响到最后skey的权限是否有异。
  • e 整数,调整二维码的边框留白大小。最大值是4,超过会被拒绝访问。
  • t 时间戳,原本以为这个参数应该参与整个过程,但是经过实验,发现这个参数应该是仅在与服务端时间差异很大的时候起辅助作用。不影响正常验证。

获取到二维码的同时,我们还需要拿到cookies中名为qrsig的东西,顾名思义应该是本次获取到的二维码的签名,在之后的步骤中要用到。

获得登录请求

现在我们需要通知服务器"我要来登陆了"。
请求https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=715030901&s_url=https%3A%2F%2Fqq.com
后会返回一个页面,我们不需要管他。
我们需要关注两个参数:

  • appid 需要与之前一致(也许)
  • s_url 登录成功后跳转的页面,这里只需要是腾讯系的网址即可。

访问后我们获取cookies里面名为pt_login_sig的字符串即可,其他的我们不需要。

建立心跳

拿着之前两步获取到的qrsigpt_login_sig,我们需要计算一下ptqrtoken

代码实现:

PHP (感谢LF112巨佬)
function get_ptqrtoken($sigs) {
    $len = strlen($sigs);
    $hash = 0;
    for ($i = 0; $i < $len; $i++) 
        $hash += (($hash << 5) & 2147483647) + ord($sigs[$i]);
    return $hash & 2147483647;
}

JS(互联网收集)

function(t){
for(var e=0,i=0,n=t.length;i<n;++i)
e+=(e<<5)+t.charCodeAt(i);
return 2147483647&e
}

原理大致是把每位字符的ASCII与long int的最大值相与,具体细节在这里不刨析。

https://ssl.ptlogin2.qq.com/ptqrlogin?u1={上一步设置的返回的URL}&ptqrtoken={计算后的qrsig}&from_ui=1&login_sig={pt_login_sig}&aid=715030901
所有参数不要去动,已是最简,否则会报参数错误

这个链接将会返回一段内容

ptuiCB('66','0','','0','二维码未失效。(526388540)', '')

其中,第一个参数就是二维码的对应状态,如下:

  • 66 => 正在等待二维码扫描
  • 65 => 二维码已失效
  • 67 => 正在等待确认
  • 0 => 登录成功

请求频率推荐1秒一次,二维码有效期大概是1分钟左右。

登录成功后将会返回一段内容

ptuiCB('0','0','https://qq.com','1','登录成功!', '时光')

接下来,Skey就会存在于本页面的cookies之中。取出来就可以以该账号的身份进行操作啦~

怎么用?

等待更新...