九零登录

[【通过】] qq浏览器免费wifi功能逆向初探

[复制链接]
发表于 2016-9-9 10:38:26 | 显示全部楼层 |阅读模式

By:axiao
QQbroswer版本qqbrowser_6.9.2.2665_20820
时间2016/8/30最新版
抓包获取到请求的ip地址与参数信息
图片1.png
每次请求都有2条同时产生,对第2条请求进行重放,发现返回包内容一样,故确定每次获取只需要一次请求即可,不存在第一次是发送什么token之类的请求

图片2.png
搜寻参数中关键字tk=   iv=   encrypt=
在WUPTask类中找到tk位置

图片3.png
并在上方发现函数名decryptWithToken,所在函数方法名为getResponseData,猜测是解密响应数据包的函数
进入decryptWithToken函数所在类,找到构造url参数的函数buildUrlParam,从之后得到的加密算法是aes,得出参数中iv就是加解密的iv向量,encrypt参数是定值,不用理会

图片4.png
对之前找到的关键函数进行调用分析发现大多数都指在WUPTask这个类中被调用
WUPTask中初始化的函数b定义如下

图片5.png

动态调试获取加密前的数据信息
图片6.png



查找反编译代码中位置
图片7.png

加密前的wifissid信息
图片8.png


初始化函数

图片9.png
初始化加密过程
图片10.png


V2为密钥 v3为url中的tk参数,即token,v4为时间,均通过v1获取,v1是通过调用b函数得到,b函数读取_wup_token.dat内容并返回,该dat文件位于/data/data/com.tencent.mtt/files/data/com.tencent.mtt_wup_token.dat
Token组成:64位+32位
图片11.png

相同类中找到key的产生函数
图片12.png


这里陷入一个误区,之前抓包一直以为tk值是本地生成的,然而分析代码没有发现算法,各种函数互相调用把逻辑弄混了,最后在基类发现了从头部信息获取tk参数值这个初始化函数,猜测是服务器返回的,自己测试时正确的,token.dat文件生成是通过读取服务器端返回数据中header中tk值获取,但是前提是本地没有
com.tencent.mtt_service_wup_token.dat文件,该文件存储加解密数据包的key和绑定的token以及获取的时间
图片13.png

抓包获得的tk值
图片14.png


获取tk值的这个请求包url构造部分定义如下
图片15.png


以上可以写出获取token值的代码
可以推断出,客户端随机生成aes加密数据包用的key并用硬编码到源代码里的rsa公钥加密后经过转码以url参数形式发送给服务器,服务器通过私钥可以逆向算出客户端生成的随机key值来解密数据包,而tk值只是服务器用于验证客户端的签名,客户端拿到tk值后用随机生成的iv向量加密后续数据包,服务器直接可以用iv进行数据包解密,tk值与key是绑定的
在WupTask类中,通过先压缩再加密数据顺序,最后补充头部进行发包
图片16.png

对响应的数据包,先解密,后解压缩

图片17.png

在编写代码出现加密过程报错Cannot find any provider supporting AES/CBC/PKCS7Padding
解决办法PKCS7Padding与PKCS5Padding是一样的结果,换成5就行了
解密数据包,得到请求查询wifi的原始数据
图片18.png

与手机上hook得到的结果是一致的
解密响应结果

图片19.png
这是第一次生成的key绑定服务器token的数据包,后面发现可以在所有请求中都可以进行tk值的获取,并不是特定的请求

图片20.png
再来分析得到tk时url中的qbkey生成情况,这个参数由encryptAESKey函数生成,在反编译代码中估计反编译器是出错了,把我带入误区,
可以看到传入encryptAESKey函数中第2个参数是1

图片21.png
而在smali代码里则变成了2
图片22.png

在它的定义中,可以看出传入1时,加密方法是普通RSA加密,这样一来qbkey应该是一个定值,但是我实际hook测试的时候发现同一个key被加密后返回的结果都是不同的,自己写的代码做测试返回的定值跟抓包中的qbkey值对不上号,我一直以为自己代码的算法写错了,后来直接hook了encryotAESKey函数才发现实际的加密算法是填充式RSA算法


图片23.png 图片24.png


至此,发送数据包时的参数生成算法和数据包加解密算法都能理清了

由此写出动态获取tk值的算法并实现

图片25.png

首先,请求数据包会读取安装目录下files/data目录下的
com.tencent.mtt_service_wup_token.dat文件,如果不存在,则会本地生成一个随机key并用硬编码到代码的rsa公钥进行填充式加密以参数qbkey发送给服务器,服务器收到这个参数用私钥进行解密得到key值,再向客户端返回一个tk值,即token,然后服务器和客户端把tk与key绑定,客户端就存储在本地,名字为上述的dat文件,之后用key对数据包进行加密发送给服务器,服务器根据tk值查找对应的key来解密数据包,实现了交互。

发表于 2016-9-9 17:50:34 | 显示全部楼层
挺你,谢谢分享,虽然没看懂我会加油的,希望LZ多发文章,谢谢。
 楼主| 发表于 2016-9-10 22:28:13 | 显示全部楼层
smallmemory 发表于 2016-9-9 17:50
挺你,谢谢分享,虽然没看懂我会加油的,希望LZ多发文章,谢谢。

谢谢支持

九零

GMT+8, 2026-10-22 15:49

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表