某平台网关请求签名rid逆向分析
仅用于学习交流,如有侵权请联系删除
最近某bubu挺火,无聊瞎研究一下某小程序的通信。
抓包
PC打开小程序提示请在手机使用,简单改了几个点都过不去检测,直接放弃此方案。
安卓抓包失败,走的不是普通https,云函数也抓不到,先看代码吧,小程序底层就是js的,整个wx对象是js封装,直接用别人的付费工具把js全脱下来:

找了下网上文章,安卓貌似没办法静态调试,只能找找代码了,搜几个关键词找到如下请求:

在小程序官方开发文档搜了下gateway,发现gateway api是官网提供的中转服务。

没办法找入参就只能从底层入手,搜了下小程序js交互相关文章,找到了这个:
https://www.cnblogs.com/TSW369/p/17252802.html
hook几个js与java层的桥接关键点后,找到了gateway的调用及入参:

找参数
wx.cloud在WACloud.js里,直接搜几个关键参数:

call_id,搜索v2:


时间戳加随机字符串
headers中其它参数(如identity_code,为wx.login的鉴权code)以及请求data的其它参数(如sign等)为小程序内的逻辑,不在此文范围。继续看:

搜cli_req_id:

还是时间戳加随机数。
关键参数rid:

Fe.xB做签名生成,Fe为webpack的613模块, webpack中的Qt为签名入口:



蜜罐
本来到这里以为已经完成了,直接把webpack导出部分和613以及以来模块扣出来,补个Long(wx原生依赖,node没有),生成rid后可以正常请求,但是并发起来直接g,而人手动操作可以一秒点多次,那肯定不是账号限制,先排除下算法问题:
代码中把时间戳和随机数固定一下:

发现自己生成的参数和客户端生成的中有固定位置的十多位都对不上,测了下几个入参的影响,发现入参随便变一下,hex就完全变了,大概率是哈希拼接。既然我的出参只是出现了小差异,那就跟入参或者哈希算法问题无关,而是在rid算法中,哈希完毕后肯定检测了环境并替换或者插入到了哈希的固定位置,OK,跟算法吧。
跟算法

全是数字计算,跳过。

新版的tx寄存器式vmp(之前是栈式),因为目标明确,只找环境监测点,所以插桩大法:

发现并没有在vmp里面做计算,白忙活一通,接着往下看代码:


反人类的控制流状态机

看似是普通的混淆代码,实则wasm的胶水语言

Tt则是纯js实现的wasm模拟器
var e = new ArrayBuffer(65536), // 64KB内存缓冲区
t = new Int8Array(e), // 有符号8位整数视图
r = new Int16Array(e), // 有符号16位整数视图
n = new Int32Array(e), // 有符号32位整数视图
i = new Uint8Array(e), // 无符号8位整数视图
o = new Uint16Array(e), // 无符号16位整数视图
a = new Uint32Array(e), // 无符号32位整数视图
s = new Float64Array(e), // 64位浮点数视图
u = Math.imul, // 32位整数乘法
c = Math.fround, // 32位浮点数舍入
l = Math.clz32, // 计算前导零位数
f = 4096, // 栈指针初始值
d = 0; // 可能是堆指针
......众所周知wasm内部取不了js环境,必须导入js模块进行交互,寻找混淆后的js符号表,插桩导入的js函数后成功发现检测的某wx环境,修改后即可成功并发。