声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,相关网址和数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!若有侵权,请联系删除!
前言
说明
因为这个网站有两种扣法,第一种是直接扣代码,第二种是扣webpack,虽然说在这个网站扣代码较为简单,但是多一种解法更好吧哈哈哈,挑战一下,所以本文主要强调扣webpack,在本文结尾呢,也会给出扣代码的示例,好,让我们开肝!!!
逆向地址
- 网址:
217d11c479a22d810e4b13e68f3f0556
- 加密接口:
d7005d04e22c2c38f83716f5aa03daf3
抓包分析
按F12打开开发者工具,点击一个按钮触发接口进行发包
然后找到带有数据的接口,也就是下面这个
接下来,我们可以按照请求头->载荷->预览->cookie
的顺序,依次去找加密的东西,可以发现只有载荷中的analysis
加密了
所以本次逆向目标:analysis
逆向分析
因为接口中有analysis
这个关键字,所以我们直接hook xhr,向控制台注入以下代码
(function () {
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async) {
if (url.indexOf("analysis") != -1) {
debugger;
}
return open.apply(this, arguments);
};
})();
成功断住,并且能看到我们的参数已经加密了,所以接下来我们需要跟栈进一步观察
到了这里我们依然能看到参数是加密好的,所以还要跟栈,但是可以看到,再往下跟就进入异步了,所以这个参数要么在异步的时候用代码生成,要么在异步之前生成,要么呢在拦截器里面生成的
可以看到,在异步之前是还没有生成analysis
参数的,所以我们可以大胆猜想,在异步的时候或者拦截器生成,所以接下来在发异步的那边打上断点,然后一步一步调试去观察代码
到了这边就要注意了,这是一个响应拦截器,而它与请求拦截器一般是同时出现的,并且在它的上面
所以我们往上找一下请求拦截器
可以看到它真的在,我们打上断点进行调试
可以看到我们要的参数是还没有生成的,所以我们放心大胆的往下走
很明显,我们要的数据已经出来了,也就是那个e
,我们把它的生成代码扣下来
(0,
i[jt])((0,
i[qt])(a, d))
它等价于:
i[jt](i[qt](a, d))
往上面找可以看到i = e(21725)
,这看起来很像webpack的模式,我们打上断点看看这个e
是个啥东东
刷新页面才能断住,我们进入e
中,可以看到这是一个webpack,并且加载器是u
,好接下来我们扣下来放node中
扣webpack
扣的时候可以看到这样一串代码,这个就是多文件的打包,对于多文件的打包,最好把文件都扣下来,但是先不急,先扣的看,看有多少
a = self.webpackChunkqimai = self.webpackChunkqimai || [];
我们先用全局变量aaa
导出加载器,然后执行aaa('21725')
报错说self没有定义,我们回浏览器可以发现self其实就是window,所以我们在代码最上面打上这两行就可以
window = global;
self = window
然后执行报错,这种报错一般都是缺少模块,我们在加载器中打印一下看看
可以看到缺少21725这个模块,我们去网站中扣下来,放在存放模块的地方中,也就是f
这里我已经扣好了,要把参数带上,不然的话会有报错,参数中的e
就是加载器
21725: function (n = {
"id": 21725,
"loaded": false,
"exports": {}
}, t = {}, e = aaa) {
e['d'](t,........
运行后可以看到还缺少模块90484和70538这两个模块,我们继续补上,补上后报错,这一般是缺少环境导致的,我们补上即可
navigator ={}
navigator.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
继续运行也报document的环境问题,我们继续补,这里我已经补好了
document = {
}
document.createEvent = function (res) {
return {}
}
document.createElement = function (res) {
return {}
}
接下来我们固定一些值进行调试,可以看到得出结果,并且正确,别的一些扣代码这里也不强调了,难点已经拿下哈哈哈
i = aaa(21725)
d = "xyz517cda96efgh"
h = i["cv"](i["oZ"]("MQ==@#/indexV2/getUserModules@#54044793542@#3", d))
console.log(h)
Js部分实现
webpack版
i = aaa(21725)
d = "xyz517cda96efgh"
h = i["cv"](i["oZ"]("MQ==@#/indexV2/getUserModules@#54044793542@#3", d))
console.log(h)
扣代码版
// e = v(h(a, d))
function h(n, t) {
t = 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 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 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 new Buffer()["from"](t)["toString"]("base64")
}
}
d = "xyz517cda96efgh"
r = +new Date() - (99 || 0) - 1661224081041
function get_analysis(params) {
a = params["sort"]()["join"]("")
a = v(a)
a = (a += "@#" + '/indexV2/getIndexRank'["replace"]('https://api.qimai.cn', "")) + ("@#" + r) + ("@#" + 3)
e = v(h(a, d))
return e
}
console.log(get_analysis([0, '5000']))
Py部分实现
import requests
import execjs
url = ''
headers = {
}
cookies = {
}
with open('', 'r') as f:
js_code = f.read()
code = execjs.compile(js_code)
datas = {
'setting': 0,
'genre': "5000"
}
datas['analysis'] = code.call('get_analysis', list(datas.values()))
res = requests.get(url=url, headers=headers, cookies=cookies, params=datas).json()
print(res)
总结
这个网站扣代码比较简单一点,但是你永远不知道自己要扣的代码有多少哈哈哈,所以懂得webpack也是很好的,这个网站扣webpack主要是补环境,模块相对较少