当前位置: 首页 > news >正文

爬虫逆向实战(二十四)--某鸟记录中心

一、数据接口分析

主页地址:某鸟记录中心

1、抓包

通过抓包可以发现数据接口是front/record/search/page
在这里插入图片描述

2、判断是否有加密参数

  1. 请求参数是否加密?
    通过查看“载荷”模块可以发现,请求参数是加密的
    在这里插入图片描述
  2. 请求头是否加密?
    通过查看“请求标头”可以发现RequestidSign是加密参数,并且有一个Timestamp时间戳
    在这里插入图片描述
  3. 响应是否加密?
    通过查看“响应”模块可以发现,响应中的数据是加密数据
    在这里插入图片描述
  4. cookie是否加密?

二、加密位置定位

1、加密参数以及请求头加密

(1)看启动器

查看启动器发现里面有一个pullData的调用堆栈,点进去查看
在这里插入图片描述
点进去后,可以看出,此处是发送ajax请求的位置,在此处下断点,再次翻页获取数据,发现可以断住,但是此处是明文数据,所以加密位置不在这里。
在这里插入图片描述

(2)搜索关键字

因为“载荷”是一整个密文,没有关键字,所以无法搜索

(3)hook

因为“载荷”是一整个密文,所以网站大概率会使用JSON.stringify将数据转换为json字符串再进行加密,所以我们可以hookJSON.stringify,hook代码:

var my_stringify = JSON.stringify;
JSON.stringify = function (params) {debuggerconsole.log("json_stringify params:",params);return my_stringify(params);
};

运行hook代码,再次获取数据,发现可以断住
在这里插入图片描述
继续调试执行,可以发现,网站是使用ajaxSetup设置了ajax请求的全局配置,请求头和加密参数都是在此处进行赋值的。
在这里插入图片描述

2、响应数据

(1)hook

因为响应加密数据一般都是json数据加密,所以解密后会使用JSON.parse进行解密,所以我们可以对JSON.parse进行hook
hook代码段:

var my_parse = JSON.parse;
JSON.parse = function (params) {debuggerconsole.log("json_parse params:",params);return my_parse(params);
};

运行hook代码,再次获取数据,发现可以断住明文
在这里插入图片描述
接着调试执行,就可以找到解密位置
在这里插入图片描述

三、扣js代码

1、加密参数及请求头

将定位到的加密位置的代码扣出,可以发现网站的数据加密是使用的JSEncrypt模块进行的RAS加密,所以我们可以直接使用标准模块进行加密,但是网站使用的encrypt.encryptUnicodeLong方法,node.js中是没有的,所以我们还需要将这个方法扣出来。下方请求头加密使用的md5,我们同样可以使用标准模块进行加密。
在这里插入图片描述

2、响应数据

将定位到的解密位置的代码扣出,进入到网站的解密方法BIRDREPORT_APIJS.decode中,可以发现,网站是使用的AES解密的,所以我们可以使用标准的AES模块进行解密。
在这里插入图片描述
JavaScript源码:

