爬虫逆向实战(二十八)--某税网第一步登录
一、数据接口分析
主页地址:某税网
1、抓包
通过抓包可以发现登录接口是factorAccountLogin

2、判断是否有加密参数
- 请求参数是否加密?
通过查看载荷模块可以发现有一个datagram和 一个signature加密参数

- 请求头是否加密?
通过查看“标头”模块可以发现,请求头中有Deviceidentyno、X-App-Clientid、X-Temp-Info三个加密参数

- 响应是否加密?
登录失败是无加密,登录成功时datagram是加密参数 - cookie是否加密?
无
二、加密位置定位
1、加密参数以及部分请求头
(1)看启动器
查看启动器发现里面包含异步,所以无法正确找到加密位置

(2)搜索关键字
通过搜索关键字datagram=可以发现在请求拦截器中会对datagram进行赋值,并且此处还有signature参数以及部分请求头,所以此处大概率是加密位置。

在此处下断点,发现可以断住,并且生成位置就在上方,所以此处就是加密位置

2、请求头Deviceidentyno
搜索关键字
通过搜索关键字Deviceidentyno可以找到设置请求头的位置。

3、响应解密
因为定位到的加密位置是在请求拦截器中,所以解密位置大概率会在响应拦截器中,我们可以在请求拦截器的js文件中搜索interceptors.response就可以找到响应拦截器的位置。并且可以发现,在响应拦截器中确实有解密操作。

三、扣js代码
1、本地存储
我们在扣js代码时,可以发现网站会从本地缓存中取出一些数据,但是其中只有new_key16、clientId和natureuuid是有值的,其他都是空。同时我们可以看到,网站将new_key16取出的值赋值给了a,然后在下方代码中,又判断a是否为空,如果为空就使用Object(A["b"])()方法生成,所以我们就可以直接将这个生成方法扣出,使用这个方法生成。clientId仔细观察可以发现,这个值是固定不变的,可以写死。所以我们只需要关心natureuuid即可。

进入控制台的“应用”标签页中的“本地存储空间”,将本地存储全部清除

然后对localStorage.setItem进行hook
hook代码:
var my_setItem = localStorage.setItem;
localStorage.setItem = function (key, value) {if (key == 'natureuuid'){debugger}return my_setItem.call(localStorage, key, value);
};
运行hook代码,再次点击登录,发现可以断住

接着调试执行,可以发现设置natureuuid的位置,同时可以看出这段代码是在回调中执行的。

再次观察发包可以发现,网站是请求了一个getPublicKey接口,返回了uuid和publicKey,虽然目前来看我们没有用到publicKey,但是肯定是有用到的地方,所以我们也先保存一下。

2、请求流程
当我们将本地存储清空之后,再次登录可以发现,网站是发送了三个请求,先请求了getPublicKey和sendSm4这两个接口之后才请求了登录接口。

所以我们在请求登录之前也需要先请求这两个接口。
观察这两个接口的“载荷”,可以发现这两个接口携带的参数与登录接口是一样的,只不过其中的数据不同,同时,网站在请求前两个接口时,也会经过我们上面定位出来的加密位置,只不过datagram的生成不太一样,前两个接口只是转成了json字符串,只有登录接口才加密。

在观察前两个接口的发包过程时,可以发现第一个接口getPublicKey的datagram就只是一个空字典,然后转成json字符串。但是,网站在给sendSm4接口发包时,是有数据的,而且还有一个我们不知道的参数secret。

我们通过搜索关键字的方式,搜索secret:就可以找到生成位置了,同时这个参数生成的时候还用到了之前通过请求getPublicKey接口获取到的publicKey。

