星球的眼睛 发表于 2025-3-7 12:05:24

web逆向实战9(七麦数据)

分析网站
分析流程

1.点击链接打开页面,抓包,我们重要还是看Fetch/XHR类型的,点击这几个按钮,获取到的数据包根本一样,就是载荷里的brand不一样,重要有一个参数analysis必要我们分析。

https://i-blog.csdnimg.cn/direct/44362f5d99dc4a56bbd283444a25a41f.png
https://i-blog.csdnimg.cn/direct/79a3c823f9bd4d5780e3a5bd6991cb6e.png
https://i-blog.csdnimg.cn/direct/01c6dd33d82147cbaed543b15ff579dc.png
2.我们这里通过free免费榜来教学,接下来我们通过搜刮analysis关键词,发现三处都是在url链接中,肯定不是,这个方法就不可行了。

https://i-blog.csdnimg.cn/direct/bcb52e963d3f40ddb830515efeefd3bd.png
2.通过启动器(Initiator)来找,映入眼帘Promise对象,我们可以想到拦截器,搜刮interceptors试一下。

https://i-blog.csdnimg.cn/direct/425ae16aac2d47629f683bf057cf07bd.png
3.有三处,第一处是赋值,不大概是加密逻辑,看下第二处和第三处整个的逻辑,代码如下:

https://i-blog.csdnimg.cn/direct/5e63eef823ac4acba25fde48167ecb87.png
l.prototype.request = function(e) {
            "string" == typeof e ? (e = arguments || {}).url = arguments : e = e || {},
            (e = s(this.defaults, e)).method ? e.method = e.method.toLowerCase() : this.defaults.method ? e.method = this.defaults.method.toLowerCase() : e.method = "get";
            var t =
            , n = Promise.resolve(e);
            for (this.interceptors.request.forEach((function(e) {
                t.unshift(e.fulfilled, e.rejected)
            }
            )),
            this.interceptors.response.forEach((function(e) {
                t.push(e.fulfilled, e.rejected)
            }
            )); t.length; )
                n = n.then(t.shift(), t.shift());
            return n
      }
4.先对e进行类型判定和值的重新赋值,然后声明t为数组和n为Promise对象,紧接着两个for循环,请求拦截器中遍历往t数组的头部插入元素,相应拦截器遍历往t数组的尾部插入元素,可以看到遍历完成后,t数组中统共有6个对象,最后从t数组的头部弹出两个元素交给Promise对象的then函数执行。

https://i-blog.csdnimg.cn/direct/800c4d8d75a040ca929db0542a30dda2.png
5.根据Promise对象的then函数可以知道,会给其传两个参数,成功了执行第一个参数,失败了执行第二个参数。所以假如这里存在加密逻辑的话,那么肯定在t数组的第一个参数处,定位到相应函数。

https://i-blog.csdnimg.cn/direct/88356d0c2bd54472b509340030d3c07d.png
6.从下面的三个变量值也可以看出没找错地方,接下来我们就要具体分析了。

https://i-blog.csdnimg.cn/direct/dd9d34cade7a4dcaad89152139b4f1bc.png
7.这段代码有许多的花指令,我们打断点还原一下,还原后的代码以及分析如下:

function fn(t) {
    var n;
    n = i["ej"]("synct"),//用于获取cookie中synct的值
      s = c["default"]["prototype"]["difftime"] = -i["ej"]("syncd") || +new z["Date"] - 1000 * n;//用于获取cookie中syncd中的值,如果cookie中没有syncd,则s=new Date()-1000*n
    var e,
        r = +new z["Date"] - (s || 0) - 1661224081041, //计算一个时间差,这个值不是固定的,所以我们可以直接把s的值固定,上面两行代码就没用了。
        a = [];
    return void 0 === t["params"] && (t["params"] = {}),//false
      z["Object"]["keys"](t["params"])["forEach"](function (n) {
            if (n == "analysis")
                return !1;
            t["params"]["hasOwnProperty"](n) && a["push"](t["params"])//遍历t["params"]中的所有键,将对应的值全部存放到a数组中
      }),
      a = a["sort"]()["join"](""),//对a数组进行排序,并用空字符串连接
      a = i["cv"](a),//i["cv"]未知
      a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),//对a的值进行拼接
      e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
      e
    // -B == t["url"]["indexOf"]("analysis") && (t["url"] += (-B != t["url"]["indexOf"]("?") ? "&" : "?") + "analysis" + "=" + z["encodeURIComponent"](e)),//判断url背后的参数是用&还是?连接
    //   t
}

8.终极化简后的代码如下:

function fn(t) {
   var e, r = new Date() + 226 - 1661224081041, a = [];
    return false,
      Object["keys"](t["params"])["forEach"](function (n) {
            if (n == "analysis")
                return !1;
            t["params"]["hasOwnProperty"](n) && a["push"](t["params"])
      }),
      a = a["sort"]()["join"](""),
      a = i["cv"](a),
      a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
      e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
      e;
}

