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

打印 上一主题 下一主题

主题 657|帖子 657|积分 1971

分析网站
分析流程

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




2.我们这里通过free免费榜来教学,接下来我们通过搜刮analysis关键词,发现三处都是在url链接中,肯定不是,这个方法就不可行了。


2.通过启动器(Initiator)来找,映入眼帘Promise对象,我们可以想到拦截器,搜刮interceptors试一下。


3.有三处,第一处是赋值,不大概是加密逻辑,看下第二处和第三处整个的逻辑,代码如下:


  1. l.prototype.request = function(e) {
  2.             "string" == typeof e ? (e = arguments[1] || {}).url = arguments[0] : e = e || {},
  3.             (e = s(this.defaults, e)).method ? e.method = e.method.toLowerCase() : this.defaults.method ? e.method = this.defaults.method.toLowerCase() : e.method = "get";
  4.             var t = [o, void 0]
  5.               , n = Promise.resolve(e);
  6.             for (this.interceptors.request.forEach((function(e) {
  7.                 t.unshift(e.fulfilled, e.rejected)
  8.             }
  9.             )),
  10.             this.interceptors.response.forEach((function(e) {
  11.                 t.push(e.fulfilled, e.rejected)
  12.             }
  13.             )); t.length; )
  14.                 n = n.then(t.shift(), t.shift());
  15.             return n
  16.         }
复制代码
4.先对e进行类型判定和值的重新赋值,然后声明t为数组和n为Promise对象,紧接着两个for循环,请求拦截器中遍历往t数组的头部插入元素,相应拦截器遍历往t数组的尾部插入元素,可以看到遍历完成后,t数组中统共有6个对象,最后从t数组的头部弹出两个元素交给Promise对象的then函数执行。


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


6.从下面的三个变量值也可以看出没找错地方,接下来我们就要具体分析了。


7.这段代码有许多的花指令,我们打断点还原一下,还原后的代码以及分析如下:

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

  1. function fn(t) {
  2.    var e, r = new Date() + 226 - 1661224081041, a = [];
  3.     return false,
  4.         Object["keys"](t["params"])["forEach"](function (n) {
  5.             if (n == "analysis")
  6.                 return !1;
  7.             t["params"]["hasOwnProperty"](n) && a["push"](t["params"][n])
  8.         }),
  9.         a = a["sort"]()["join"](""),
  10.         a = i["cv"](a),
  11.         a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
  12.         e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
  13.         e;
  14. }
