声明

本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。

逆向目标

逆向过程

本次的逆向目标是建筑市场监管平台的企业数据,来到全国建筑市场监管公共服务平台首页,依次点击数据服务 —> 企业数据,尝试抓包一下所有企业的数据,可以看到返回的数据是经过加密的:

数据看不出来是什么加密方式,但是加密分析得多了,就知道一般都是经过 CryptoJS 加密模块加密得到的,那么我们可以尝试直接搜索 CryptoJSdecrypt 等关键字,或者搜索加密算法中经常用到的偏移量 iv、模式 mode、填充方式 padding 等,还有一般的 JSON 数据可以搜索 JSON.parse 等,这里直接搜索 JSON.parse,在 app.a9f6bb6d.js 文件里定位到可疑代码,埋下断点进行调试:

可以看到 e 就是解密后的数据,观察语句 var e = JSON.parse(h(t.data));,直接跟进 h 函数,可以看到很明显的 AES 加密:

function h(t) {
var e = d.a.enc.Hex.parse(t)
, n = d.a.enc.Base64.stringify(e)
, a = d.a.AES.decrypt(n, f, {
iv: m,
mode: d.a.mode.CBC,
padding: d.a.pad.Pkcs7
})
, r = a.toString(d.a.enc.Utf8);
return r.toString()
}

加密模式为 CBC,填充方式为 Pkcs7,而缺少的偏移量 m、f 的值,在上面也可以找到:

f = d.a.enc.Utf8.parse("jo8j9wGw%6HbxfFn")
m = d.a.enc.Utf8.parse("0123456789ABCDEF")

在 Python 当中,直接引入 CryptoJS,重写这个函数即可。

完整代码

完整代码可在 GitHub 下载:https://github.com/kuaidaili/crawler/tree/main/jzsc_mohurd_gov_cn

jzsc_mohurd_decrypt.js

// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js') function getDecryptedData(t) {
var m = CryptoJS.enc.Utf8.parse("0123456789ABCDEF"),
f = CryptoJS.enc.Utf8.parse("jo8j9wGw%6HbxfFn"),
e = CryptoJS.enc.Hex.parse(t),
n = CryptoJS.enc.Base64.stringify(e),
a = CryptoJS.AES.decrypt(n, f, {
iv: m,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}),
r = a.toString(CryptoJS.enc.Utf8);
return r.toString()
} // 测试样例
// var t = '95780ba094xxxxxxxxxx'
// console.log(getDecryptedData(t))

