澳门在线威尼斯官方 > 澳门在线威尼斯官方 > 芝麻HTTP:JavaScript加密逻辑分析与Python模拟执行实

原标题:芝麻HTTP:JavaScript加密逻辑分析与Python模拟执行实

浏览次数:161 时间:2019-11-05

本节来证澳优下 JavaScript 加密逻辑剖析并使用 Python 模拟执行 JavaScript 实现数量爬取的长河。在此以中中原人民共和国空气品质在线监测解析平台为例来進展深入分析,首要分析其加密逻辑及破解方法,并使用 PyExecJS 来实现 JavaScript 模拟推行来贯彻该网站的数额爬取。

反混淆

JavaScript 混淆之后,其实是有反混淆方法的,最简便易行的措施正是探求在线反混淆网址,这里提供多个:,大家将 jquery-1.8.0.min.js 中第二行 eval 开始的歪曲后的 JavaScript 代码复制一下,然后粘贴到那一个网址中张开反混淆,就足以见见不奇怪的 JavaScript 代码了,找出一下就足以找到 getServerData() 方法了,能够看来那个主意真的产生了一个 Ajax 必要,诉求了刚刚我们分析到的接口:

图片 1

那正是谈到那边大家又可以发掘叁个很要紧的议程,那正是 getParam(),它承担了 method 和 object 参数,然后回来得到的 param 结果就视作 POST Data 参数伏乞接口了,所以 param 就是加密后的 POST Data,一些加密逻辑都在 getParam() 方法里面,其艺术完毕如下:

var getParam = (function () {
        function ObjectSort(obj) {
            var newObject = {};
            Object.keys(obj).sort().map(function (key) {
                newObject[key] = obj[key]
            });
            return newObject
        }
        return function (method, obj) {
            var appId = '1a45f75b824b2dc628d5955356b5ef18';
            var clienttype = 'WEB';
            var timestamp = new Date().getTime();
            var param = {
                appId: appId,
                method: method,
                timestamp: timestamp,
                clienttype: clienttype,
                object: obj,
                secret: hex_md5(appId + method + timestamp + clienttype + JSON.stringify(ObjectSort(obj)))
            };
            param = BASE64.encrypt(JSON.stringify(param));
            return AES.encrypt(param, aes_client_key, aes_client_iv)
        }
    })();

能够看出此间运用了 Base64 和 AES 加密。加密其后的字符串便作为 POST Data 传送给服务器了,然后服务器再举办解密处理,然后开展逻辑管理,然后再对拍卖后的数码开展加密,再次来到了加密后的数量,那么 JavaScript 再接受到之后再开展三遍解密,再渲染技巧赢得不奇怪的结果。

于是这里还索要深入分析服务器传回的数目是什么样解密的。顺腾摸瓜,超级轻巧就找到叁个 decodeData() 方法,其定义如下:

function decodeData(data) {
        data = AES.decrypt(data, aes_server_key, aes_server_iv);
        data = DES.decrypt(data, des_key, des_iv);
        data = BASE64.decrypt(data);
        return data
    }

啊,这里又通过了三层解密,才把例行的当众数据深入分析出来。

就此一切都清晰了,我们须要得以完结四个进度技能健康使用那些接口,即落到实处 POST Data 的加密进度和 Response Data 的解密进度。此中 POST Data 的加密进度是 Base64 + AES 加密,Response Data 的解密是 AES + DES + Base64 解密。加密解密的 Key 也都在 JavaScript 文件里能找到,大家用 Python 达成这个加密解密进度就能够了。

故而接下去怎么做?接着刚啊!

随之刚才怪!

何须去费这个事去用 Python 重写叁次JavaScript,万生机勃勃二者里面有多少格式不联合或许两个由于语言不包容难题以致总括结果不是,上哪个地方去 Debug?

那怎么做?这里我们赖以 PyExecJS 库来达成 JavaScript 模拟就好了。

PyExecJS

PyExecJS 是二个足以利用 Python 来模拟运转 JavaScript 的库。大家只怕听说过 PyV8,它也是用来效仿实施 JavaScript 的库,然而由于这一个项目已经不爱抚了,何况对 Python3 的支撑不佳,并且安装现身种种难点,所以这边选取了 PyExecJS 库来代替他。

首先大家来设置一下以此库:

pip install PyExecJS

行使 pip 安装就能够。

在利用这一个库早前请保管您的机械上设置了以下个中贰个JS运维条件:

  • JScript
  • JavaScriptCore
  • Nashorn
  • Node
  • PhantomJS
  • PyV8
  • SlimerJS
  • SpiderMonkey

PyExecJS 库会遵照优先级调用那些引擎来落到实处 JavaScript 推行,这里推荐安装 Node.js 或 PhantomJS。

随时大家运转代码检查一下运行条件:

import execjs
print(execjs.get().name)

运维之后,由于本身设置了 Node.js,所以那边会利用 Node.js 作为渲染引擎,结果如下:

Node.js (V8)

接下去大家将刚刚反混淆的 JavaScript 保存成二个文件,叫做 encryption.js,然后用 PyExecJS 模拟运转相关的措施就可以。

率先我们来达成加密进程,这里 getServerData() 方法其实早就帮我们兑现好了,并得以完结了 Ajax 央浼,但那几个点子里面有获取 Storage 的措施,Node.js 不适用,所以那边我们一贯改写下,实现一个getEncryptedData() 方法完结加密,在 encryption.js 里面落成如下方法:

function getEncryptedData(method, city, type, startTime, endTime) {
    var param = {};
    param.city = city;
    param.type = type;
    param.startTime = startTime;
    param.endTime = endTime;
    return getParam(method, param);
}

随之我们模拟实践这个方法即可:

import execjs