const JSEncrypt = require('jsencrypt');var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64pad = "=";function hex2b64(h) {var i;var c;var ret = "";for (i = 0; i + 3 <= h.length; i += 3) {c = parseInt(h.substring(i, i + 3), 16);ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);}if (i + 1 == h.length) {c = parseInt(h.substring(i, i + 1), 16);ret += b64map.charAt(c << 2);} else if (i + 2 == h.length) {c = parseInt(h.substring(i, i + 2), 16);ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);}while ((ret.length & 3) > 0) {ret += b64pad;}return ret;
}JSEncrypt.prototype.encryptUnicodeLong = function (string) {var k = this.getKey();//根据key所能编码的最大长度来定分段长度。key size - 11:11字节随机padding使每次加密结果都不同。var maxLength = ((k.n.bitLength() + 7) >> 3) - 11;var subStr = "", encryptedString = "";var subStart = 0, subEnd = 0;var bitLen = 0, tmpPoint = 0;for (var i = 0, len = string.length; i < len; i++) {//js 是使用 Unicode 编码的,每个字符所占用的字节数不同var charCode = string.charCodeAt(i);if (charCode <= 0x007f) {bitLen += 1;} else if (charCode <= 0x07ff) {bitLen += 2;} else if (charCode <= 0xffff) {bitLen += 3;} else {bitLen += 4;}//字节数到达上限,获取子字符串加密并追加到总字符串后。更新下一个字符串起始位置及字节计算。if (bitLen > maxLength) {subStr = string.substring(subStart, subEnd)encryptedString += k.encrypt(subStr);subStart = subEnd;bitLen = bitLen - tmpPoint;} else {subEnd = i;tmpPoint = bitLen;}}subStr = string.substring(subStart, len)encryptedString += k.encrypt(subStr);return hex2b64(encryptedString);
};const CryptoJS = require('crypto-js')function getUuid() {var s = [];var a = "0123456789abcdef";for (var i = 0; i < 32; i++) {s[i] = a.substr(Math.floor(Math.random() * 0x10), 1)}s[14] = "4";s[19] = a.substr((s[19] & 0x3) | 0x8, 1);s[8] = s[13] = s[18] = s[23];var b = s.join("");return b
}function sort_ASCII(a) {var b = new Array();var c = 0;for (var i in a) {b[c] = i;c++}var d = b.sort();var e = {};for (var i in d) {e[d[i]] = a[d[i]]}return e
}function url2json(a) {var b = /^[^\?]+\?([\w\W]+)$/, reg_para = /([^&=]+)=([\w\W]*?)(&|$|#)/g, arr_url = b.exec(a), ret = {};if (arr_url && arr_url[1]) {var c = arr_url[1], result;while ((result = reg_para.exec(c)) != null) {ret[result[1]] = result[2]}}return ret
}function dataTojson(a) {var b = [];var c = {};b = a.split('&');for (var i = 0; i < b.length; i++) {if (b[i].indexOf('=') != -1) {var d = b[i].split('=');if (d.length == 2) {c[d[0]] = d[1]} else {c[d[0]] = ""}} else {c[b[i]] = ''}}return c
}const serialize = function (a) {var b = [];for (var p in a)if (a.hasOwnProperty(p) && a[p]) {b.push(encodeURIComponent(p) + '=' + encodeURIComponent(a[p]))}return b.join('&')
};
var paramPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvxXa98E1uWXnBzXkS2yHUfnBM6n3PCwLdfIox03T91joBvjtoDqiQ5x3tTOfpHs3LtiqMMEafls6b0YWtgB1dse1W5m+FpeusVkCOkQxB4SZDH6tuerIknnmB/Hsq5wgEkIvO5Pff9biig6AyoAkdWpSek/1/B7zYIepYY0lxKQIDAQAB";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(paramPublicKey);function get_params() {var b_data = 'page=1&limit=20&taxonid=&startTime=&endTime=&province=&city=&district=&pointname=%E6%B2%B3%E5%8D%97&username=&serial_id=&ctime=&taxonname=&state=&mode=0&outside_type=0'var c = Date.parse(new Date());var d = getUuid();var e = JSON.stringify(sort_ASCII(dataTojson(b_data || '{}')));b_data = encrypt.encryptUnicodeLong(e);var f = CryptoJS.MD5(e + d + c).toString();return [{timestamp: c.toString(),requestId: d.toString(),sign: f.toString()}, b_data]
}var key = '3583ec0257e2f4c8195eec7410ff1619';
var iv = 'd93c0d5ec6352f20'
apijs_decode = function(a) {var b = CryptoJS.enc.Utf8.parse(key);var c = CryptoJS.enc.Utf8.parse(iv);var d = CryptoJS.AES.decrypt(a, b, {iv: c,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});return d.toString(CryptoJS.enc.Utf8)}function get_data(r_data) {var decode_str = apijs_decode(r_data);return JSON.parse(decode_str)
}

