百某应JS逆向

https://ying.baichuan-ai.com/

 

目录

一、发起提问

二、观察发现有两个加密参数:X-Bc-Sig和X-Bc-Ts

​三、观察JS调用栈

四、从JS中搜索 X-Bc-Sig和X-Bc-Ts

五、断点并分析参数的生成方式

六、分析入参

七、发现关键的o方法调用了一个i()方法

八、验证结果

九、python执行Node.JS获取参数(本地安装了Node环境)

十、python本地执行JS(本地未安装Node.js环境)

十一、实际应用


一、发起提问

二、观察发现有两个加密参数:X-Bc-Sig和X-Bc-Ts

 三、观察JS调用栈

四、从JS中搜索 X-Bc-Sig和X-Bc-Ts

发现只有_app-xxxxx.js文件中存在X-Bc-Sig

五、断点并分析参数的生成方式

六、分析入参

一个参数是固定字符串:"uwlACMuXQApWgO0Q"

一个参数是时间戳组成的动态字符串:"1721891456251retry=3&thread_info=[object Object]"

七、发现关键的o方法调用了一个i()方法

找了一圈没找到i()方法,无奈我只好在控制台打印一下,看看这个i()是什么样的

断点挺住,在去控制台打印一下

七、模拟生成

1、先将关键的o方法复制出来

2、模拟i()方法

3、 调用o方法和截取逻辑复制过来

4、构建参数

我们可以看到n是当前时间戳 n = Date.now()

r是混淆参数 undefined

a是由时间戳组成的固定字符串

 

八、验证结果

 九、python执行Node.JS获取参数(本地安装了Node环境)

import execjs# JavaScript代码
js_code = """
const CryptoJS = require("crypto-js");function i() {return CryptoJS
}function o(t, e) {let r = i().enc.Utf8.parse("0000000000000000");return i().AES.encrypt(t, i().enc.Utf8.parse(e), {iv: r,mode: i().mode.CBC,padding: i().pad.Pkcs7}).toString()
}//构建入参
const n = '1721892945291'
const r = undefined
const a = `${n.toString()}retry=3&thread_info=[object Object]`// 执行关键o函数
let s = o(a, r ? r.substring(0, 16) : "uwlACMuXQApWgO0Q");
// 截取逻辑
s.length > 64 && (s = s.substring(0, 64))
result = {"x-bc-sig": s,"x-bc-ts": n.toString()
}
return result
"""# 编译JavaScript代码
ctx = execjs.compile(js_code)# 执行JavaScript代码并获取结果
result = ctx.call("JSON.stringify")# 输出结果
print(result)

十、python本地执行JS(本地未安装Node.js环境)

将crypto-js下载到本地:

crypto-js.min.js

CRYPTO-JS.MIN.JS: DOWNLOAD - CDNPKG

 
encryption.js
//encryption.js//引入本地加密库
const CryptoJS = require('./crypto-js.min.js');function i() {return CryptoJS
}function o(t, e) {let r = i().enc.Utf8.parse("0000000000000000");return i().AES.encrypt(t, i().enc.Utf8.parse(e), {iv: r,mode: i().mode.CBC,padding: i().pad.Pkcs7}).toString()
}//构建入参
const n = '1721892945291'
const r = undefined
const a = `${n.toString()}retry=3&thread_info=[object Object]`// 执行关键o函数
let s = o(a, r ? r.substring(0, 16) : "uwlACMuXQApWgO0Q");
// 截取逻辑
return s.length > 64 && (s = s.substring(0, 64)),{"x-bc-sig": s,"x-bc-ts": n.toString()}
import execjs# 读取crypto-js库文件和你的JavaScript代码
with open('crypto-js.min.js', 'r', encoding='utf-8') as file:crypto_js_code = file.read()with open('encryption.js', 'r', encoding='utf-8') as file:script_code = file.read()# 整合JavaScript代码
js_code = crypto_js_code + "\n" + script_code# 编译JavaScript代码
ctx = execjs.compile(js_code)# 执行JavaScript代码并获取结果
result = ctx.call("JSON.stringify")# 输出结果
print(result)

十一、实际应用

发现runs接口的签名和delete接口的签名有所不同

runs直接对时间戳签名就可以

delete接口需要对时间戳和id进行双重签名

我只能写成两个function来供python调用