3、坑
在对这三个请求发包时,使用的new_key16以及deviceIdentyNo的值都要使用同一个。
4、加密算法
通过扣js代码可以发现,网站使用了sm2、sm4以及HmacSHA256三种加密算法,解密时使用的是sm4解密,而且这些算法都是标准算法,所以我们可以直接使用标准模块进行加解密。
四、源代码
JavaScript源码:
const {sm2, sm4} = require("sm-crypto");
const CryptoJS = require("crypto-js");function func_i(e, t) {var n, a, r = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""), i = [];if (t = t || r.length,e)for (n = 0; n < e; n++)i[n] = r[0 | Math.random() * t];elsefor (i[8] = i[13] = i[18] = i[23] = "-",i[14] = "4",n = 0; n < 36; n++)i[n] || (a = 0 | 16 * Math.random(),i[n] = r[19 == n ? 3 & a | 8 : a]);return i.join("")
}function object_A_d(e, t) {r = sm4.encrypt(e, t);return r
}function object_A_i(e) {for (var t = "", n = 0; n < e.length; n++)"" === t ? t = e.charCodeAt(n).toString(16) : t += e.charCodeAt(n).toString(16);return t
}function object_A_a(e, t) {var n = CryptoJS.HmacSHA256(e, t).toString();return n
}function object_A_e(e, t) {r = sm4.decrypt(e, t);return r
}function padZero(num) {return num < 10 ? "0" + num : num;
}var clientId = 's44fftt3bc634tcab4teasbaasba7ft4'function get_headers(natureuuid, ded) {if (!ded) {ded = func_i(32)}var t = {headers: {},}t.headers["deviceIdentyNo"] = ded;t.headers["X-APP-CLIENTID"] = clientIdif (natureuuid) {t.headers["X-TEMP-INFO"] = natureuuid}return [t.headers, ded]
}
var v = 'GwdK^R4q'
function get_params(t_data, is_get_key, g) {if (!g) {g = func_i(16, 61)}var currentDate = new Date();var formattedDate = currentDate.getFullYear() +padZero(currentDate.getMonth() + 1) +padZero(currentDate.getDate()) +padZero(currentDate.getHours()) +padZero(currentDate.getMinutes()) +padZero(currentDate.getSeconds());c = {}p = g.substring(0, 8) + vu = ""c["zipCode"] = "0"if (is_get_key) {c["encryptCode"] = "0";c.datagram = JSON.stringify(t_data);} else {f = JSON.stringify(t_data);u = object_A_d(f, object_A_i(p));c.datagram = u;c["encryptCode"] = "2";}c["timestamp"] = formattedDatec["access_token"] = ""c["signtype"] = "HMacSHA256"c["signature"] = object_A_a(c["zipCode"] + c["encryptCode"] + u + c["timestamp"] + c["signtype"], g)return [c, g]
}function func_l(e, t, a) {if (t) {var i = sm2.doEncrypt(e, t, a);return i}return ""
}function get_secret(pubkey, g) {new_key16 = gsecret = func_l(new_key16, pubkey, 1)return secret
}function get_data(g, datagram) {var a = g.substring(0, 8) + v;return object_A_e(datagram, object_A_i(a))
}
Python源码:
"""
Author:陈帅超
Email:912917367@qq.com
Date: 2023/8/29 16:25
"""
import jsonimport execjs
import requestsclass Spider:def __init__(self):self.session = requests.session()self.session.headers = {"Accept": "application/json, text/plain, */*","Accept-Language": "zh-CN,zh;q=0.9","Authorization": "","Cache-Control": "no-cache","Connection": "keep-alive","Content-Type": "application/json","Origin": "https://tpass.jiangsu.chinatax.gov.cn:8443","Pragma": "no-cache","Referer": "https://tpass.jiangsu.chinatax.gov.cn:8443/","Sec-Fetch-Dest": "empty","Sec-Fetch-Mode": "cors","Sec-Fetch-Site": "same-origin","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36","X-LANG-ID": "null","X-NATURE-IP": "","X-SM4-INFO": "0","X-TICKET-ID": "null","hUid": "","sec-ch-ua": "^\\^Chromium^^;v=^\\^116^^, ^\\^Not)A;Brand^^;v=^\\^24^^, ^\\^Google","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "^\\^Windows^^"}with open('reverse.js', 'r', encoding='utf-8') as f:self.js_obj = execjs.compile(f.read())self.uuid = ''self.publicKey = ''self.g = ''self.ded = ''def get_public_key(self):url = "https://tpass.jiangsu.chinatax.gov.cn:8443/sys-api/v1.0/auth/oauth2/getPublicKey"headers2 = self.js_obj.call('get_headers', self.uuid)self.ded = headers2[0]self.session.headers = headers2[0] | self.session.headersdata = self.js_obj.call('get_params', {}, True)self.g = data[1]response = self.session.post(url, json=data[0])datagram = json.loads(response.json()['datagram'])self.uuid = datagram['uuid']self.publicKey = datagram['publicKey']print('uuid:', self.uuid)print('publicKey:', self.publicKey)def send_sm4(self):url = "https://tpass.jiangsu.chinatax.gov.cn:8443/sys-api/v1.0/auth/white/sendSm4"headers2 = self.js_obj.call('get_headers', self.uuid, self.ded)self.session.headers = headers2[0] | self.session.headerssecret = self.js_obj.call('get_secret', self.publicKey, self.g)data = self.js_obj.call('get_params', {'uuid': self.uuid, 'secret': secret}, True, self.g)response = self.session.post(url, json=data[0])print(response.text)print(response)def login(self):t_data = {"client_id": 's44fftt3bc634tcab4teasbaasba7ft4',"account": '登录用户名',"password": '登录密码',"redirect_uri": "https://etax.jiangsu.chinatax.gov.cn/sso/kxLogin/authorize","creditCode": '税号'}url = "https://tpass.jiangsu.chinatax.gov.cn:8443/sys-api/v1.0/auth/enterprise/quick/factorAccountLogin"headers2 = self.js_obj.call('get_headers', self.uuid, self.ded)self.session.headers = headers2[0] | self.session.headersdata = self.js_obj.call('get_params', t_data, False, self.g)response = self.session.post(url, json=data[0])response_data = self.js_obj.call('get_data', self.g, response.json()['datagram'])print(response_data)if __name__ == '__main__':s = Spider()s.get_public_key()s.send_sm4()s.login()
相关文章:
爬虫逆向实战(二十八)--某税网第一步登录
一、数据接口分析 主页地址:某税网 1、抓包 通过抓包可以发现登录接口是factorAccountLogin 2、判断是否有加密参数 请求参数是否加密? 通过查看载荷模块可以发现有一个datagram 和 一个signature加密参数 请求头是否加密? 通过查看“标…...
【Dots之003】SystemAPI.Query相关基础笔记
1、SystemAPI.Query 注:SystemAPI.Query只能作为foreach中in的的子句 SystemAPI.Query<RefRO<LocalTransform>>().WithAll<Obstacle>()解析:对于每个具有LocalTransform和Obstacle的Entity;都会将LocalTransform的只读引…...
vue v-for 例子
vue v-for 例子 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&…...
206.Flink(一):flink概述,flink集群搭建,flink中执行任务,单节点、yarn运行模式,三种部署模式的具体实现
一、Flink概述 1.基本描述 Flink官网地址:Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。 2.有界流和无界流 无界流(流): 有定义流的开始,没有定义结束。会无休止…...
科技探究之旅--亲子研学活动
2023年8月26日,广州市从化区齐家社会工作服务中心(以下简称“齐家”)的“星乐园-乡村儿童公益辅导服务项目”组织了新开村及西湖村助学点24对亲子到广州市白云区文搏3D打印基地进行“科技探究之旅--亲子研学”活动,旨在发现、点燃…...
华为云Stack的学习(三)
四、华为云Stack公共组件 1.华为云Stack公共负载均衡方案介绍 1.1 LVS原理 LVS是四层负载均衡,建立在OSI模型的传输层之上,所以效率非常高。 LVS有两种转发模式: NAT模式的转发主要通过修改IP地址(位于OSI模型的第三层网络层&…...
大数据平台三大优势详解-行云管家
大数据平台三大优势详解 1、轻松进行数据共享 企业在管理以及快速发展过程中,有着越来越多的数据需要进行管理,如果单独管理则工作量巨大,且难免出现问题,同时共享难。因此需要大数据平台对数据进行统一管理,以及轻松…...
智慧景区方案:AI与视频融合技术如何助力景区监管智能化升级?
随着经济的发展,人们对生活的需求也不再局限于温饱层面,越来越多的人们开始追求文化、艺术的高层次需求,旅游也逐渐成为人们日常放松的一种方式。由于我国人口多、易扎堆等特点,景区的运营监管方式也亟需改革。TSINGSEE青犀智能分…...
HTML基础--Form表单--内联元素
目录 Form表单 表单元素 创建表单 () 文本输入 () 密码输入 单选按钮 () 和 复选框 () 下拉列表 () 和 选项 ()提交按钮 () 重置按钮 () 块元素与行内元素(内联元素) Form表单 HTML中的表单(<form>)是一个重要的元…...
【月度刷题计划同款】常规状压 DP 启发式搜索
题目描述 这是 LeetCode 上的 「1879. 两个数组最小的异或值之和」 ,难度为 「困难」。 Tag : 「状压 DP」、「动态规划」、「启发式搜索」 给你两个整数数组 nums1 和 nums2,它们长度都为 n。 两个数组的 异或值之和 为 (nums1[0] XOR nums2[0]) (nums…...
C#: Json序列化和反序列化,集合为什么多出来一些元素?
如下面的例子,很容易看出问题: 如果类本身的无参构造函数, 就添加了一些元素,序列化,再反序列化,会导致元素增加。 如果要避免,必须添加: new JsonSerializerSettings() { Object…...
Docker教程-centos快速安装和配置Docker
# step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2# Step 2: 添加软件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# Step 3: 更新并安装 Docker-CE sudo …...
three.js(四):react + three.js
绘制多个立方体 1.搭建reactts 项目 npx create-react-app basics-demo --template typescriptreactts 的用法可参考此链接: https://react-typescript-cheatsheet.netlify.app/docs/basic/setup 2.安装three依赖 npm install three types/three --save3.安装路…...
IDEA全局统一设置Maven
原来每次打开新建的项目都需要经过 File-> Settings 重新配置maven,这样很不爽 然而经过 File-> New Projects Setup -> Settings for New Projects 后,再如上图配置后就全局设置好了...
CSS中的margin与padding
目录 一、margin 1.概念及作用 2.基本语法 3.margin的用法 二、padding 1.介绍 2.基本语法及要求 3. 用法 4.内边距和元素宽度 讲这些之前,先看一张图,便于理解 一、margin 1.概念及作用 CSS margin 属性用于在任何定义的边框之外,…...
匿名内部类、Lambda、方法引用 的总结
在今天的项目中看到这样一行代码 Integer syncCount consumer.consumerInfo( Collections.singletonList(KafkaTopicConst.Event_BMS_SYSLOG_ROLE),consumer::handle); 直接傻眼,无法理解consumer::handle这种用法,因此总结如下 consumer::handle这种写…...
本地docker registry 搭建
#!/bin/bash DOCKER_REGISTRY_ROOT/data0/docker/registry DOMAINexample.host.com #生成证书:https://goharbor.io/docs/2.6.0/install-config/configure-https/ mkdir $DOCKER_REGISTRY_ROOT/certs cd $DOCKER_REGISTRY_ROOT/certs openssl genrsa -out ca.key 40…...
阿里云将关停代销业务
我是卢松松,点点上面的头像,欢迎关注我哦! 阿里云自从逐渐分拆独立之后,做了很多调整。最近它又做了一个大动作:据DoNews消息,阿里云将会在今年9月30日之前,全面关停代销业务。 这件事实际上…...
【ES6】JavaScript的Proxy:理解并实现高级代理功能
在JavaScript中,Proxy是一种能够拦截对对象的读取、设置等操作的机制。它们提供了一种方式,可以在执行基本操作之前或之后,对这些操作进行自定义处理。这种功能在许多高级编程场景中非常有用,比如实现数据验证、日志记录、权限控制…...
[Pandas] 求百分比并添加百分(%)号
导入数据 import pandas as pddf pd.DataFrame(data{orders: [2130,5102,3256,1297,1918,786],repeat_orders: [73,158,89,30,49,18]}) df df[repetition_rate] df[repeat_orders] / df[orders] df df[repetition_rate] df[repetition_rate].apply(lambda x: format(x, .2…...
HC7251晨芯阳科技内置MOS开关降压型LED恒流驱动器
HC7251是一款内置60V功率MOS 高效率、高精度的开关降压型大功率LED 恒流驱动芯片。HC7251采用固定关断时间的峰值电流控制方式,关断时间可通过外部电容进行调节,工作频率可根据用户要求而改变。HC7251通过调节外置的电流采样电阻,能控制高亮度…...
【会议征稿通知 | E3S出版 | EI 、Scopus稳定检索】第十二届能源材料与环境工程国际学术会议(ICEMEE 2026)
第十二届能源材料与环境工程国际学术会议(ICEMEE 2026) 2026 12th International Conference on Energy Materials and Environment Engineering 2026年6月12-14日 | 线上会议 大会官网:www.icemee.net 截稿时间:见官网&#x…...
突破Windows资源管理器性能瓶颈:智能缩略图预加载解决方案
突破Windows资源管理器性能瓶颈:智能缩略图预加载解决方案 【免费下载链接】WinThumbsPreloader-V2 WinThumbsPreloader is a powerful open source tool for quickly preloading thumbnails in Windows Explorer. 项目地址: https://gitcode.com/gh_mirrors/wi/W…...
水文水资源、水生态与水环境领域必修技能暨 ArcGIS Pro全流程实践技术学习及AI融合应用
ArcGIS Pro 是一款集数据采集、处理、分析和可视化于一体的强大 GIS 工具,广泛应用于水文、水资源、水生态和水环境等领域。其全面的功能使得研究人员能够高效地处理各种水文和环境数据,从而为科学研究和决策支持提供强有力的技术保障。在水文分析方面&a…...
告别Blob分析:Halcon差异化模型在复杂印刷品检测中的降本增效实践
工业视觉新范式:Halcon差异化模型在精密印刷检测中的实战突破 印刷品质量检测一直是工业视觉领域的硬骨头——那些微米级的墨点缺失、毫厘间的字符偏移,以及生产线上的光影变幻,都在挑战传统算法的极限。当Blob分析遇上多印漏印、位置飘移、…...
保姆级教程:在Ubuntu上把YOLOv5的ONNX模型转成RV1126能用的RKNN模型(附完整代码)
从ONNX到RKNN:YOLOv5模型在RV1126平台的完整转换指南 当清晨的第一缕阳光透过窗帘缝隙洒在键盘上,我正盯着终端里那个顽固的ONNX模型发愁——它已经在我的Ubuntu工作站上运行了整整一夜,却依然没能成功转换为RV1126开发板可用的RKNN格式。这…...
ATxmega时钟与GPIO配置详解:从原理到实战调试
1. 项目概述:从零认识ATxmage的时钟与GPIO最近在捣鼓一块ATxmage的开发板,很多刚入门的朋友拿到手,面对密密麻麻的引脚和一堆陌生的寄存器,往往不知道从哪里下手。其实,玩转任何一款微控制器,最核心、最基础…...
MPh 开源项目教程
MPh 开源项目教程 【免费下载链接】MPh Pythonic scripting interface for Comsol Multiphysics 项目地址: https://gitcode.com/gh_mirrors/mp/MPh 项目介绍 MPh 是一个基于 Python 的强大开源项目,旨在简化数学物理问题的求解过程。它结合了符号计算的灵活…...
ROS Topic通讯实战:拆解`/turtle1/cmd_vel`,理解速度指令如何驱动小乌龟运动
ROS Topic通讯实战:拆解/turtle1/cmd_vel,理解速度指令如何驱动小乌龟运动 在机器人操作系统(ROS)的学习过程中,控制小乌龟(turtlesim)画圆是一个经典案例。这个看似简单的任务背后,…...
DepHell与Docker集成:容器化Python应用开发的终极指南
DepHell与Docker集成:容器化Python应用开发的终极指南 【免费下载链接】dephell :package: :fire: Python project management. Manage packages: convert between formats, lock, install, resolve, isolate, test, build graph, show outdated, audit. Manage ven…...
