webpack是 JavaScript 应用程序的模块打包器,可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。所有的资源都是通过JavaScript渲染出来的。
如果代码中出现了类似 `n('123')` 这样的代码,就可以大概知道了这是webpack打包的js模块代码。其中 `n` 就是分发器,定位到这个函数很简单,就只需要在分发器的位置打上断点,然后重新刷新当前页面即可。
!function(x){
function a(t) { // 分发器,参数t为模块名称
if (r[t])
return r[t].exports;
var n = r[t] = {
i: t,
l: !1,
exports: {}
};
return e[t].call(n.exports, n, n.exports, a),
n.l = !0,
n.exports
}
}
(
//模块有两种组成方式,取其一
// 第一种,由数组组成,调用时,数组从0开始计算
// [function (){
// console.log(1)
// }, function (){
// console.log(2)
// }]
// 第二种,由对象组成,调用时,只需根据模块名称调用即可
{
'asdf': function (){
console.log('asdf')
},
'qwer': function (){
console.log('qwer')
}
}
)
aHR0cHM6Ly9oc2RkY3gud3Nqa3cuemouZ292LmNuL3dlYmFwcC9hcHAtbW9iaWxlL2VwaWRNYXA=
打开控制台,下拉页面,发现只有一个接口。而且其中请求参数和响应结果都是经过加密之后的,如下:
这个站点还是比较友好的,直接在 console面板中就已经把加密的位置暴露出来了。
点击进入之后发现如下代码,并且在合适的位置下断点,下拉页面,断点就能生效,如下:
我们可以通过控制台输出个别参数,可以看出来,`t` 就是post请求需要的加密前的参数,并且在第1429行,已经生成加密参数了。所以,我们构造如下代码:
function get_encrypt_params(page) {
// 传进来一个页码参数,动态生成加密后的参数
var t = {
"orgName": "",
"pageNum": page,
"pageSize": 30,
"areaName": "",
"levelName": "",
"serviceStatus": "",
"gisLat": "",
"gisLng": "",
"isFree": "",
"isRed": "",
"isYellow": "",
"isNeedHs": "",
"isLive": "0"
},
n = JSON.stringify(t),
n1 = a.enc.Utf8.parse(n),
n2 = f.a.encrypt(n1, w, {
iv: O
}).toString()
return n2
}
其中,未知参数 `a, f, w, O`,在当前js文件中,往上查找,可以找到这几个参数的定义位置。如下:
经过第一步分析,类似这种的,就是webpack打包的js模块代码。在图示所示位置打上断点,重新刷新页面(不是下拉页面哦),断点即可生效。并在控制台中输入 `n` 并点击进去,即可找到分发器。
把自执行函数里边的内容复制下来,不需要复制模块函数。接下来就是我们自己去补模块函数了。回到断点的位置,`a = n("21bf")`,搜索该模块,并复制。
我最终补出来的如下:
经过测试,在本地控制台输出的结果和网页上输出的结果一致。
如下,过程和请求参数加密差不多。
function get_decrypt_data(encrypt_data) {
var i = f.a.decrypt({
ciphertext: a.enc.Base64.parse(encrypt_data.replace(/\s+/g, ""))
}, w, {
iv: O,
padding: s.a.pad.Pkcs7
}).toString(s.a.enc.Utf8);
return JSON.parse(i)
}