wangguang 发表于 2023-5-10 17:46

某麦数据参数逆向分析

本帖最后由 wangguang 于 2023-5-10 19:22 编辑

# 1.前言

这篇帖子还是关于数据采集的学习笔记,

我本就不多的分享欲都写进了笔记里面。

最近看到很喜欢的一句话:内心深处肯定会有觉得有趣的东西,如果不去做这个努力的话,自己觉得有趣的东西就会消失的。

所以要做自己喜欢的事情哦!!!

# 2.网址

aHR0cHM6Ly93d3cucWltYWkuY24vcmFuaw==

# 3.正文

在榜单处往下面划可以得到榜单app的数据

![](https://img1.imgtp.com/2023/05/10/sb7zufXD.png)

查看参数,只有一个**analysis**参数需要加密传参的

咦,看到后面的两个等于号,八成是base64编码,看能不能解码拿到其编码之前的数据。

![](https://img1.imgtp.com/2023/05/10/d7HXIXzJ.png)

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

![](https://img1.imgtp.com/2023/05/10/VKLWWTh5.png)

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

![](https://img1.imgtp.com/2023/05/10/5o1yCN2N.png)

## axios简介:

![](https://img1.imgtp.com/2023/05/10/XwAefQM1.png)

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

![](https://img1.imgtp.com/2023/05/10/LcoK9nZT.png)

在js里面搜索interceptor,但是发现三个都不是正常的使用拦截器。

正常的拦截器的使用方式应该是`xxx.interceptors.request.use()`

![](https://img1.imgtp.com/2023/05/10/9iyW8B4l.png)

## 正常的拦截器使用方法:

![](https://img1.imgtp.com/2023/05/10/upVSSjLA.png)

那便不去找`xxx.interceptors.request.use()`,估计混淆了。因为394行到409行是axios的核心,无论加密的拦截器在哪里执行最后都会经过这个axios代码的地方的。分析这段代码从而找到加密的关键代码处。

## 拦截器代码分析:

t是一个数组,第三和第五行分别把请求拦截器和响应拦截器的两个函数传到了t里面。

for循环,只要t数组里面有值,便执行`n = n.then(t.shift(), t.shift());`

![](https://img1.imgtp.com/2023/05/10/Vw3w6sGt.png)

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

![](https://img1.imgtp.com/2023/05/10/dvj2Eurk.png)

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

![](https://img1.imgtp.com/2023/05/10/SVgLA7bP.png)

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

![](https://img1.imgtp.com/2023/05/10/x2a9Igy8.png)

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

![](https://img1.imgtp.com/2023/05/10/aLqg3Mc4.png)

在控制台打印了Kt,Ut,Ft,符合拦截器`xxx.interceptors.request.use()`

但是并不确定这段代码到底是不是我们需要的加密代码勒。

![](https://img1.imgtp.com/2023/05/10/JQUJCTSi.png)

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

![](https://img1.imgtp.com/2023/05/10/QL1opCJU.png)

## 关键代码分析:

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

![](https://img1.imgtp.com/2023/05/10/uZcBys2h.png)

浏览器调试f和 F!=s

![](https://img1.imgtp.com/2023/05/10/MefeJtPE.png)

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

![](https://img1.imgtp.com/2023/05/10/FaFgSCbP.png)

先替换z

![](https://img1.imgtp.com/2023/05/10/31dvBCDz.png)

是个生成时间戳的函数

s是一个会变的数值,先写死。H是0

![](https://img1.imgtp.com/2023/05/10/wz08KZvd.png)

![](https://img1.imgtp.com/2023/05/10/jSsMezIX.png)

替换Zt

![](https://img1.imgtp.com/2023/05/10/PcSDk85X.png)

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

![](https://img1.imgtp.com/2023/05/10/gpjwImtB.png)

`void 0 === t["params"] && (t["params"] = {}`

代码有个逻辑与,逻辑与的执行原理是左边为真,执行右边,左边为假,右边不执行。上面的代码的意思就是如果传下来的参数t里面的params没有值的话就让它等于一个空对象。

替换z,Z,i7,Zt,M,P,!B,N2,b

![](https://img1.imgtp.com/2023/05/10/04luZmnN.png)

![](https://img1.imgtp.com/2023/05/10/luIbSriQ.png)

`window['Object']['keys'](t['params'])['forEach'](function(n) {if (n == 'analysis') return false;t['params']['hasOwnProperty'](n) && a['push'](t['params'])})`

这段代码的意思就是取出params里面的键遍历出来传给n,如果键是analysis就结束,是其余的键就执行后面的代码。

后面的代码有个逻辑与,逻辑与的执行原理是左边为真,执行右边,左边为假,右边不执行

把断点打到2585行,左边为真,执行右边的代码。`a['push'](t['params'])`的意思是把值都存到a数组里面。

![](https://img1.imgtp.com/2023/05/10/aLqg3Mc4.png)

下一行

![](https://img1.imgtp.com/2023/05/10/XtGXd3MO.png)

替换Ot,I1,__

![](https://img1.imgtp.com/2023/05/10/9cqXX3c7.png)

`a = a["sort"]()["join"](""),`

代码的意思是将a里面的值按照字符编码的顺序进行排序然后拼接起来。

下一行是一个函数调用了a重新赋值给了a,需要找到对应的函数扣下来。

![](https://img1.imgtp.com/2023/05/10/tm7BNgwV.png)

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

![](https://img1.imgtp.com/2023/05/10/0oKRhn6y.png)

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

![](https://img1.imgtp.com/2023/05/10/KNJtRwRh.png)

替换混淆的字符

![](https://img1.imgtp.com/2023/05/10/86DW4jah.png)

得到新的代码

``function v(t) {
    t = window["encodeURIComponent"](t)["replace"](/%({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函数是做什么的。

![](https://img1.imgtp.com/2023/05/10/XdiYqlEe.png)

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

![](https://img1.imgtp.com/2023/05/10/XxGlxXo1.png)

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

下一行

![](https://img1.imgtp.com/2023/05/10/3yUrGqup.png)

替换混淆代码

`a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),`

![](https://img1.imgtp.com/2023/05/10/RCPa9aSV.png)

这一行明显就是拼接一些乱七八糟的东西。

主要就baseurl跟r。

![](https://img1.imgtp.com/2023/05/10/ZZci4aju.png)

r在上面代码就已经生成了

而那个baseurl就是我们传下来的url里面的**pathname**,传url的时候取一下pathname替换这段代码就好了。

![](https://img1.imgtp.com/2023/05/10/v7cEXDnS.png)

下一行

![](https://img1.imgtp.com/2023/05/10/82q7G9EI.png)

替换混淆代码

![](https://img1.imgtp.com/2023/05/10/qrcm1My5.png)

得到下面代码

i是我们刚刚已经扣下来的v函数,直接替换

d是字符串**"xyz517cda96abcd"**

替换后的代码

`-1 == t["url"]["indexOf"]("analysis") && (t["url"] += (-1 != t["url"]["indexOf"]("?") ? "&" : "?") + "analysis" + "=" + window["encodeURIComponent"](e)), t`

i是h函数,进去扣下来替换。

![](https://img1.imgtp.com/2023/05/10/8xYuavRG.png)

![](https://img1.imgtp.com/2023/05/10/gRzEaL8I.png)

替换混淆代码

![](https://img1.imgtp.com/2023/05/10/DpwyjTiE.png)

替换后的代码

`function h(n, t) {
    t = t || u();
    for (var e = (n = n["split"](""))["length"], r = t["length"], a = "charCodeAt", i = 0; i < e; i++)
      n = o(n(0) ^ t[(i + 10) % r](0));
    return n["join"]("")
}`

分析了代码,我们要传的参数有个url跟params

![](https://img1.imgtp.com/2023/05/10/t7abG1Qs.png)

运行代码报错了。

![](https://img1.imgtp.com/2023/05/10/nWGDE666.png)



![](https://img1.imgtp.com/2023/05/10/nzwfrr5X.png)

缺啥补啥

![](https://img1.imgtp.com/2023/05/10/20KGmJUN.png)

报了个window未定义

![](https://img1.imgtp.com/2023/05/10/OZtUSMd7.png)

给window赋值个全局变量

最后一件事情,我们传进去的url是长的,而baseurl要的是短的。所以我们要在代码把长url变成短的url

![](https://img1.imgtp.com/2023/05/10/euvkHEsd.png)

运行代码,链接生成成功

![](https://img1.imgtp.com/2023/05/10/EaivOpax.png)

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

![](https://img1.imgtp.com/2023/05/10/eEpOyDBP.png)

# 结尾:

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

![](https://img1.imgtp.com/2023/05/10/602ZCqUT.png)

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

Hmily 发表于 2023-5-10 18:21

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

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

wangguang 发表于 2023-5-10 19:23

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

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

wangguang 发表于 2023-5-10 17:52

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

deffedyy 发表于 2023-5-10 21:07

感谢分享

cdb2022 发表于 2023-5-10 21:11

感谢分享

N1san 发表于 2023-5-10 21:55

感谢分享

moruye 发表于 2023-5-10 22:53

丶沐箐 发表于 2023-5-11 09:10

控制台打印用的淋漓尽致,我每次弄的时候总是差最后一点的时候没耐心了。。

xavier001 发表于 2023-5-11 09:30

学习了,感谢大佬分享思路
页: [1] 2 3 4 5
查看完整版本: 某麦数据参数逆向分析