|
声明:本篇文章仅用于知识分享
实战网址:https://www.xiniudata.com/industry/newest?from=data
请求参数加密
- 访问网址,往下翻翻,可以看到触发了如下的数据包,请求参数进行了加密。
- 全局搜索list_industries_by_sort地址,有四处,都位于同一个文件中。
随便点一个看看,可以看到有payload关键字。
打断点,刷新界面触发断点,一步一步往下调试,可以看到payload传给了j.a.fetch()函数。
- 定位j.a.fetch()函数。
打断点,跳转进来。可以看到明显给payload和sig赋值的语句。
最关键的就是如下这行代码。
- var f = Object(u.c)(Object(u.d)(JSON.stringify(s.payload))), p = Object(u.e)(f);
复制代码 涉及到一个变量和三个函数,一个一个看。
(1)变量s.payload:直接输出看即可。
(2)函数Object(u.c):控制台输出,定位。
(3)函数Object(u.d):控制台输出,定位。
(4)函数Object(u.e):控制台输出,定位。
上面三个函数的代码可以不用看,直接调用js代码就可以了。
4. 目前的js代码如下。- s = {
- "payload": {
- "sort": 1,
- "start": 20,
- "limit": 20
- }
- }
- function e1(e) {
- if (null == e)
- return null;
- for (var t, n, r, o, i, a, u, c = "", l = 0; l < e.length;)
- o = (t = e.charCodeAt(l++)) >> 2,
- i = (3 & t) << 4 | (n = e.charCodeAt(l++)) >> 4,
- a = (15 & n) << 2 | (r = e.charCodeAt(l++)) >> 6,
- u = 63 & r,
- isNaN(n) ? a = u = 64 : isNaN(r) && (u = 64),
- c = c + _keyStr.charAt(o) + _keyStr.charAt(i) + _keyStr.charAt(a) + _keyStr.charAt(u);
- return c
- }
- function e2(e) {
- if (null == (e = _u_e(e)))
- return null;
- for (var t = "", n = 0; n < e.length; n++) {
- var r = _p.charCodeAt(n % _p.length);
- t += String.fromCharCode(e.charCodeAt(n) ^ r)
- }
- return t
- }
- function sig(e) {
- return md5(e + _p).toUpperCase()
- }
- var f = e1(e2(JSON.stringify(s.payload)))
- , p = sig(f);
- console.log(f);
- console.log(p);
复制代码 运行提示_u_e is not defined,去找一下补到代码中。
运行提示_p is not defined,去找_p。
运行提示md5 is not defined,这里需要导入crypto-js库,可以通过npm install crypto-js命令下载。- const CryptoJS = require("crypto-js");
- function sig(e) {
- return CryptoJS.MD5(e + _p).toUpperCase()
- }
复制代码 运行提示CryptoJS.MD5(...).toUpperCase is not a function,是因为在转换为大写之前需要先用toString函数转为字符串。
完整代码如下:- // query_parameter_encrypt.js
- const CryptoJS = require("crypto-js");
- s = {
- "payload": {
- "sort": 1,
- "start": 0,
- "limit": 20
- }
- }
- function _u_e(e) {
- if (null == e)
- return null;
- e = e.replace(/\r\n/g, "\n");
- for (var t = "", n = 0; n < e.length; n++) {
- var r = e.charCodeAt(n);
- r < 128 ? t += String.fromCharCode(r) : r > 127 && r < 2048 ? (t += String.fromCharCode(r >> 6 | 192),
- t += String.fromCharCode(63 & r | 128)) : (t += String.fromCharCode(r >> 12 | 224),
- t += String.fromCharCode(r >> 6 & 63 | 128),
- t += String.fromCharCode(63 & r | 128))
- }
- return t
- }
- var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
- , _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";
- function e1(e) {
- if (null == e)
- return null;
- for (var t, n, r, o, i, a, u, c = "", l = 0; l < e.length;)
- o = (t = e.charCodeAt(l++)) >> 2,
- i = (3 & t) << 4 | (n = e.charCodeAt(l++)) >> 4,
- a = (15 & n) << 2 | (r = e.charCodeAt(l++)) >> 6,
- u = 63 & r,
- isNaN(n) ? a = u = 64 : isNaN(r) && (u = 64),
- c = c + _keyStr.charAt(o) + _keyStr.charAt(i) + _keyStr.charAt(a) + _keyStr.charAt(u);
- return c
- }
- function e2(e) {
- if (null == (e = _u_e(e)))
- return null;
- for (var t = "", n = 0; n < e.length; n++) {
- var r = _p.charCodeAt(n % _p.length);
- t += String.fromCharCode(e.charCodeAt(n) ^ r)
- }
- return t
- }
- function sig(e) {
- return CryptoJS.MD5(e + _p).toString().toUpperCase();
- }
- function generate(s) {
- var payload = e1(e2(JSON.stringify(s.payload))), sign = sig(payload);
- return [payload, sign];
- }
- console.log(generate(s));
复制代码 运行结果如下。
成功,接下来就是编写python代码获取数据了。- import requests
- import json
- import execjs
- url = "https://www.xiniudata.com/api2/service/x_service/person_industry_list/list_industries_by_sort"
- # 这里面最重要的就是content-type参数,否则获取不到数据
- headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/129.0.0.0 Safari/537.36",
- # "cookie": "btoken=82SLKQK1ESJ7A9NZ1C3ZAKREOC0I3AAC",
- # "referer": "https://www.xiniudata.com/industry/newest?from=data",
- # "origin": "https://www.xiniudata.com",
- "content-type": "application/json"}
- # 生成payload和sig
- s = {
- "payload": {
- "sort": 1,
- "start": 0,
- "limit": 20
- }
- }
- file = open("query_parameter_encrypt.js", mode="r")
- exec_code = file.read()
- exec_js = execjs.compile(exec_code)
- payload, sig = exec_js.call("generate", s)
- data = {
- "payload": payload,
- "sig": sig,
- "v": 1
- }
- # 注意需要转换为json数据传输
- resp = requests.post(url, headers=headers, data=json.dumps(data))
- print(json.loads(resp.text))
复制代码 运行结果如下。
返回数据解密
- 一般来说对于返回数据的解密,常规操作是搜索interceptors,但是很可惜不适用于该网站。那就得想其他的办法。
- 我们知道该数据包采用的是JSON格式数据,解密出来后肯定需要进行JSON解析,所以可以搜索JSON.parse关键字。
地方比较多,需要进行筛选。如果JSON.parse是该函数的第一行代码就铁定不是,因为是需要先解密再进行JSON解析的。点击几个,发现了一处跟加密逻辑很像的代码。(其实一般情况下加密逻辑和解密逻辑是写在一起的)
- 打断点,一行一行调试。
可以看到s的值就是返回的数据,说明我们没找错地方。
y的值是明文了,所以解密逻辑肯定跟Object(u.a)和Object(u.b)相关。
找到这两个函数的定义。
- 接下来就跟加密逻辑一样了,把相关的js代码复制出来,把需要用到的变量和参数都补齐。
[code]// response_data_decrypt.jsvar _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" , _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";function d1(e) { var t, n, r, o, i, a, u = "", c = 0; for (e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); c < e.length;) t = _keyStr.indexOf(e.charAt(c++)) > 4, n = (15 & o) > 2, r = (3 & i) 191 && r < 224 ? (o = e.charCodeAt(n + 1), t += String.fromCharCode((31 & r) |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|