中国空气质量在线监测分析平台-js混淆的坑

  • 一、背景
  • 二、过程
    • 1、确定加密参数
    • 2、确定加密函数
    • 3、处理js函数
  • 三、总结

一、背景

分析过程参照:https://cuiqingcai.com/5024.html , 主要梳理下处理这类js混淆的思路,并记录踩过的坑

二、过程

1、确定加密参数

点进去后抓包,没有明显的数据接口链接,切换一个城市后,发现两个数据接口:https://www.aqistudy.cn/apinew/aqistudyapi.php ,链接相同,post_data不同(一个请求AQI数据,一个请求天气数据),该请求post_data整个进行了加密,同时返回结果也进行了加密

2、确定加密函数

全局搜索‘d’显然是不现实的,所以通过城市列表中各城市对应的点击事件为突破口,寻找js函数

将鼠标放在北京上,在Elements右侧(或下侧)的事件监听(Event Listeners)的点击事件中,可以看到相应的事件,点击红色箭头所指,会跳转到对应的js函数中,如下图

该函数中,发现一个函数getData(),显然是获取数据的js, 全局搜索,最终在:https://www.aqistudy.cn/html/city_detail.html 中发现该函数

调用了两个函数getAQIData()和getWeatherData(),查看这两个函数后,发现均调用了同一个函数getServerData(),在 https://www.aqistudy.cn/js/jquery-1.8.0.min.js?v=1.2 中发现该函数,但是是经过js混淆的代码

通过反混淆处理网站(http://www.bm8.com.cn/jsConfusion/ ),将从eval往下全部复制,通过反混淆处理,获得明文

在getServerData中,通过调用函数getParam进行请求参数加密,decodeData函数进行返回结果解密

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)}})();

getParam对参数进行了MD5, base64以及AES加密

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}

decodeData函数也进行了AES、DES、base64解密

3、处理js函数

方法一:Python实现:暂未实现,AES加解密没有实现,

import hashlib
def MD5(data_str):object = hashlib.md5()object.update(data_str.encode('utf-8'))return object.hexdigest()appId='1a45f75b824b2dc628d5955356b5ef18'
method='GETDETAIL'
timestamp=str(int(time.time()*13))
clienttype='WEB'
obj= '{"city":"北京","endTime":"2019-05-14 08:00:00","startTime":"2019-05-14 05:00:00","type":"HOUR"}'
data = appId + method + timestamp + clienttype + obj
secret = MD5(data)
dicts = '''{appId: %s, clienttype: %s, method: %s, object: %s, secret: %s, timestamp: %s,}'''%(appId, clienttype, method, obj, secret, timestamp)
ss = base64.b64encode(dicts.encode())

python重写时,需要注意字典的顺序,js加密时是安装字典的key值进行了排序,而Python的字典是无序的

方法二:执行js代码,选择js2py
新增一个函数,用于传递数据,调用参数加密函数

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

使用node.js执行时,将加密后的参数用于请求数据,返回数据正常,但是当通过js2py执行时,返回结果:{“success”:false,“errcode”:1005,“errmsg”:“invalid timestamp”},通过日志打印,发现了两次执行时不同之处:

secret: hex_md5(appId + method + timestamp + clienttype + JSON.stringify(ObjectSort(obj)))
该参数的JSON.stringify(ObjectSort(obj)),打印出来不同,
node.js:{"city":"北京","endTime":"2019-05-14 08:00:00","startTime":"2019-05-14 05:00:00","type":"HOUR"}
js2py:{"city":"\\u5317\\u4eac","endTime":"2019-05-14 08:00:00","startTime":"2019-05-14 05:00:00","type":"HOUR"}

通过Python实现secret的加密,并传入js,实现加密过程,改写的getEncryptedData和getParam函数

function getEncryptedData(method, city, type, startTime, endTime, timestamp, secret) {var param = {};param.city = city;param.type = type;param.startTime = startTime;param.endTime = endTime;xx = getParam(method, param, timestamp, secret);return xx
}
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, timestamp, secret) {var appId = '1a45f75b824b2dc628d5955356b5ef18';var clienttype = 'WEB';var param = {appId: appId,method: method,timestamp: timestamp,clienttype: clienttype,object: obj,secret: secret};param = BASE64.encrypt(JSON.stringify(param));return AES.encrypt(param, aes_client_key, aes_client_iv)}})();

Python调用代码

import time
import requests
import hashlib
import js2pydef MD5(data_str):object = hashlib.md5()object.update(data_str.encode('utf-8'))return object.hexdigest()def get_data(city, type, startTime, endTime, method):appId = '1a45f75b824b2dc628d5955356b5ef18'timestamp = str(int(time.time() * 1000))clienttype = 'WEB'obj = '{"city":"%s","endTime":"%s","startTime":"%s","type":"%s"}' % (city, endTime, startTime, type)data = appId + method + timestamp + clienttype + objsecret = MD5(data)with open('tac.js') as f:js = f.read()context = js2py.EvalJs()context.execute(js)param_sign = context.getEncryptedData(method, city, type, startTime, endTime, timestamp, secret)url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'post_data = {'d': param_sign,}headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',}response = requests.post(url, data=post_data, headers=headers)data = context.decodeData(response.text)print(data)if __name__ == '__main__':city = '北京'type = 'HOUR'startTime = '2019-05-14 05:00:00'endTime = '2019-05-14 08:00:00'method = 'GETDETAIL'get_data(city, type, startTime, endTime, method)time.sleep(1)method = 'GETCITYWEATHER'get_data(city, type, startTime, endTime, method)

