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]