js逆向实战之烯牛数据请求参数加密和返回数据解密

news/2024/9/22 15:15:41

声明:本篇文章仅用于知识分享

实战网址:https://www.xiniudata.com/industry/newest?from=data

请求参数加密

  1. 访问网址,往下翻翻,可以看到触发了如下的数据包,请求参数进行了加密。
    image
  2. 全局搜索list_industries_by_sort地址,有四处,都位于同一个文件中。
    image
    随便点一个看看,可以看到有payload关键字。
    image
    打断点,刷新界面触发断点,一步一步往下调试,可以看到payload传给了j.a.fetch()函数。
    image
  3. 定位j.a.fetch()函数。
    image
    打断点,跳转进来。可以看到明显给payloadsig赋值的语句。
    image
    最关键的就是如下这行代码。
var f = Object(u.c)(Object(u.d)(JSON.stringify(s.payload))), p = Object(u.e)(f);

涉及到一个变量和三个函数,一个一个看。
(1)变量s.payload:直接输出看即可。
image
(2)函数Object(u.c):控制台输出,定位。
image
(3)函数Object(u.d):控制台输出,定位。
image
(4)函数Object(u.e):控制台输出,定位。
image
上面三个函数的代码可以不用看,直接调用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,去找一下补到代码中。
image
运行提示_p is not defined,去找_p
image
运行提示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.jsconst 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));

运行结果如下。
image
成功,接下来就是编写python代码获取数据了。

import requests
import json
import execjsurl = "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))

运行结果如下。
image

返回数据解密

  1. 一般来说对于返回数据的解密,常规操作是搜索interceptors,但是很可惜不适用于该网站。那就得想其他的办法。
    image
  2. 我们知道该数据包采用的是JSON格式数据,解密出来后肯定需要进行JSON解析,所以可以搜索JSON.parse关键字。
    image
    地方比较多,需要进行筛选。如果JSON.parse是该函数的第一行代码就铁定不是,因为是需要先解密再进行JSON解析的。点击几个,发现了一处跟加密逻辑很像的代码。(其实一般情况下加密逻辑和解密逻辑是写在一起的)
    image
  3. 打断点,一行一行调试。
    image
    可以看到s的值就是返回的数据,说明我们没找错地方。
    image
    y的值是明文了,所以解密逻辑肯定跟Object(u.a)Object(u.b)相关。
    找到这两个函数的定义。
    image
    image
  4. 接下来就跟加密逻辑一样了,把相关的js代码复制出来,把需要用到的变量和参数都补齐。
// 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++)) << 2 | (o = _keyStr.indexOf(e.charAt(c++))) >> 4,n = (15 & o) << 4 | (i = _keyStr.indexOf(e.charAt(c++))) >> 2,r = (3 & i) << 6 | (a = _keyStr.indexOf(e.charAt(c++))),u += String.fromCharCode(t),64 != i && (u += String.fromCharCode(n)),64 != a && (u += String.fromCharCode(r));return u
}function _u_d(e) {for (var t = "", n = 0, r = 0, o = 0, i = 0; n < e.length;)(r = e.charCodeAt(n)) < 128 ? (t += String.fromCharCode(r),n++) : r > 191 && r < 224 ? (o = e.charCodeAt(n + 1),t += String.fromCharCode((31 & r) << 6 | 63 & o),n += 2) : (o = e.charCodeAt(n + 1),i = e.charCodeAt(n + 2),t += String.fromCharCode((15 & r) << 12 | (63 & o) << 6 | 63 & i),n += 3);return t
}function d2(e) {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 = _u_d(t)
}function decrypt(e){return d2(d1(e));
}e = '返回的加密数据';
//  console.log(decrypt(e));

运行结果如下。
image
成功。
5. 写python代码,将加密逻辑和解密逻辑进行融合。