9.接下来就是扣代码了(这里我就不浪费时间了,自己去扣一下),扣完后的代码如下:

function o(n) {    t = "",    ['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65']["forEach"](function(n) {      t += unescape("%u00" + n)    });    var t, e = t;    return String(n)}function u() {    return unescape("861831832863830866861836861862839831831839862863839830865834861863837837830830837839836861835833"["replace"](/8/g, "%u00"))}var i = {    cv:function v(t) {      t = encodeURIComponent(t)["replace"](/%({2})/g, function(n, t) {            return o("0x" + t)      });      try {            return btoa(t)      } catch (n) {            return Buffer["from"](t)["toString"]("base64")      }    },    oZ: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"]("")    }};function fn(t) {
   var e, r = new Date() + 226 - 1661224081041, a = [];
    return false,
      Object["keys"](t["params"])["forEach"](function (n) {
            if (n == "analysis")
                return !1;
            t["params"]["hasOwnProperty"](n) && a["push"](t["params"])
      }),
      a = a["sort"]()["join"](""),
      a = i["cv"](a),
      a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
      e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
      e;
}

10.终极的完备代码如下:

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

var i = {
    cv:function v(t) {
      t = encodeURIComponent(t)["replace"](/%({2})/g, function(n, t) {
            return o("0x" + t)
      });
      try {
            return btoa(t)
      } catch (n) {
            return Buffer["from"](t)["toString"]("base64")
      }
    },
    oZ: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"]("")
    }
};
function fn(t) {
   var e, r = new Date() + 226 - 1661224081041, a = [];
    return false,
      Object["keys"](t["params"])["forEach"](function (n) {
            if (n === "analysis")
                return !1;
            t["params"]["hasOwnProperty"](n) && a["push"](t["params"])
      }),
      a = a["sort"]()["join"](""),
      a = i["cv"](a),
      a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
      e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
      e;
}

function get_analysis(url, pm) {
    var params = {
      "url": url,
      "baseURL": "https://api.qimai.cn",
      "params":pm,
    };
    return fn(params);
}

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :pythonProject
@File    :test.py
@IDE   :PyCharm
@Author:haozaispider
@Date    :2024/12/12 上午11:43
'''
import requests
import execjs
from loguru import logger
import warnings
# 忽略 DeprecationWarning
warnings.filterwarnings("ignore", category=DeprecationWarning)
headers = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Cache-Control": "no-cache",
    "Connection": "keep-alive",
    "Origin": "https://www.qimai.cn",
    "Pragma": "no-cache",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-site",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
    "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\""
}
cookies = {
    "qm_check": "脱敏处理",
    "PHPSESSID": "脱敏处理",
    "gr_user_id": "510ed001-e791-40a4-99fc-063e93a7ab51",
    "ada35577182650f1_gr_session_id": "97645d15-06c3-437d-a02a-8a13765e3038",
    "ada35577182650f1_gr_session_id_sent_vst": "97645d15-06c3-437d-a02a-8a13765e3038",
    "USERINFO": "脱敏处理",
    "AUTHKEY": "脱敏处理",
    "ada35577182650f1_gr_last_sent_sid_with_cs1": "97645d15-06c3-437d-a02a-8a13765e3038",
    "ada35577182650f1_gr_last_sent_cs1": "qm22766779697",
    "aso_ucenter": "5730k%2BgpXumagmcIZq2OYokDWKWmGaaMtNHXswGAPR5XqVm9FIC8Q%2FIpN%2BbGYX7ZF6k",
    "synct": "1733973854.587",
    "syncd": "-260809",
    "ada35577182650f1_gr_cs1": "qm22766779697"
}
url = "https://脱敏处理/rank/index"
params = {
    # "analysis": "ex88DQoVIwNvZmETByZRQAcLMlU4WlVHUFkISwhXUgAeJ0tPS00AAQBRUVUABiVFVA==",
    "brand": "free",
    "device": "iphone",
    "country": "cn",
    "genre": "36"
}
analysis = execjs.compile(open('./demo.js','r',encoding = 'utf-8').read()).call('get_analysis',url.replace('https://api.qimai.cn',''),params)
logger.info('analysis参数 ===》》》 ' + analysis)
params['analysis'] = analysis
response = requests.get(url, headers=headers,
                        cookies=cookies,
                        params=params)

decoded_text = bytes(response.text, 'utf-8').decode('unicode_escape')
logger.info('解编码后的数据 ===》》》 ' + decoded_text)
结果展示

https://i-blog.csdnimg.cn/direct/ca11b51a53e546f0921efff9b6f7d2e8.png
更换也可以拿到数据。
https://i-blog.csdnimg.cn/direct/79e950b397bf4fad9e05c75210a9cc6d.png
完结撒花❀❀❀❀❀❀(大佬可以直接滤过,接待+v:haozaispider 一起交换学习)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: web逆向实战9(七麦数据)