三、总结

  • python重写js代码时,注意字典的顺序,js加密时是安装字典的key值进行了排序,而Python的字典是无序的
  • js加密的一般处理思路:
    • 加密url或某个post_data参数时,可以全局搜索对应的参数名或者值,确定js函数
    • 整个post_data加密或无法搜索到参数,可通过元素的事件监听,确定js函数
  • 注意node.js与其他执行js的Python库对数据处理的不同之处

中国空气质量在线监测分析平台-js混淆的坑相关推荐

  1. 爬取中国空气质量在线监测分析平台

    1.准备,爬取的链接地址 https://www.aqistudy.cn/html/city_detail.html 2.分析 a.当打开链接后,数据已经设置好了,说明里面大部分都是js通过ajax调 ...

  2. python爬虫爬取(中国空气质量在线监测分析平台)北京PM2.5,2013年至2018年的数据

    要爬取的数据网站如下图所示: 即是爬取该网站2013年12月2日至2018年11月份北京空气质量指数历史数据,其中要爬起的 内容如PM2.5,So2等,即是从这个网页内置的表格中爬取,因为该网站比较有 ...

  3. java获取空气质量在线监测分析平台(PM2.5真气网)数据

    空气质量在线监测分析平台(PM2.5真气网) https://www.aqistudy.cn/ 获取实时监测数据: 通过以上信息可知请求需要携带的参数d是加密的,返回的信息也是加密的 查找getSer ...

  4. python爬取中国空气质量在线监测平台分析数据【已更新】

    **本文介绍如何爬取诸如北京等城市的空气污染物浓度数据,并附有完整代码,统统解决你们找不到数据的科研问题!干货满满!!! 2021年1月12日更新 看了很多小伙伴的评论,发现我的代码被官方给" ...

  5. 中国空气质量在线监測分析平台

    中国空气质量在线监測分析平台是公益性质的软件平台,提供PM2.5及天气数据的实时查询和历史数据可视化分析,统计挖掘,眼下收录了190个城市的PM2.5及天气信息数据,主要包含PM2.5实时查询.历史曲 ...

  6. 环保数采仪助力空气质量在线监测系统

    空气的质量和人民生活健康息息相关.目前,空气污染源影响空气质量的最主要因素之一是来自固定和流动污染源的人为污染物排放,包括车辆.船舶.飞机的尾气.工业污染.居民生活和取暖.垃圾焚烧等. 随着生活水平的 ...

  7. 【python爬虫】js逆向:空气质量在线平台,解决反调试,加密

    js逆向:pyhon爬虫空气质量,无线debugger,AES,DES,MD5加密 前言 解决无限debugger 第一次debugger 第二次debugger 加密解密流程分析 请求数据加密 返回 ...

  8. 空气质量在线检测平台 js 逆向)(aqistudy)

    # **空气质量在线检测平台 js 逆向 全新版本 学习内容: (多了提个eval()加密)https://www.aqistudy.cn/apinew/aqistudyapi.php:** 学习内容 ...

  9. VOCs在线监测云平台 甲烷 非甲烷总炷监测 环保治污解决方案(安科瑞-须静燕)

    VOCs,也称挥发性有机物,包括非甲烷总烃.苯系物(苯.甲苯.乙苯.二甲苯等).挥发性卤代烃(二氯甲烷.氯仿.四氯化碳等).醇类(乙醇.异丙醇.乙二醇等).醚类(乙醚.丁醚.四氢呋喃等)等有机挥发性有 ...

最新文章

  1. excel去掉超链接
  2. 近世代数--有限交换群--存在子群的阶是群阶的因子
  3. MS CRM 2011中的新特性(1)——界面部分
  4. 不止代码:机器分配(动态规划)
  5. Oracle约数,Oracle约束简介
  6. mysql 表 组织 管理_MySQL 基础知识梳理学习(二)----记录在页面层级的组织管理...
  7. MATLAB 中 floor、round、ceil、fix 取整函数的意义和区别
  8. 都昌时间轴控件功能说明
  9. win10无线投屏_win10无线投屏智能电视
  10. bootstrop table api
  11. Weakly Supervised Instance Segmentation using Class Peak Response论文复现以及遇到的问题
  12. 如何成为优秀的软件人才
  13. poj1723 SOLDIERS
  14. java中时间的转换相关问题整理
  15. 《2019腾讯区块链白皮书》全文发布,13次提及Facebook加密项目Libra(附下载)
  16. android 解锁过程,Android-解锁与刷机(以一加为例)
  17. 什么是递归查询,迭代查询?
  18. Druid之——连接池自定义数据库密码加解密的实现
  19. 有关笔记本电池校正的方法
  20. JAVA地铁舆情管理系统计算机毕业设计Mybatis+系统+数据库+调试部署

热门文章

  1. 如何在VMware虚拟机上安装运行Mac OS系统(详细图文教程)
  2. js电影票预订座位网页js特效
  3. 哪些开源协议可以商用
  4. Spring 学习 (三)大话AOP
  5. 七阶拉丁方阵_拉丁方阵【转】
  6. java web中英翻译_中英文翻译简单web项目示例(3)
  7. 面试题之__分苹果(java实现)
  8. STM32单片机基础之蜂鸣器
  9. pap认证失败_PPP PAP(CHAP)认证
  10. 阿里云网站备案申请被驳回怎么办?