复制代码
9.接下来就是扣代码了(这里我就不浪费时间了,自己去扣一下),扣完后的代码如下:

  1. 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[e](n)}function u() {    return unescape("861831832863830866861836861862839831831839862863839830865834861863837837830830837839836861835833"["replace"](/8/g, "%u00"))}var i = {    cv:function v(t) {        t = encodeURIComponent(t)["replace"](/%([0-9A-F]{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[i] = o(n[i][a](0) ^ t[(i + 10) % r][a](0));        return n["join"]("")    }};function fn(t) {
  2.    var e, r = new Date() + 226 - 1661224081041, a = [];
  3.     return false,
  4.         Object["keys"](t["params"])["forEach"](function (n) {
  5.             if (n == "analysis")
  6.                 return !1;
  7.             t["params"]["hasOwnProperty"](n) && a["push"](t["params"][n])
  8.         }),
  9.         a = a["sort"]()["join"](""),
  10.         a = i["cv"](a),
  11.         a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
  12.         e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
  13.         e;
  14. }
复制代码
10.终极的完备代码如下:

  1. function o(n) {
  2.         t = "",
  3.         ['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65']["forEach"](function(n) {
  4.                 t += unescape("%u00" + n)
  5.         });
  6.         var t, e = t;
  7.         return String[e](n)
  8. }
  9. function u() {
  10.     return unescape("861831832863830866861836861862839831831839862863839830865834861863837837830830837839836861835833"["replace"](/8/g, "%u00"))
  11. }
  12. var i = {
  13.     cv:function v(t) {
  14.         t = encodeURIComponent(t)["replace"](/%([0-9A-F]{2})/g, function(n, t) {
  15.             return o("0x" + t)
  16.         });
  17.         try {
  18.             return btoa(t)
  19.         } catch (n) {
  20.             return Buffer["from"](t)["toString"]("base64")
  21.         }
  22.     },
  23.     oZ:function h(n, t) {
  24.         t = t || u();
  25.         for (var e = (n = n["split"](""))["length"], r = t["length"], a = "charCodeAt", i = 0; i < e; i++)
  26.             n[i] = o(n[i][a](0) ^ t[(i + 10) % r][a](0));
  27.         return n["join"]("")
  28.     }
  29. };
  30. function fn(t) {
  31.    var e, r = new Date() + 226 - 1661224081041, a = [];
  32.     return false,
  33.         Object["keys"](t["params"])["forEach"](function (n) {
  34.             if (n === "analysis")
  35.                 return !1;
  36.             t["params"]["hasOwnProperty"](n) && a["push"](t["params"][n])
  37.         }),
  38.         a = a["sort"]()["join"](""),
  39.         a = i["cv"](a),
  40.         a = (a += "@#" + t["url"]["replace"](t["baseURL"], "")) + ("@#" + r) + ("@#" + 3),
  41.         e = i["cv"](i["oZ"](a, "xyz517cda96efgh")),
  42.         e;
  43. }
  44. function get_analysis(url, pm) {
  45.     var params = {
  46.         "url": url,
  47.         "baseURL": "https://api.qimai.cn",
  48.         "params":pm,
  49.     };
  50.     return fn(params);
  51. }
复制代码
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. '''
  4. @Project :pythonProject
  5. @File    :test.py
  6. @IDE     :PyCharm
  7. @Author  :haozaispider
  8. @Date    :2024/12/12 上午11:43
  9. '''
  10. import requests
  11. import execjs
  12. from loguru import logger
  13. import warnings
  14. # 忽略 DeprecationWarning
  15. warnings.filterwarnings("ignore", category=DeprecationWarning)
  16. headers = {
  17.     "Accept": "application/json, text/plain, */*",
  18.     "Accept-Language": "zh-CN,zh;q=0.9",
  19.     "Cache-Control": "no-cache",
  20.     "Connection": "keep-alive",
  21.     "Origin": "https://www.qimai.cn",
  22.     "Pragma": "no-cache",
  23.     "Sec-Fetch-Dest": "empty",
  24.     "Sec-Fetch-Mode": "cors",
  25.     "Sec-Fetch-Site": "same-site",
  26.     "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",
  27.     "sec-ch-ua": ""Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"",
  28.     "sec-ch-ua-mobile": "?0",
  29.     "sec-ch-ua-platform": ""Windows""
  30. }
  31. cookies = {
  32.     "qm_check": "脱敏处理",
  33.     "PHPSESSID": "脱敏处理",
  34.     "gr_user_id": "510ed001-e791-40a4-99fc-063e93a7ab51",
  35.     "ada35577182650f1_gr_session_id": "97645d15-06c3-437d-a02a-8a13765e3038",
  36.     "ada35577182650f1_gr_session_id_sent_vst": "97645d15-06c3-437d-a02a-8a13765e3038",
  37.     "USERINFO": "脱敏处理",
  38.     "AUTHKEY": "脱敏处理",
  39.     "ada35577182650f1_gr_last_sent_sid_with_cs1": "97645d15-06c3-437d-a02a-8a13765e3038",
  40.     "ada35577182650f1_gr_last_sent_cs1": "qm22766779697",
  41.     "aso_ucenter": "5730k%2BgpXumagmcIZq2OYokDWKWmGaaMtNHXswGAPR5XqVm9FIC8Q%2FIpN%2BbGYX7ZF6k",
  42.     "synct": "1733973854.587",
  43.     "syncd": "-260809",
  44.     "ada35577182650f1_gr_cs1": "qm22766779697"
  45. }
  46. url = "https://脱敏处理/rank/index"
  47. params = {
  48.     # "analysis": "ex88DQoVIwNvZmETByZRQAcLMlU4WlVHUFkISwhXUgAeJ0tPS00AAQBRUVUABiVFVA==",
  49.     "brand": "free",
  50.     "device": "iphone",
  51.     "country": "cn",
  52.     "genre": "36"
  53. }
  54. analysis = execjs.compile(open('./demo.js','r',encoding = 'utf-8').read()).call('get_analysis',url.replace('https://api.qimai.cn',''),params)
  55. logger.info('analysis参数 ===》》》 ' + analysis)
  56. params['analysis'] = analysis
  57. response = requests.get(url, headers=headers,
  58.                         cookies=cookies,
  59.                         params=params)
  60. decoded_text = bytes(response.text, 'utf-8').decode('unicode_escape')
  61. logger.info('解编码后的数据 ===》》》 ' + decoded_text)
复制代码
结果展示


更换也可以拿到数据。

完结撒花❀❀❀❀❀❀(大佬可以直接滤过,接待+v:haozaispider 一起交换学习)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

星球的眼睛

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表