JS解密:处理 jQuery 代码混淆破解中国空气质量在线网站
2020-06-25 本文已影响0人
dex0423
1. 前言
- 本文的主要内容,是通过处理 jQuery 代码混淆,逆向破解中国空气质量在线网站,网站地址:https://www.aqistudy.cn/html/city_detail.html;
- 并通过 pyexecuteJS 调用这段 jQuery 代码,从而构造参数模拟请求,以获取想要的数据;
2. 分析
- 通过查看网页,发现这是一个动态 AJAX 加载的网页;
- 当鼠标点击 查找 按钮的时候,会触发网页 查找 事件;
- 调出调试窗口,按照下图所示的步骤,分析查找事件对应的代码文件;
- 在下图位置找到 getData() 方法,但并没有 getData() 方法具体代码内容,ctrl + F 调出文本搜索框,搜索 getData;
- 通过搜索找到了getData() 定义,但未发现 click 事件需要的 jQuery 格式的代码;
-- 注意:关于 jQuery 格式的代码,请参考我的另一篇文章《JS解密:AJAX 请求的 jQuery 语法格式样例》;
- 但在 function getData() 代码块中,发现尾部调用了 getAQIData()、getWeatherData() 两个方法,继续搜索这两个方法;
- 找到后分析发现,两个方法结构相同,都先赋值两个变量 method 和 param,之后都调用了 getServerData() 方法;
-
查看代码发现,getServerData() 方法有四个参数,分别是 method、param、function(obj){...}、0.5 四个参数,其中:
-- method 值为 'GETDETAIL';
-- param 为字典,共有四个元素,city、type、startTime、endTime,分别对应 城市、类型、开始时间、截止时间,这里注意 type 为 'HOUR',在上面的图中可以找到 if(type=='HOUR') 代码;
image.png - 我们继续搜索 getServerData 方法,发现这个文件中没有该方法的定义,改为全局搜索该方法,通过分析文件代码发现代码被混淆过;
- 将这段被混淆的代码复制下来,用于反混淆;
3. 反混淆
- 打开网站 https://www.bm8.com.cn/jsConfusion/,在输入框输入前面被混淆的代码;
- 格式化之后得到下面的代码,在代码尾部找到 getServerData 定义,并发现 jQuery 格式代码;
- 得到反混淆后的 getServerData 代码;
function getServerData(method, object, callback, period) {
const key = hex_md5(method + JSON.stringify(object));
const data = getDataFromLocalStorage(key, period);
if (!data) {
var param = getParam(method, object); //这段代码就是获取参数的代码
$.ajax({
url: '../apinew/aqistudyapi.php',
data: {
d: param
},
type: "post",
success: function (data) {
data = decodeData(data);
obj = JSON.parse(data);
if (obj.success) {
if (period > 0) {
obj.result.time = new Date().getTime();
localStorageUtil.save(key, obj.result)
}
callback(obj.result)
} else {
console.log(obj.errcode, obj.errmsg)
}
}
})
} else {
callback(data)
}
}
- 在 js 文件中新建 function 调用 getParam;
function getPostParamCode (method, city, type, startTime, endTime){
var param = {};
param.city = city;
param.type = type;
param.startTime = startTime;
param.endTime = endTime;
return getParam(method, param);
}
- 编辑 py 代码,调用 js;
import execjs
# Params
method = 'GETDETAIL'
city = '北京'
type = 'HOUR'
start_time = '2018-01-25 00:00:00'
end_time = '2018-01-25 23:00:00'
# Compile javascript
file = 'aqi.js'
ctx = execjs.compile(open(file=file, encoding='utf-8').read())
# js = 'getPostParamCode("{}", "{}", "{}", "{}", "{}")'.format(method, city, type, start_time, end_time)
# params = ctx.call('getPostParamCode', method, city, type, start_time, end_time)
# print(params)
#发起post请求
url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
response_text = requests.post(url, data={'d': params}).text
print(response_text)