声明
本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文未经许可禁止转载,禁止任何形式的修改后进行二次传播,若有侵权,请联系作者删除!
逆向目标
- 目标:aHR0cDovL3d3dy5zcG9saWN5LmNvbS8=
抓包分析
这里需要右键检查打开开发者工具,F12不行的已被网站禁用,出现无限debugger
解决无限debugger的方法可以进行hook将debugger函数置空,注入方式有很多,这里选择控制台注入如下代码
var AAA=Function.prototype.constructor
Function.prototype.constructor=function(n){
if(n!="debugger"){
return AAA(n)
}
return function(){};
}
控制台注入
转到源代码页面点击跳过,即可正常调试网页
开始抓包
加载了一个数据接口
点击进去,发现请求参数是进制流,需要逆向分析,数据明文响应
复制路径进行XHR断点调试
点击切换,加载数据成功断住
进制流数据已加载出来
继续分析,查找数据是在哪里实现进制流的,点击跳出当前函数找到如图所示位置
axiosInstance[sr(918, 893, 289, 785, "&8n(") + sK(1381, "NujK", 1269) + "rs"][sK(639, "l*hm", 1046) + sB("l*hm", 2190, 1697, 2005)][sr(493, 860, 346, 780, "auGk")]
像这种进制流是由拦截器生成的,拦截器分为request和response,这种是在request里生成的,我们先还原一下上面这段代码
axiosInstance[sr(918, 893, 289, 785, "&8n(") + sK(1381, "NujK", 1269) + "rs"][sK(639, "l*hm", 1046) + sB("l*hm", 2190, 1697, 2005)][sr(493, 860, 346, 780, "auGk")]
//axiosInstance['interceptors']['response']['use']
我们看到还原后是response,我们要找的是request,ctrl+f搜索一下axiosInstance,找到如下位置
axiosInstance[sd(83, "&8n(", 207, 214, 527) + sr(1006, 562, 915, 902, "zj&U") + "rs"][sK(1548, "WAuM", 1535) + "st"][sY(247, "FDww")]
//axiosInstance['interceptors']['request']['use']
这里就是我们要找的request,打上断点,再删掉之前的XHR断点,放掉断点再次点击切换
成功在断点处断住,明文数据如下图
点击下图位置进行调试
多次调试发现数据在经过断点处代码后变成进制流
把代码扣出来
n[a(502, 444, 578, 484, "NujK")] = u[s(412, "K*ER", -308, 112) + "e"](n[i(774, "A!hb")])[r(642, 1123, 1176, "6#7Q") + "h"]()[r(466, 755, 569, "!X^n")]()
//n["data"] = u["encode"](n["data"])["finish"]()['slice']()
n["data"]就是请求参数明文
n["data"] = {
"policyType": "6",
"province": "",
"city": "",
"downtown": "",
"garden": "",
"centralId": "",
"sort": 0,
"homePageFlag": 1,
"pageNum": 1,
"pageSize": 7
}
接下来需要找到u["encode"],选中后跳进去,扣出如下代码
补全代码后本地运行调试
function PolicyInfoByTypeIdParam$encode(m,w){
if(!w)
w=Writer.create()
if(m.policyType!=null&&Object.hasOwnProperty.call(m,"policyType"))
w.uint32(10).string(m.policyType)
if(m.centralId!=null&&Object.hasOwnProperty.call(m,"centralId"))
w.uint32(18).string(m.centralId)
if(m.province!=null&&Object.hasOwnProperty.call(m,"province"))
w.uint32(26).string(m.province)
if(m.city!=null&&Object.hasOwnProperty.call(m,"city"))
w.uint32(34).string(m.city)
if(m.downtown!=null&&Object.hasOwnProperty.call(m,"downtown"))
w.uint32(42).string(m.downtown)
if(m.garden!=null&&Object.hasOwnProperty.call(m,"garden"))
w.uint32(50).string(m.garden)
if(m.sort!=null&&Object.hasOwnProperty.call(m,"sort"))
w.uint32(56).uint32(m.sort)
if(m.pageNum!=null&&Object.hasOwnProperty.call(m,"pageNum"))
w.uint32(64).uint32(m.pageNum)
if(m.pageSize!=null&&Object.hasOwnProperty.call(m,"pageSize"))
w.uint32(72).uint32(m.pageSize)
if(m.homePageFlag!=null&&Object.hasOwnProperty.call(m,"homePageFlag"))
w.uint32(80).uint32(m.homePageFlag)
return w
}
data = {
"policyType": "6",
"province": "",
"city": "",
"downtown": "",
"garden": "",
"centralId": "",
"sort": 0,
"homePageFlag": 1,
"pageNum": 1,
"pageSize": 7
}
data = PolicyInfoByTypeIdParam$encode(data)["finish"]()['slice']()
出现以下错误
Writer显示未定义,继续扣代码
发现是一个webpack,找到此处将整个加载器抠出来
这里代码很长,直接折叠代码,很方便就扣下来了,如果不能折叠自行搜索方法或更换浏览器,也可以不折叠但很费眼睛!!!
扣下来是这样的,这里可以再删掉一下多余的代码
直接改为这样
这两个是一样的效果,可以直接删掉外面的自执行函数
然后定义变量全局导出
导出后使用如下
w=red.Writer.create()
然后运行会报如下错误
commonjsGlobal变量没有定义,在js中搜索一下
找到如下代码,直接补到本地即可
commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
到此全部逆向完毕
最后疑问
那上图逆向出来的东西如何使用呢,这里提供一个方法,其余自行思考+百度(gpt也可以,还更方便哦)
data = execjs.compile(open("XXX.js","r",encoding="utf-8").read()).call("XXX")
data_list = data['data']
byte_array = bytes(data_list).decode()