from functools import partial
import subprocesssubprocess.Popen = partial(subprocess.Popen, encoding="utf-8")import requests
import json
import execjsurl = "https://www.xiniudata.com/api2/service/x_service/person_industry_list/list_industries_by_sort"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}}file1 = open("query_parameter_encrypt.js", mode="r")
exec_code1 = file1.read()
exec_js1 = execjs.compile(exec_code1)
payload, sig = exec_js1.call("generate", s)
data = {"payload": payload, "sig": sig, "v": 1}resp = requests.post(url, headers=headers, data=json.dumps(data))
# 得到返回的响应数据
response_data = json.loads(resp.text)['d']
# print(response_data)# 调用解密逻辑
file2 = open("response_data_decrypt.js", mode="r")
exec_code2 = file2.read()
exec_js2 = execjs.compile(exec_code2)
ming_str = exec_js2.call('decrypt', response_data)
print(ming_str)

运行结果如下。
image
跟页面上显示的对应。
image
大功告成。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

python中列表切片

001、>>> list1 ## 测试列表 [chicken, duck, goose, iron, xxx] >>> list1[:3] ## 前三个 [chicken, duck, goose] >>> list1[-3:] ## 后三个 [goose, iron, xxx] >>> list1[2:] ##…

帝国cms怎么搭建网站教程-帝国CMS搭建安装教程详细步骤

搭建一个基于帝国CMS(EmpireCMS, ECMS)的网站需要经历几个主要步骤:安装帝国CMS、配置网站环境、创建网站内容和管理网站。以下是一个简化的教程,指导你如何从零开始搭建一个帝国CMS网站。 第一步:安装帝国CMS下载安装包访问帝国CMS官方网站或其他可信来源下载最新版本的安…

帝国cms内核的系统安装和还原数据库

帝国CMS(EmpireCMS,简称ECMS)是一款功能强大且灵活的内容管理系统,被广泛应用于各种类型的网站上。下面将详细介绍帝国CMS系统的安装过程以及如何还原数据库。 帝国CMS系统安装步骤 准备工作下载安装包访问帝国CMS官方网站下载最新版的安装包。解压安装包将下载的安装包解压…

帝国cms网站如何安装

安装帝国CMS(EmpireCMS,简称ECMS)的过程主要包括几个关键步骤:下载安装包、解压文件、上传文件到服务器、配置数据库信息以及完成安装。下面是详细的安装步骤: 安装步骤下载安装包访问帝国CMS的官方网站或其他可靠的下载来源,下载最新版本的安装包。 根据你的需求选择合适…

帝国cms安装时怎么数据库名跟密码不输入也能安装

在正常情况下,安装帝国CMS时,数据库名称和密码是必需的,因为系统需要这些信息来连接和创建数据库表。然而,如果你遇到了不需要输入数据库名称和密码就能安装的情况,这可能是由于以下几个原因:安装程序的默认行为有些早期版本的安装程序可能存在漏洞或设计缺陷,使得在某些…

帝国CMS源码忘记后台用户名和密码怎么办?

如果你忘记了帝国CMS后台的用户名和密码,可以通过以下几种方法来恢复或重置它们: 通过数据库重置密码登录数据库使用数据库管理工具(如phpMyAdmin)登录到你的数据库。定位用户表在数据库中找到存储用户信息的表,通常该表名为user。修改密码找到管理员用户的记录(通常是ad…

MySQL 用户、权限管理,C/C++连接与使用

目录用户用户管理查询所有用户查看当前用户查看当前连接数创建用户删除用户修改密码规则查看规则/策略规则说明临时设置持久设置修改密码权限数据库提供的 权限列表查看权限给用户授权回收用户权限使用C语言连接库的安装C APImysql_initmysql_real_connectmysql_closemysql_que…

帝国默认后台用户名及认证码,帝国CMS忘记后台登陆用户名 密码 认证码 安全提问答案 数据库用户名及密码的解决方法

当你忘记了帝国CMS后台的登录信息,包括用户名、密码、认证码、安全提问答案或数据库的用户名及密码时,可以采取以下几种方法来解决问题: 忘记用户名和密码默认信息帝国CMS在某些版本中提供了默认的后台登录信息,例如账号admin,密码admin888。不过,这并不适用于所有版本,…