案例-七麦数据

这里是为我所统率的战场。 / 2023-08-23 / 原文

地址:  https://www.qimai.cn/rank

 

逆向的目标是请求参数:

全局搜索:第三个文件不用看了,因为是CSS文件。

看到下面的请求的是URL有所搜索的关键字,而关键字是来自请求参数的。好像不太对。所以搜索 analysis 没啥用,要用其他方案搜索。

观察到每个请求都有analysis,说明所有请求都要过一个地方,根据经验,应该是axios,应该是一个拦截器做的事。

观察一下启动器,用到了promise。

 

所以应该搜索 interceptors

 

看到下面,这是源码

 

参数应该是在axios的拦截器上进行的加密,改成下述逻辑之后拦截器搜不到。

haha = 'interc'+'eptors'

axios[haha]['request']["use"](function(){}, function(){})

axios.interceptors.response.use(function(){}, function(){})

猜测. 网站的逻辑应该是用上述逻辑完成的.

遇到这种情况怎么办? 从axios源码下手。

o函数是xhr发送请求的函数。

 

python代码:

import subprocess
from functools import partial

subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")

import execjs
import requests
import json

f = open("七麦.js", mode='r', encoding="utf-8")
js_code = f.read()
f.close()

js = execjs.compile(js_code)

url = "https://api.qimai.cn/rank/index"

params = {
    "brand": "free",
    "device": "iphone",
    "country": "cn",
    "genre": "36",
    "date": "2023-05-15",
    "page": 3,
    "is_rank_index": 1,
    "snapshot": "23:08:06"
}

analysis = js.call("fn", url, params)
params['analysis'] = analysis


resp = requests.get(url, params, headers={
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
})
print(resp.json())

 

七麦.js
// global就是node的全局
window = global;

function o(n) {
    t = "",
    ['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65']['forEach'](function(n) {
        t += window['unescape']('%u00' + n)
    });
    var t, e = t;
    return window['String']["fromCharCode"](n)
}

function v1(t) {
    t = window['encodeURIComponent'](t)["replace"](/%([0-9A-F]{2})/g, function(n, t) {
        return o("0x" + t)
    });
    try {
        return window["btoa"](t); // base64  浏览器的
    } catch (n) {
        return window["Buffer"]["from"](t)["toString"]("base64"); // base64  nodejs的
    }
}

function h(n, t) {

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

function fn(url, params) {
    let baseURL = 'https://api.qimai.cn'
    let s = -56;
    var e, r = +new Date - (s) - 1661224081041, a = [];
    void 0 === params && (params = {}),
        // 循环参数. 然后把参数的值. 塞入 数组a中
    Object.keys(params)["forEach"](function(n) {
        if (n === "analysis")
            return !1;
        params["hasOwnProperty"](n) && a["push"](params[n])
    }),
    a = a["sort"]()["join"](""),
    a = v1(a),
    a = (a += "@#" + url["replace"](baseURL, "")) + ("@#" + r) + ("@#" + 3);
    e = v1(h(a, "xyz517cda96abcd"));
    return e;
}