//引入本地加密库
const CryptoJS = require('./crypto-js.min.js');function i() {return CryptoJS
}function o(t, e) {let r = i().enc.Utf8.parse("0000000000000000");return i().AES.encrypt(t, i().enc.Utf8.parse(e), {iv: r,mode: i().mode.CBC,padding: i().pad.Pkcs7}).toString()
}function runs_sign() {//构建入参const n = Date.now()const r = undefinedconst a = `${n.toString()}retry=3&thread_info=[object Object]`// const a = `${n.toString()}id=6042075`// 执行关键o函数let s = o(a, r ? r.substring(0, 16) : "uwlACMuXQApWgO0Q");// 截取逻辑return s.length > 64 && (s = s.substring(0, 64)),{"x-bc-sig": s,"x-bc-ts": n.toString()}
}function delete_sign(id) {//构建入参const n = Date.now()const r = undefinedconst a = `${n.toString()}id=${id}`// 执行关键o函数let s = o(a, r ? r.substring(0, 16) : "uwlACMuXQApWgO0Q");// 截取逻辑return s.length > 64 && (s = s.substring(0, 64)),{"x-bc-sig": s,"x-bc-ts": n.toString()}
}

    def get_runs_sign_and_timestamp(self):"""获取访问签名和时间戳"""# 读取crypto-js库文件和你的JavaScript代码with open('crypto-js.min.js', 'r', encoding='utf-8') as file:crypto_js_code = file.read()with open('encryption.js', 'r', encoding='utf-8') as file:script_code = file.read()# 整合JavaScript代码js_code = crypto_js_code + "\n" + script_code# 编译JavaScript代码ctx = execjs.compile(js_code)# 执行JavaScript代码并获取结果result = ctx.call("runs_sign")return result['x-bc-sig'], result['x-bc-ts']def get_delete_sign_and_timestamp(self, id):"""获取删除签名和时间戳"""# 读取crypto-js库文件和你的JavaScript代码with open('crypto-js.min.js', 'r', encoding='utf-8') as file:crypto_js_code = file.read()with open('encryption.js', 'r', encoding='utf-8') as file:script_code = file.read()# 整合JavaScript代码js_code = crypto_js_code + "\n" + script_code# 编译JavaScript代码ctx = execjs.compile(js_code)# 执行JavaScript代码并获取结果result = ctx.call("delete_sign", id)return result['x-bc-sig'], result['x-bc-ts']

十二、技巧①

当我们找不到某个函数在哪里的时候,只要在控制台打印这个函数,然后在控制台点击打印的结果,即可跳转到该函数。

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

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

相关文章

windows下配置Elasticsearch和kibana

一、下载Elasticsearch 8.12.2 Download Elasticsearch | Elastic 二、下载kibana 8.12.2 Download Kibana Free | Get Started Now | Elastic 三、下载ik:https://github.com/infinilabs/analysis-ik/releases?page1 选择与下载的es版本一致的下载 解压改名&…

Python 消费Kafka手动提交 批量存入Elasticsearch

一、第三方包选择 pip install kafka,对比了kafka和pykafka,还是选择kafka,消费速度更快pip install elasticsearch7.12.0(ES版本) 二、创建es连接对象 from elasticsearch import Elasticsearch from elasticsearch.helpers import bulkc…

@RequestParam和@PathVariable 处理 HTTP 请求参数的注解

