前言:
天几天出了一个js逆向环境搭建的博文,因为涉及到pycharm专业版破解,审核不通过,敏感部分全部删掉了,官方给出的说法是涉及到大厂软件破解😀😀😀
今天肝一个点点数据js逆向,后续网页结构可能更新,本博文只提供思路参考
1.数据接口分析
第一步:
打开网站按 f12 打开开发者工具,我这里用的中文版开发者工具界面,因为感觉中文对菜鸡比较友好,找英文选项的可以直接挨个翻译
如下图,切换到网络选项,并点击清除网络日志(ctrl+l),没有网络选项的需要点击箭头右边的加号添加网络选项才有
第二步:
随便点一个分类,换页,因为这样才会出现新的数据包(下图框起来的就叫数据包)
第三步:
全局搜索,搜索页面内数据
搜索出来只有一个数据包包含这个游戏的名字,也就是说这个就是我们要拿到的数据包
接下来打开他的负载,看一下它都携带了什么参数发送请求
再次切换网页分类,再进去全局搜索搜刚才那个游戏,仔细观察这两个数据包的负载,是有变化的,这个k值发生了变化,这个k就是我们需要进行逆向的东西
2.详解异步栈堆跟栈分析与断点
异步操作在JavaScript中很常见,比如Promise、async/await等。在进行逆向工程时,理解异步栈堆和栈的分析是至关重要的。
-
异步栈堆:异步栈堆是指在JavaScript引擎中用于管理异步任务的数据结构。异步任务包括Promise回调、setTimeout、事件处理器等。当这些任务被调度执行时,它们会进入异步栈堆中等待执行。异步栈堆的管理使得JavaScript能够处理并发任务,保证了代码的顺序执行。
-
栈分析:栈是JavaScript引擎中用于管理执行上下文的数据结构,执行上下文包括函数调用、变量声明等。在进行逆向工程时,栈的分析可以帮助理解代码的执行流程和上下文切换情况。通过分析栈的调用关系和变量作用域,可以更好地理解代码的逻辑和结构。
将选项切换到标头,将他的路径复制下来,然后将开发者工具切换到源代码选项,按图所示的箭头操作,添加断点
添加好断点后,再次切换网页分类,成功断住
3.详解头部签名多参数栈堆分析
接下来我们开始找他的网络拦截器,也是为了进一步去找k值加密的位置
网络拦截器通常是指一种网络安全技术,用于阻止恶意攻击者利用 HTTP 请求中的头部、参数以及栈堆信息来进行攻击。这种拦截器可以在网络通信过程中对请求进行监控和分析,检测是否存在异常或恶意的请求,并在必要时拦截这些请求,从而保护网络系统的安全。
网络拦截器一般都是配合异步栈使用
滚轮往下,找到这个request点进去,在高亮那一行打上断点,再次切换分类(前面打的断点要释放掉,才可以在这里断住)
,
断住之后,查看他的这个m列表,这个列表储存了很多方法,都是回调方法
回调方法是指在异步操作完成后执行的函数。回调函数通常作为参数传递给异步函数,以便在异步操作完成后被调用。
在 JavaScript 中,常见的异步操作包括网络请求、定时器、事件处理等。当执行这些异步操作时,JavaScript 不会等待其完成,而是继续执行后续的代码。一旦异步操作完成,系统会调用预先定义好的回调函数,以便处理异步操作的结果或执行相关的逻辑。
一共有十几个,点进去第一个方法(网络拦截器就在里面)
一共有四个拦截器
后面两个是异常的时候才会用到的,不是我们要找的
前两个一个是请求一个是响应,我们需要找的是请求拦截器(因为先请求才会有响应)
在拦截器里面打上断点,释放程序(前面的断点要先释放掉),此时k值还没有出现
在拦截器外面设置断点,释放程序,此时k值出现了,说明这个t方法就是生成k值的
继续往里面进,查看t方法的具体内容
隔四行打一个断点,进一步找出生成k值的地方(一边调试一边观察右侧k值是否出现),有些地方一直循环的,可以把断点往下放一点
调试过后得出是由M生成的,于是按上面的方法,继续点进去M看内容(步骤较多,主要是为了掌握调试方法,用多了就很快了)
进去M之后,还需要继续找一下,截图截不全,太长了
function M(e, t, n) {
e = e.replace("/user/api/", "/common/v1/").replace("/web/api/", "/".concat("app", "/v1/")).replace("/web/api2/", "/".concat("app", "/v2/")).replace("/web/api3/", "/".concat("app", "/v3/")).replace("/video/api/", "/videotest/v1/").replace("/user/order/", "/put/v1/");
var r = [{
proxy: "/".concat("app"),
target: "",
sort: "dd",
num: 10,
s: n.state.u.s,
k: n.state.u.k,
l: n.state.u.l,
d: n.state.u.d
}, {
proxy: "/common",
target: "",
sort: "dc",
num: 10,
s: n.state.u.s,
k: n.state.u.k,
l: n.state.u.l,
d: n.state.u.d
}, {
proxy: "/videotest/",
target: "/",
sort: "dv",
server: !0,
num: 10,
s: n.state.u.s,
k: n.state.u.k,
l: n.state.u.l,
d: n.state.u.d
}];
return "/track/baidu_ocps" === e && (t.baseURL = "/"),
["/common/v1/config/basic", "/common/v1/config/system"].includes(e) || r.forEach((function(n) {
if (e.includes(n.proxy)) {
var path = e.replace(n.proxy, n.target);
if ("get" === t.method) {
t.paramsSerializer = function(e) {
return _.a.stringify(e, {
arrayFormat: "repeat"
})
}
,
t.params = h()(t.params, !1) || {};
var r = h()(t.params, !1)
, o = Object(y.a)(r, path, {
s: n.s,
k: n.k,
l: n.l,
d: n.d,
sort: n.sort,
num: n.num
}, "get");
t.params.k = o
} else if ("post" === t.method || "delete" === t.method || "put" === t.method) {
t.data = h()(t.data, !1) || {};
var data = h()(t.data, !1)
, d = Object(y.a)(data, path, {
s: n.s,
k: n.k,
l: n.l,
d: n.d,
sort: n.sort,
num: n.num
}, "post");
t.data.k = d
}
}
}
)),
t
}
4.详解js逆向定位与调试
继续打断点调试,找他的k值生成位置(同上,前面打的断点要先释放掉),这里很多地方打不进去断点,因为有些代码是一整行的,能打就打,然后一边调试一边观察k值就可以了
调试过后找到加密的地方在接近最下面的地方,把断点放到M结尾处,其他断点放掉,切换分类,这里是生成了o值,最后赋值给了k,变成k值
可以到控制台验证一下输出是否为加密好的o值(断点要打对控制台才能正常输出)
最后通过分析加密方法,得出是一个标准的MD5加密算法,自行解密即可