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

一、数据接口分析

主页地址:某鸟记录中心

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/91636.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

各种排序算法性能对比

C数据结构与算法 目录 冒泡排序 ​ 插入排序 ​ 选择排序 ​ 上图中最后一列为&#xff1a;nn*(n-1)/2 ​

北京收录2023开学了《乡村振兴战略下传统村落文化旅游设计》中建博后许少辉八一新书

北京收录2023开学了《乡村振兴战略下传统村落文化旅游设计》中建博后许少辉八一新书

Linux进程信号

文章目录 信号入门什么是linux信号&#xff1f;信号处理的常见方式查看系统定义的信号列表 产生信号通过终端按键产生信号调用系统函数向进程发送信号由软件条件产生信号硬件异常产生信号 阻塞信号阻塞信号相关常见概念信号在内核中的表示sigset_t信号操作函数sigprocmasksigpe…

设计师都去哪些网站找样机素材

在当今的设计领域&#xff0c;3D样机素材已经成为一个重要的领域。3D样机素材可以让设计师更好地展示他们的设计理念和概念&#xff0c;也可以帮助客户更好地理解设计。为了帮助设计师更容易地创建3D样机素材&#xff0c;以下是我推荐的10个易于使用的3D样机素材网站。 即时设…

uniapp使用wx.requirePrivacyAuthorize实现微信小程序隐私政策

一、前言 微信小程序官方出了一个公告《关于小程序隐私保护指引设置的公告》。不整的话&#xff0c;后果很多授权无法使用&#xff0c;详见《小程序用户隐私保护指引内容介绍》 。 二、操作流程 1、在 微信小程序后台的【设置】- 【服务内容与声明】 &#xff0c;设置好用户隐…

Linux的基本使用和Web程序部署(JavaEE初阶系列18)

目录 前言&#xff1a; 1.Linux 1.1Linux是什么 1.2Linux发行版 1.3Linux环境搭建 1.3.1环境搭建方式 1.3.2使用云服务器 1.4使用终端软件连接到Linux 1.4.1什么是终端软件 1.4.2使用Xshell登录主机 1.5Linux常用的命令 1.5.1ls 1.5.2cd 1.5.3pwd 1.5.4touch 1.…

CocosCreator3.8研究笔记(二)windows环境 VS Code 编辑器的配置

一、设置文件显示和搜索过滤步骤 为了提高搜索效率以及文件列表中隐藏不需要显示的文件&#xff0c; VS Code 需要设置排除目录用于过滤。 比如 cocoscreator 中&#xff0c;编辑器运行时会自动生成一些目录&#xff1a;build、temp、library&#xff0c; 所以应该在搜索中排除…

《存储IO路径》专题:IO块设备的创建

今天我们来一起学习一下Linux块设备层。它就像是一位大厨&#xff0c;为我们准备各种数据的饕餮盛宴。这个大厨非常厉害&#xff0c;不仅能够读取和写入数据&#xff0c;还能对数据进行各种复杂的操作&#xff0c;比如切割、合并、复制等等。那么&#xff0c;块设备层是如何实现…

SpringBoot初级开发--整体应用的统一性异常管理(7)

在整个系统中&#xff0c;通常会要求有统一性的异常抛出&#xff0c;统一的异常格式&#xff0c;统一的异常界面&#xff0c;而不是把整个堆栈错误信息抛出&#xff0c;这样对整个系统的安全性以及错误定位都非常不好&#xff0c;接下来我们紧接上一章的源码&#xff0c;加上统…

JVM之程序计数器和栈

Java虚拟机&#xff08;JVM&#xff09;是运行Java程序的关键组件&#xff0c;它负责将Java源代码转换为可执行的字节码&#xff0c;并在运行时管理内存、执行程序等。在JVM的内部&#xff0c;有许多重要的组成部分&#xff0c;如下图&#xff1a; 1. JVM程序计数器 程序计数器…

CSRF(跨站请求伪造)和SSRF(服务端请求伪造)漏洞复现:风险与防护方法

这篇文章旨在用于网络安全学习&#xff0c;请勿进行任何非法行为&#xff0c;否则后果自负。 环境准备 一、CSRF&#xff08;跨站请求伪造&#xff09; 示例&#xff1a;假设用户在银行网站A上登录并保持会话活动&#xff0c;同时他也在浏览其他网站。攻击者在一个不可信任…

聊聊Http服务化改造实践

在微服务架构体系中远程RPC调用主要包括Dubbo与Http调用两个大类&#xff0c;由于Dubbo拥有服务注册中心&#xff0c;并且起服务的命名非常规范&#xff0c;使用包名.类名.方法名进行描述。 而http调用通常都是使用httpclient等相关类库&#xff0c;这些在使用上并没有问题&am…