# Init environment
node = execjs.get()

# Params
method = 'GETCITYWEATHER'
city = '北京'
type = 'HOUR'
start_time = '2018-01-25 00:00:00'
end_time = '2018-01-25 23:00:00'

# Compile javascript
file = 'encryption.js'
ctx = node.compile(open(file).read())

# Get params
js = 'getEncryptedData("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
params = ctx.eval(js)

此处大家率先定义一些参数,如 method、city、start_time 等,那么些都足以通过剖判 JavaScript 非常轻巧得出其准则。

下一场这里首先通过 execjs(即 PyExecJS卡塔 尔(阿拉伯语:قطر‎的 get() 方法声明一个运维遭受,然后调用 compile() 方法来实践方才保存下去的加密库 encryption.js,因为那其间包括了生龙活虎部分加密方法和自定义方法,所以只有施行壹次本领调用。

接着大家再组织多个 js 字符串,传递这么些参数,然后经过 eval() 方法来效仿实行,获得的结果赋值为 params,那么些正是 POST Data 的加密数据。

随着大家平昔用 requests 库来效仿 POST 央浼就好了,也没须要用 jQuery 自带的 Ajax 了,当然后面一个也有效的,只可是需求加载一下 jQuery 库。

紧接着大家用 requests 库来模拟 POST 央求:

# Get encrypted response text
api = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
response = requests.post(api, data={'d': params})

那样 response 的从头到尾的经过就是服务器再次回到的加密的故事情节了。

接下去大家再调用一下 JavaScript 中的 decodeData() 方法就可以达成解密:

# Decode data
js = 'decodeData("{0}")'.format(response.text)
decrypted_data = ctx.eval(js)

这样 decrypted_data 就是解密后的字符串了,解密之后,实际上是二个 JSON 字符串:

{'success': True, 'errcode': 0, 'errmsg': 'success', 'result': {'success': True, 'data': {'total': 22, 'rows': [{'time': '2018-01-25 00:00:00', 'temp': '-7', 'humi': '35', 'wse': '1', 'wd': '东北风', 'tq': '晴'}, {'time': '2018-01-25 01:00:00', 'temp': '-9', 'humi': '38', 'wse': '1', 'wd': '西风', 'tq': '晴'}, {'time': '2018-01-25 02:00:00', 'temp': '-10', 'humi': '40', 'wse': '1', 'wd': '东北风', 'tq': '晴'}, {'time': '2018-01-25 03:00:00', 'temp': '-8', 'humi': '27', 'wse': '2', 'wd': '东北风', 'tq': '晴'}, {'time': '2018-01-25 04:00:00', 'temp': '-8', 'humi': '26', 'wse': '2', 'wd': '东风', 'tq': '晴'}, {'time': '2018-01-25 05:00:00', 'temp': '-8', 'humi': '23', 'wse': '2', 'wd': '东北风', 'tq': '晴'}, {'time': '2018-01-25 06:00:00', 'temp': '-9', 'humi': '27', 'wse': '2', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 07:00:00', 'temp': '-9', 'humi': '24', 'wse': '2', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 08:00:00', 'temp': '-9', 'humi': '25', 'wse': '2', 'wd': '东风', 'tq': '晴转多云转多云间晴'}, {'time': '2018-01-25 09:00:00', 'temp': '-8', 'humi': '21', 'wse': '3', 'wd': '东北风', 'tq': '晴转多云转多云间晴'}, {'time': '2018-01-25 10:00:00', 'temp': '-7', 'humi': '19', 'wse': '3', 'wd': '东北风', 'tq': '晴转多云转多云间晴'}, {'time': '2018-01-25 11:00:00', 'temp': '-6', 'humi': '18', 'wse': '3', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 12:00:00', 'temp': '-6', 'humi': '17', 'wse': '3', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 13:00:00', 'temp': '-5', 'humi': '17', 'wse': '2', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 14:00:00', 'temp': '-5', 'humi': '16', 'wse': '2', 'wd': '东风', 'tq': '多云'}, {'time': '2018-01-25 15:00:00', 'temp': '-5', 'humi': '15', 'wse': '2', 'wd': '北风', 'tq': '多云'}, {'time': '2018-01-25 16:00:00', 'temp': '-5', 'humi': '16', 'wse': '2', 'wd': '东北风', 'tq': '多云'}, {'time': '2018-01-25 17:00:00', 'temp': '-5', 'humi': '16', 'wse': '2', 'wd': '东风', 'tq': '多云'}, {'time': '2018-01-25 18:00:00', 'temp': '-6', 'humi': '18', 'wse': '2', 'wd': '东风', 'tq': '晴间多云'}, {'time': '2018-01-25 19:00:00', 'temp': '-7', 'humi': '19', 'wse': '2', 'wd': '东风', 'tq': '晴间多云'}, {'time': '2018-01-25 20:00:00', 'temp': '-7', 'humi': '19', 'wse': '1', 'wd': '东风', 'tq': '晴间多云'}, {'time': '2018-01-25 21:00:00', 'temp': '-7', 'humi': '19', 'wse': '0', 'wd': '南风', 'tq': '晴间多云'}]}}}

功勋卓著告成!

如此大家就足以成功得到温度、湿度、风力、天气等音讯了。

其余那有些数据实际上不全,还会有 PM 2.5、AQI 等数据需求用此外四个 method 参数 GETDETAIL,改进一下就能够获得那有的多少了。

再以后的数目便是分析和存储了,这里不再赘言。

本文由澳门在线威尼斯官方发布于澳门在线威尼斯官方,转载请注明出处:芝麻HTTP:JavaScript加密逻辑分析与Python模拟执行实

关键词:

上一篇:没有了

下一篇:澳门在线威尼斯官方:自学课程,第五堂课