相关文章:

爬虫逆向实战(二十四)--某鸟记录中心

一、数据接口分析 主页地址&#xff1a;某鸟记录中心 1、抓包 通过抓包可以发现数据接口是front/record/search/page 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现&#xff0c;请求参数是加密的 请求头是否加密&#xff1f; 通过查…...

【操作系统】中断和异常

中断的作用 CPU上会执行两种程序&#xff1a;内核程序和应用程序 在适合的情况下&#xff0c;操作系统内核会把CPU的使用权主动让给应用程序&#xff0c;“中断”是让操作系统内核夺回CPU使用权的唯一途径&#xff08;用户态转内核态&#xff09;。 中断技术保证了并发。 中…...

锁策略、原子编程CAS 和 synchronized 优化过程

前言 锁冲突&#xff1a;两个线程获取一把锁&#xff0c;一个线程阻塞等待&#xff0c;一个线程加锁成功。 目录 前言 一、锁策略 &#xff08;一&#xff09;乐观锁和悲观锁 &#xff08;二&#xff09;重量级锁和轻量级锁 &#xff08;三&#xff09;自旋锁和挂起等待…...

【WINAPI】文件读写操作问题

问题描述 在利用WINAPI中的WriteFile和ReadFile函数进行文件读写操作时&#xff0c;出现无法正常读写文件报错。 分析问题 查阅WINAPI源码&#xff0c;查看参数列表各个参数的数据类型。 发现其中第二个参数&#xff0c;也就是需要写进文件的真实数据&#xff0c;其数据类型…...

【LeetCode-中等题】148. 排序链表

文章目录 题目方法一&#xff1a;集合排序&#xff08;核心是内部的排序&#xff09;方法二&#xff1a; 优先队列&#xff08;核心也是内部的排序&#xff09;方法三&#xff1a;归并排序&#xff08;带递归&#xff09; 从上往下方法四&#xff1a;归并排序&#xff08;省去递…...

Ceph EC pg backfill run

