【金沙澳门官网】芝麻HTTP:JavaScript加密逻辑分析

作者: 网络编程  发布:2019-07-18

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() 方法声贝拉米(Bellamy)个周转情状,然后调用 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,修改一下就可以获取这一部分数目了。

再今后的数据正是剖判和存款和储蓄了,这里不再赘述。

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,修改一下就能够获取这一部分数额了。

再将来的数额就是解析和仓库储存了,这里不再赘述。

本节来验证一下 JavaScript 加密逻辑剖判并动用 Python 模拟实行...

反混淆

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 模拟就好了。

反混淆

JavaScript 混淆之后,其实是有反混淆方法的,最轻松易行的办法正是搜索在线反混淆网址,这里提供贰个: jquery-1.8.0.min.js 中第二行 eval 开头的混淆后的 JavaScript 代码复制一下,然后粘贴到那几个网站中开始展览反混淆,就能够看到平常的 JavaScript 代码了,搜索一下就足以找到 getServerData() 方法了,能够看看那一个艺术确实产生了叁个 Ajax 诉求,乞请了刚刚大家剖判到的接口:

金沙澳门官网 2

那就是提及此处大家又有啥不可发掘三个很要紧的法子,那便是 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 模拟就好了。

本文由金沙澳门官网发布于网络编程,转载请注明出处:【金沙澳门官网】芝麻HTTP:JavaScript加密逻辑分析

关键词: 金沙澳门官网

上一篇:芝麻代理基本原理,代理的基本原理
下一篇:没有了