RequestParam 请求参数 可解析前端get请求路径后以问号拼接的参数,查询参数是 URL 后面的问号 (?) 后跟的一系列键值对,RequestParam 可以设置参数是否是必需的(使用 required 属性) GetMapping("/users") public String getUsers(RequestPar…

前后端项目打包对比——关于Spring Boot Maven Plugin配置的问题

Spring Boot Maven Plugin 配置详解 Spring Boot Maven Plugin 配置详解1. 添加插件到 pom.xml2. 插件配置2.1 基本配置2.2 配置参数详解默认行为说明简单配置示例为什么这样的配置能工作?进一步说明 2.3 高级配置 3. 使用插件打包应用程序3.1 打包成 JAR 文件3.2 打…

ElasticSearch(六)— 全文检索

一、match系列查询 前面讲到的query中的查询,都是精准查询。可以理解成跟在关系型数据库中的查询类似。match系列的查询,是全文检索的查询。会通过分词进行评分,匹配,再返回搜索结果。 1.1 match 查询 "query": {&qu…

Linux 大页修改

随笔记录 目录 1. 背景介绍 2. 麒麟SP1 系统修改大页 2.1 查询大页信息 2.2 通过kernel cmdline配置大页 2.3 生成配置 2.4 查看配置是否生效 2.5 查询大页是否配置成功 3. CenOS 系统修改大页 1. 背景介绍 若操作系统当前Hugepagesize不是2048kB,则只能…

SSM框架整合——常用方式整合SSM框架(三)Spring和MyBatis整合

一、Spring和MyBatis的整合步骤 Spring和MyBatis的整合可以分为2步来完成,首先搭建Spring环境,然后整合MyBatis到Spring环境中。框架环境包含框架对应的依赖和配置文件,其中Spring的依赖、MyBatis的依赖、Spring和MyBatis整合的依赖&#xf…

c++笔记4

目录 深度优先搜索DFS DFS的复杂度 DFS与递归 递归与暴力枚举 递归树 DFS与栈 DFS的搜索剪枝 搜索剪枝与优化 可行性剪枝 最优化剪枝 减少等效的分支 优化搜索顺序 搜索的记忆化 搜索的复杂度 大多时候,搜索的复杂度都是指数级的。各种剪枝方案&#…

Flink 技术与应用(一)

Flink技术与应用(初级篇) 起源 Apache Flink 是一个开源的大数据处理框架,其起源可以追溯到一个名为 Stratosphere 的研究项目,旨在建立下一代大数据分析引擎,2010 年,从 Stratosphere 项目中分化出了 Fl…

「Unity3D」场景中的距离单位Unit与相关设置PixelsToUnits、PixelsPerUnit

GameObject在场景的位置Position,并没有明确是什么具体单位——如:Transform的x、y、z,或RectTransform的PosX、PosY、PosZ。而RectTransform在面板上显示的Width和Height,也没有具体单位,其实并不是像素。 事实上&am…

Java 中对象List 转map实践

class MyObject {Long id;String name;// Constructorpublic MyObject(Long id, String name) {this.id id;this.name name;}// Getterspublic Long getId() {return id;}public String getName() {return name;} }第一种 List 转 Map<Long, String> List<MyObject…

百易云资产管理运营系统 comfileup.php 文件上传致RCE漏洞复现(XVE-2024-18154)

0x01 产品简介 百易云资产管理运营系统,是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全生命周期管理,包括资产的登记、盘点、评估、处置等多个环节,同时提供强大的运营分析功能,帮助企业优化资产配置,提升运营效率。 0x02 漏…

用Python移除Word文档中的宏

Word文档作为最常用的电子文档格式之一&#xff0c;经常被用来作为内容分享工具&#xff0c;在网络中或设备之间进行传输&#xff0c;其安全性也需要受到关注。宏是可嵌入Word文档中的一种VBA迷你程序&#xff0c;用来执行一些自动化操作。虽然宏可以提高工作效率&#xff0c;但…

C++内存管理(候捷)第五讲 笔记

GNU C对allocators的描述 new_allocator 和malloc_allocator&#xff0c;它们都没有特别的动作&#xff0c;无非底部调用operator new和malloc。它们没有用内存池 区别&#xff1a;::operator new是可重载的 智能型的allocator&#xff0c;使用内存池&#xff0c;分一大块然后…

嵌入式系统面试宝典:常见问题与答案解析

1. 什么是嵌入式系统&#xff1f; 答案: 嵌入式系统是一种专用的计算机系统&#xff0c;它被设计用于执行特定的任务。它通常包含硬件组件&#xff08;如微控制器或微处理器&#xff09;和嵌入在硬件中的软件。 2. 请解释中断和轮询的区别。 答案: 中断是一种异步事件&#…

【PyTorch】基于YOLO的多目标检测项目(一)

【PyTorch】基于YOLO的多目标检测项目&#xff08;一&#xff09; 【PyTorch】基于YOLO的多目标检测项目&#xff08;二&#xff09; 目标检测是对图像中的现有目标进行定位和分类的过程。识别的对象在图像中显示有边界框。一般的目标检测方法有两种&#xff1a;基于区域提议的…

如何找到最快解析速度的DNS

如何找到最快解析速度的DNS DNS&#xff0c;即域名系统&#xff08;Domain Name System&#xff09;&#xff0c;是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使用户更方便地访问互联网&#xff0c;而不用记住能够被机器直接读取的IP数…

6.乳腺癌良性恶性预测(二分类、逻辑回归、PCA降维、SVD奇异值分解)

乳腺癌良性恶性预测 1. 特征工程1.1 特征筛选1.2 特征降维 PCA1.3 SVD奇异值分解 2. 代码2.1 逻辑回归、二分类问题2.2 特征降维 PCA2.3 SVD奇异值分解 1. 特征工程 专业上&#xff1a;30个人特征来自于临床一线专家&#xff0c;每个特征和都有医学内涵&#xff1b;数据上&…

7月25日JavaSE学习笔记

线程的生命周期中&#xff0c;等待是主动的&#xff0c;阻塞是被动的 锁对象 创建锁对象&#xff0c;锁对象同一时间只允许一个线程进入 //创建锁对象Lock locknew ReentrantLock(true);//创建可重入锁 可重入锁&#xff1a;在嵌套代码块中&#xff0c;锁对象一样就可以直接…

探索PostgreSQL的GUI工具:提升数据库管理效率

在当今快速发展的技术世界中&#xff0c;数据库管理是任何软件开发项目的核心部分。PostgreSQL&#xff0c;作为一款功能强大的开源关系型数据库管理系统&#xff0c;因其稳定性、可靠性和高度的可扩展性而广受开发者和数据库管理员的青睐。然而&#xff0c;尽管PostgreSQL自带…