某麦数据参数逆向分析

查看 55|回复 7
作者:wangguang   
1.前言
这篇帖子还是关于数据采集的学习笔记,
我本就不多的分享欲都写进了笔记里面。
最近看到很喜欢的一句话:内心深处肯定会有觉得有趣的东西,如果不去做这个努力的话,自己觉得有趣的东西就会消失的。
所以要做自己喜欢的事情哦!!!
2.网址
aHR0cHM6Ly93d3cucWltYWkuY24vcmFuaw==
3.正文
在榜单处往下面划可以得到榜单app的数据

查看参数,只有一个analysis参数需要加密传参的
咦,看到后面的两个等于号,八成是base64编码,看能不能解码拿到其编码之前的数据。

解码之后是乱码,那么通过查看代码去逆向它这个参数是怎么生成的

在initiator面板看到了Promise.then,并且每个数据包都携带了同一个参数。猜测这个xhr用了axios,其加密解密的代码都会运行在这个拦截器里面。

axios简介:

直接搜索拦截器interceptor看看能不能找到代码的关键位置,搜索到了一个唯一的js文件。可以证明这个xhr确确实实用了axios。

在js里面搜索interceptor,但是发现三个都不是正常的使用拦截器。
正常的拦截器的使用方式应该是xxx.interceptors.request.use()

正常的拦截器使用方法:

那便不去找xxx.interceptors.request.use(),估计混淆了。因为394行到409行是axios的核心,无论加密的拦截器在哪里执行最后都会经过这个axios代码的地方的。分析这段代码从而找到加密的关键代码处。
拦截器代码分析:
t是一个数组,第三和第五行分别把请求拦截器和响应拦截器的两个函数传到了t里面。
for循环,只要t数组里面有值,便执行n = n.then(t.shift(), t.shift());

n是promise,便可以知道是发送请求,并且是把t数组里面的函数两两对应进行发送。

那么把断点下到407行,刷新取t的值看看。总共有6个函数,请求拦截器的函数是添加到t数组的前面的,便去前面的函数看看。

从t的第0个函数进去继续跟代码。

代码跟进去的时候停在了2572行,在2575行下断点看看是不是加密关键代码

在控制台打印了Kt,Ut,Ft,符合拦截器xxx.interceptors.request.use()
但是并不确定这段代码到底是不是我们需要的加密代码勒。

在2572和2595行下断点,在榜单页面鼠标往下滑。可以看到e就是我们需要的加密参数。那么加密函数肯定就在这段代码里面了。

关键代码分析:
代码中有两个逻辑或,逻辑或的执行原理就是当左边为假的时候才执行右边,左边为真的时候就不执行右边的代码了。

浏览器调试f和 F!=s

在控制台打印值,可以看到f为false,于是执行了F!=s,F是null,s是一个数字。所以F!=s为真,右边的代码不执行。

先替换z[w]

是个生成时间戳的函数
s是一个会变的数值,先写死。H是0


替换Zt

t是传下来的参数,t里面的params是传参。

void 0 === t["params"] && (t["params"] = {}
代码有个逻辑与,逻辑与的执行原理是左边为真,执行右边,左边为假,右边不执行。上面的代码的意思就是如果传下来的参数t里面的params没有值的话就让它等于一个空对象。
替换z,Z,i7,Zt,M,P,!B,N2,b


window['Object']['keys'](t['params'])['forEach'](function(n) {if (n == 'analysis') return false;t['params']['hasOwnProperty'](n) && a['push'](t['params'][n])})
这段代码的意思就是取出params里面的键遍历出来传给n,如果键是analysis就结束,是其余的键就执行后面的代码。
后面的代码有个逻辑与,逻辑与的执行原理是左边为真,执行右边,左边为假,右边不执行
把断点打到2585行,左边为真,执行右边的代码。a['push'](t['params'][n])的意思是把值都存到a数组里面。

下一行

替换Ot,I1,__

a = a["sort"]()["join"](""),
代码的意思是将a里面的值按照字符编码的顺序进行排序然后拼接起来。
下一行是一个函数调用了a重新赋值给了a,需要找到对应的函数扣下来。

把断点下到2588行进去查看函数

把这段代码扣下来,分析这段代码做了什么。

替换混淆的字符

得到新的代码
`function v(t) { t = window["encodeURIComponent"](t)["replace"](/%([0-9A-F]{2})/g, function(n, t) { return o("0x" + t) }); try { return window["btoa"](t) } catch (n) { return window["Buffer"]["from"](t)["toString"]("base64") } }
有个o函数,扣下来。
看看o函数是做什么的。

o函数是将传进去的参数转为一个字符。

try...catch...就只是一个异常捕获函数,作用就是将参数base64编码之后返回。直接改写成node环境中能用的base64编码就行了。
下一行

替换混淆代码
a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),

这一行明显就是拼接一些乱七八糟的东西。
主要就baseurl跟r。

r在上面代码就已经生成了
而那个baseurl就是我们传下来的url里面的pathname,传url的时候取一下pathname替换这段代码就好了。

下一行

替换混淆代码

得到下面代码
i[jt]是我们刚刚已经扣下来的v函数,直接替换
d是字符串"xyz517cda96abcd"
替换后的代码
-1 == t["url"]["indexOf"]("analysis") && (t["url"] += (-1 != t["url"]["indexOf"]("?") ? "&" : "?") + "analysis" + "=" + window["encodeURIComponent"](e)), t
i[qt]是h函数,进去扣下来替换。


替换混淆代码

替换后的代码
function h(n, t) { t = t || u(); for (var e = (n = n["split"](""))["length"], r = t["length"], a = "charCodeAt", i = 0; i
分析了代码,我们要传的参数有个url跟params

运行代码报错了。


缺啥补啥

报了个window未定义

给window赋值个全局变量
最后一件事情,我们传进去的url是长的,而baseurl要的是短的。所以我们要在代码把长url变成短的url

运行代码,链接生成成功

用python执行,成功获取到数据

结尾:
有个总结,baseurl不能错,自己可以插赃看一下js代码生成的跟浏览器生成的那个a是不是一样的。因为这个baseurl错了改bug改了好久。

就因为一个us的大小写调试了好久好久。哭唧唧啊!!!具体解决方法就是自己传baseurl。

代码, 函数

wangguang
OP
  


wangguang 发表于 2023-5-10 17:52
emmmm,咦。
为什么我的上传图床的图片显示不出来@涛之雨

有防盗链吧,f12看下链接都403了。
wangguang
OP
  


Hmily 发表于 2023-5-10 18:21
有防盗链吧,f12看下链接都403了。

好的老大,我已经更换了图床链接了
deffedyy   

emmmm,咦。
为什么我的上传图床的图片显示不出来@涛之雨
cdb2022   

感谢分享
N1san   

感谢分享
moruye   

感谢分享
wangguang
OP
  

厉害厉害,感谢分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部