pg的backfill请求也是发送到osd的work queue中与业务IO一起竞争。 PGRecovery::run backfill 57 void PGRecovery::run( 58 OSD *osd, 59 OSDShard *sdata, 60 PGRef& pg, 61 ThreadPool::TPHandle &handle) 62 { 63 osd->do_recovery(pg.get(), epoch_queued…...

腾讯云服务器地域怎么选?广州上海北京?

腾讯云服务器地域有什么区别&#xff1f;怎么选择比较好&#xff1f;地域选择就近原则&#xff0c;距离地域越近网络延迟越低&#xff0c;速度越快。关于地域的选择还有很多因素&#xff0c;地域节点选择还要考虑到网络延迟速度方面、内网连接、是否需要备案、不同地域价格因素…...

Apple Configurator iphone ipad 设备管控 描述文件使用方法

一、准备 App Store 下载安装 Apple Configurator 二、Apple Configurator 注册组织&#xff0c; -----------这个组织可以是个人&#xff0c;或者其它组织导出-------再导入进来&#xff1a; 三、描述文件配置&#xff1a;“” 根据管控需求进行配置 “” 四、使用 Ap…...

Linux 管道(pipe)用法

在 Linux 中&#xff0c;管道&#xff08;pipe&#xff09;是一种特殊的机制&#xff0c;用于连接一个进程的标准输出到另一个进程的标准输入。通过使用管道&#xff0c;可以将一个命令的输出直接传递给另一个命令进行处理&#xff0c;实现了进程之间的通信和数据传输。 管道的…...

元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型

今天在写ts文件的过程中&#xff0c;我遍历了一个对象&#xff0c;然后取值的时候发现爆红,如下图&#x1f447; 经过我一通排查&#xff08;原因我对ts也不是很熟练&#xff09;&#xff0c;了解到大致意思是说key的值类型不是string类型&#xff0c;在javascript中是默认给你…...

34、springboot切换内嵌Web服务器(Tomcat服务器)与 生成SSL证书来把项目访路径从 HTTP 配置成 HTTPS

知识点1&#xff1a;springboot切换内嵌Web服务器&#xff08;Tomcat服务器&#xff09; 知识点2&#xff1a;生成SSL证书来把项目访路径从 HTTP 配置成 HTTPS ★ Spring Boot默认的Web服务器&#xff08;Tomcat&#xff09; ▲ 基于Servlet的应用&#xff08;使用Spring MV…...

3种CSS实现背景图片全屏铺满自适应的方式

01 margin:0px; background: url(images/bg.png) no-repeat; background-size:100% 100%; background-attachment:fixed; url(images/beijing.png)——图片路径的位置&#xff1b; no-repeat—— 图片不重复&#xff1b; center 0px——center是距离页面左边的定位&#xf…...

M1 Pro 利用docker 搭建pytho2的开发环境,以vscode连接开发为例

使用 M1 Pro &#xff08;不支持python2的安装&#xff09;开发&#xff0c;需要使用 Python 2.7 的环境&#xff0c;在使用 pyenv 安装 Python 2 时遇到了各种奇怪的问题。最终&#xff0c;我决定使用 Docker 搭建开发环境&#xff0c;并使用 VS Code 连接到本地容器。以下是详…...

MySQL概述,架构原理

一.MySQL简介 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典的MySQL AB公司开发&#xff0c;后被oracle公司收购&#xff0c;MySQL是当下最流行的关系型数据库管理系统之一&#xff0c;在WEB应用方面&#xff0c;MySQL是最好的RDBMS&#xff08;Relational Database Man…...

Three.js实现模型,模型材质可拖拽效果 DragControls

Three.js提供了一个拖拽的API DragControls 用于实现模型材质拖拽效果 DragControls&#xff1a;是一个用于在Three.js中实现拖拽控制的辅助类。它简化了在Three.js中实现拖拽物体的过程。 DragControls的构造函数接受三个参数&#xff1a; objects&#xff1a;一个包含需要…...

机器学习笔记之优化算法(二十)牛顿法与正则化

机器学习笔记之优化算法——再回首:牛顿法与正则化 引言回顾&#xff1a;经典牛顿法及其弊端牛顿法&#xff1a;算法步骤迭代过程中可能出现的问题正则化 Hessian Matrix \text{Hessian Matrix} Hessian Matrix与相应问题 引言 本节我们介绍经典牛顿法在训练神经网络过程中的迭…...

【Go 基础篇】深入探索:Go语言中的切片遍历与注意事项

嗨&#xff0c;Go语言学习者&#xff01;在我们的编程旅程中&#xff0c;切片&#xff08;Slice&#xff09;是一个极其重要的工具。它可以帮助我们处理各种类型的数据&#xff0c;从而让我们的代码更加灵活和高效。本文将围绕Go语言中切片的遍历方法以及在遍历时需要注意的事项…...

一些经典的SQL语句

查sql中as的用法搜索到的一些经典的sql语句 convert(2008-11-20 18:03:50) In:等值连接&#xff0c;用来查找多表相同字段的记录 Not In:非等值连接&#xff0c;用来查找不存在的记录 Inner join:内连接&#xff0c;主要用来查找都符合条件的记录 Left join:左连接&#xff…...

〔018〕Stable Diffusion 之 批量替换人脸 篇

✨ 目录 &#x1f388; 下载插件&#x1f388; 插件基础使用&#x1f388; 基础使用效果&#x1f388; 批量处理图片&#x1f388; 多人脸部替换 &#x1f388; 下载插件 如果重绘图片的时候&#xff0c;你只想更换人物面部的话&#xff0c;可以参考这篇文章扩展地址&#xff…...

Unity字符串性能问题

前言 分享一些通过书籍和网络学到的知识 每次动态创建一个string&#xff0c;C#都会在堆内存分配一个内存用来分配字符串&#xff0c;因为C#没有对字符串的缓存机制&#xff0c;会导致每次连接、切割、组合的时候都会申请新的内存&#xff0c;并且抛弃原来的内存&#xff0c;等…...

深入浅出SSD:固态存储核心技术、原理与实战(文末赠书)

名字&#xff1a;阿玥的小东东 学习&#xff1a;Python、C/C 主页链接&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 内容简介 作者简介 使用Python做一个计算器 本期赠书 近年来国家大力支持半导体行业&#xff0…...

关于layui+php,三级联动-编辑回显的问题。

注 忍不住吐槽一波。都什么年代了。现在都前后端分离&#xff0c;但是公司老项目非得用tplayui。。 代码如下 layui.use([form], function () {var form layui.form;//php代码渲染页面的时候&#xff0c;将一级分类id和二级分类id带过来&#xff0c;存到页面input框中&#x…...

lua的函数

1.一个示例实现列表的元素的求和 [root]# more funcAdd.lua function add(a)local sum 0for i 1,#a dosum sum a[i]endreturn sum enda {1,2,3,4,5,6}local sum add(a)print(sum)...

pytorch/tensorflow 直接给张量中的某个位置的值赋值,操作不可导。

问题&#xff1a;给一个tensor A中[i,j]&#xff0c;赋值p。直接操作A[i,j]p可能会导致值覆盖&#xff0c;操作不可导。 解决方案&#xff1a;通过引入一个额外的mask实现。 mask[i,j] 0 mask tf.convert_to_tensor(mask, dtypetf.float32) A (A * mask) (p * (1-mask))p…...

如何使用CSS实现一个平滑滚动到页面顶部的效果(回到顶部按钮)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 平滑滚动到页面顶部的效果&#xff08;回到顶部按钮&#xff09;⭐ 创建HTML结构⭐ 编写CSS样式⭐ 编写JavaScript函数⭐ 添加滚动事件监听器⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右…...

【RuoYi移动端】uniApp导入和引用uView2.0插件

一、打开uiew官网 安装 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架uView UI&#xff0c;是 uni-app 生态最优秀的 UI 框架&#xff0c;全面的组件和便捷的工具会让您信手拈来&#xff0c;如鱼得水https://uviewui.com/components/install.html 也可直…...

etcd 备份还原

etcd 备份还原 查看 etcdctl 是否已经安装 # quick check if etcdctl is available or not ETCDCTL_API3 etcdctl --help | head安装 etcdctl # 获取 etcd 版本信息 kubectl exec -it etcd-master -n kube-system -- /bin/sh -c ETCDCTL_API3 /usr/local/bin/etcd --version…...

LInux之chrony服务器

目录 场景 重要性 LInux的两个时钟 硬件时钟 系统时钟 NTP协议 Chrony介绍 定义 组成 --- chronyd和chronyc 安装与配置 安装 Chrony配置文件分析 同步时间服务器 chronyc命令 chronyc sources输出分析 其它命令 查看时间服务器的状态 查看时间服务器是否在线 …...

《Flink学习笔记》——第七章 处理函数

为了让代码有更强大的表现力和易用性&#xff0c;Flink 本身提供了多层 API 在更底层&#xff0c;我们可以不定义任何具体的算子&#xff08;比如 map&#xff0c;filter&#xff0c;或者 window&#xff09;&#xff0c;而只是提炼出一个统一的“处理”&#xff08;process&a…...

Nacos基础(3)——nacos+nginx 集群的配置和启动 端口开放 nginx反向代理nacos集群

目录 引出nacos集群nginx反向代理nacos集群停止单例nacos准备8848和8858修改cluster.conf配置【配置】修改启动配置文件【配置】开放8858的端口分别以集群方式启动【启动】前端访问查看生产者测试8858nacos nginx反向代理配置代理tcp代理http启动nginx反向代理容器生产者访问测…...