jzsc_mohurd.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import json import execjs
import requests data_url = 'http://jzsc.mohurd.gov.cn/api/webApi/dataservice/query/comp/list?pg=%s&pgsz=15&total=450' def get_encrypted_data(page):
headers = {
'Host': 'jzsc.mohurd.gov.cn',
'Referer': 'http://jzsc.mohurd.gov.cn/data/company',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
encrypted_data = requests.get(url=data_url % page, headers=headers).text
return encrypted_data def get_decrypted_data(encrypted_data):
with open('jzsc_mohurd_decrypt.js', 'r', encoding='utf-8') as f:
jzsc_mohurd_js = f.read()
decrypted_data = execjs.compile(jzsc_mohurd_js).call('getDecryptedData', encrypted_data)
return json.loads(decrypted_data) def main():
# 30页数据
for page in range(30):
encrypted_data = get_encrypted_data(page)
decrypted_data = get_decrypted_data(encrypted_data)
print(decrypted_data) if __name__ == '__main__':
main()

【JS 逆向百例】建筑市场监管平台企业数据的更多相关文章

  1. 通过JS逆向ProtoBuf 反反爬思路分享

    前言 本文意在记录,在爬虫过程中,我首次遇到Protobuf时的一系列问题和解决问题的思路. 文章编写遵循当时工作的思路,优点:非常详细,缺点:文字冗长,描述不准确 protobuf用在前后端传输,在 ...

  2. 年底奉献-QT编写视频监管平台(开源)

    忙忙碌碌又是一年,算算自己毕业四年半,一直在现在这家公司做研发外加总经理助理,研发起初用的VB.NET,而后全面转为C#,最后又全面转为QT,都是由于项目需要,算下来自己搞QT编程也已经四年了,201 ...

  3. 网络爬虫之记一次js逆向解密经历

    1 引言 数月前写过某网站(请原谅我的掩耳盗铃)的爬虫,这两天需要重新采集一次,用的是scrapy-redis框架,本以为二次爬取可以轻松完成的,可没想到爬虫启动没几秒,出现了大堆的重试提示,心里顿时 ...

  4. 我去!爬虫遇到JS逆向AES加密反爬,哭了

    今天准备爬取网页时,遇到『JS逆向AES加密』反爬.比如这样的: 在发送请求获取数据时,需要用到参数params和encSecKey,但是这两个参数经过JS逆向AES加密而来. 既然遇到了这个情况,那 ...

  5. Tapdata 实时数据融合平台解决方案(一):现代企业数据架构及痛点

    作者介绍:TJ,唐建法,Tapdata 钛铂数据 CTO,MongoDB中文社区主席,原MongoDB大中华区首席架构师,极客时间MongoDB视频课程讲师. "怎样可以来搭建一个数据中台? ...

  6. JS逆向之补环境过瑞数详解

    JS逆向之补环境过瑞数详解 "瑞数" 是逆向路上的一座大山,是许多JS逆向者绕不开的一堵围墙,也是跳槽简历上的一个亮点,我们必须得在下次跳槽前攻克它!! 好在现在网上有很多讲解瑞数 ...

  7. JS逆向之浏览器补环境详解

    JS逆向之浏览器补环境详解 "补浏览器环境"是JS逆向者升职加薪的必备技能,也是工作中不可避免的操作. 为了让大家彻底搞懂 "补浏览器环境"的缘由及原理,本文将 ...

  8. Java使用正则表达式取网页中的一段内容(以取Js方法为例)

    关于正则表达式: 表1.常用的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串 ...

  9. 用FineReport报表系统构建资金监管平台

    一.应用背景 计算机的应用已经渗透到日常工作的许多方面,无论是其自身还是所发挥的作用,计算机都标志着一种高科技,使工作高效率和高水平.为了能更方便,更轻松,更好的管理,信息化建设正在日益发展壮大,更加 ...

  10. DataPipeline丨新型企业数据融合平台的探索与实践

    文 |刘瀚林 DataPipeline后端研发负责人 交流微信 | datapipeline2018 一.关于数据融合和企业数据融合平台 数据融合是把不同来源.格式.特点性质的数据在逻辑上或物理上有机 ...

随机推荐

  1. Solon 开发进阶,四、启动参数说明

    Solon 开发进阶 一.插件扩展机制 二.体外扩展机制 三.常用配置说明 四.启动参数说明 五.全局异常订阅 启动参数,在应用启动后会被静态化(为了内部更高效的利用).比如,想通过体外扩展加载配置, ...

  2. Netty ChannelFuture 监听三种方法

    以下是伪代码 方法一 前后代码省略 //绑定服务器,该实例将提供有关IO操作的结果或状态的信息 ChannelFuture channelFuture = bootstrap.bind(); this ...

  3. 将应用程序注册为Linux系统服务,并设置开机自启动

    1.新建服务文件 vim /usr/lib/systemd/system/statagent.service 其中statagent是自定义的服务名称 2.文件内容 [Unit] Descriptio ...

  4. 生成学习全景:从基础理论到GANs技术实战

    本文全面探讨了生成学习的理论与实践,包括对生成学习与判别学习的比较.详细解析GANs.VAEs及自回归模型的工作原理与结构,并通过实战案例展示了GAN模型在PyTorch中的实现. 关注TechLea ...

  5. 牛客 | 一起来做题~欢乐赛2 (AK 题解)

    补题链接:Here A.新比赛,在眼前. 对于每次猜数和裁判的判断,可以确定一个区间内所有的数都有可能,比如对于样例中(8 +)来说,[ -INT_MIN, 7] 中所有的数都有可能,那么对于每次猜数 ...

  6. L2-010. 排座位(种类并查集)

    布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位.无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席. 输入格式: ...

  7. OKR之剑·实战篇04:OKR执行过程优化的那些关键事

    作者:vivo 互联网平台产品研发团队 本文是<OKR 之剑>系列之实战第 4 篇--OKR执行过程不是一成不变的,团队和个人在执行中不断优化执行的具体行动,保障OKR的高效执行. 前言 ...

  8. 三、swift大对象--动态大对象

    系列导航 一.swift对象存储环境搭建 二.swift添加存储策略 三.swift大对象--动态大对象 四.swift大对象--静态态大对象 五.java操作swift对象存储(官网样例) 六.ja ...

  9. <vue 路由 8、keep-alive的使用>

    一.     知识点 1.什么是keep-alive? keep-alive是Vue.js的一个内置组件. 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们.它自身不会渲染一个 DOM 元素,也 ...

  10. svg组件封装

    svg图标优点 文件体积小,能够被大量的压缩 图片可无限放大而不失真(矢量图的基本特征) 在视网膜显示屏上效果极佳 能够实现互动和滤镜效果 svg图标使用 1.安装相应的npm包: yarn add ...