声明
本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文未经许可禁止转载,禁止任何形式的修改后进行二次传播,若有侵权,请联系作者删除!
逆向目标
- 网站:aHR0cHM6Ly9lYy5taW5tZXRhbHMuY29tLmNuL29wZW4vaG9tZS9wdXJjaGFzZS1pbmZv
抓包分析
打开开发者工具或者F12,翻页进行接口加载,每次翻页可以看到两个接口加载
目标数据如下图
查看请求参数信息,发现加密密文,再查看public,返回一长串密文
加载数据时每次都会加载public,猜测public返回的密文有用,复制路径搜索,找到相应位置并打上断点,翻页进行调试成功断住
查看代码发现t.setPublicKey(r) 、t.encryptLong(JSON.stringify(a)) 等相关代码,在适当位置打上断点进行调试发现s为数据接口参数param,r为public返回的长串密文
t.encryptLong(JSON.stringify(a))为参数param的生成位置,向上看,发现用到了以下代码,需要解决a,t,r,其中r可以暂时固定,后期再调整
建一个js文件,放入以下代码,r固定后需要解决的只剩下t和a了
t = new v["a"]
r = n.data,//控制台打印r,暂时固定,后期传入即可
t.setPublicKey(r),
a = m(m({}, e), {}, {
sign: f()(JSON.stringify(e)),
timeStamp: +new Date
}),
s = t.encryptLong(JSON.stringify(a))
逆向分析
变量a
接下来先看a,控制台打印输出,sign需要逆向,pageIndex可暂时固定
找到a的生成位置,发现m()函数、f()函数、参数e不知道,参数e控制台打印输出即可,和a差不多,只是少了timeStamp和sign
a处打上断点进行调试依次跟进找到m()函数、f()函数,m()函数很简单如下图,f()函数实质为一个标准md5加密,直接使用JS标准算法库还原
//md5加密算法
function f(data){
const md5Hash = crypto.createHash("md5");
md5Hash.update(data);
return md5Hash.digest("hex");
}
变量t
接下来还剩下t未完成,看到 t = new v["a"] 要逆向t就要先找到v,向上找发现如图所示,很明显是一个webpack,该处断点调试跟进去发现t("9816")由g函数生成,扣出webpack相关代码,不会的话网上自行搜索
扣出webpack代码如下,注意需要全局导出g函数,比如定义一个变量a,让a来接收g,方便后面调用
var a;
(function(A) {
//代码过长,这里是部分代码
function g(e) {
if (n[e])
return n[e].exports;
var t = n[e] = {
i: e,
l: !1,
exports: {}
};
return A[e].call(t.exports, t, t.exports, g),
t.l = !0,
t.exports
}
a = g;//全局导出g函数,方便后面调用
}
)({
//此处放模块,后面会用到
})
接下来需要补全webpack模块代码,选中 t("9816") 直接跟进去,进入到chunkXXX.js文件,直接搜索9816,把代码抠出来,有点小长哦
最后还差个t.encryptLong,选中它直接跟进去,直接扣出
v["a"].prototype.encryptLong = function(A) {
var e = this.getKey()
, t = (e.n.bitLength() + 7 >> 3) - 11;
try {
var n = ""
, r = "";
if (A.length > t)
return n = A.match(/.{1,50}/g),
n.forEach((function(A) {
var t = e.encrypt(A);
r += t
}
)),
w(r);
var a = e.encrypt(A)
, s = w(a);
return s
} catch (i) {
return i
}
}
温馨提示:扣的js代码放到本地运行会报错,根据提示补全剩余代码即可,很简单的~
本次逆向到此就结束了,下面是结果验证,由于是第一次写,大佬看见还请多多指导。