【JS逆向】某物官网实战-签名对抗
字数 1602 2025-12-06 12:05:09
某物官网JS逆向实战教学文档
一、反调试对抗
1.1 反调试现象分析
- 打开开发者工具时触发无限debugger反调试机制
- 阻止正常调试流程,增加逆向分析难度
1.2 反调试绕过方法
方法一:修改为手机预览模式
- 操作步骤:切换浏览器为移动设备模拟模式
- 原理:部分网站对移动端和PC端采用不同的反调试策略
方法二:使用AntiDebug_Breaker工具
- 工具地址:https://github.com/0xsdeo/AntiDebug_Breaker
- 具体功能:使用Bypass Debugger功能成功绕过反调试
- 优势:自动化绕过,无需手动修改代码
二、加密逻辑分析
2.1 签名定位
- 点击分类栏触发API请求:
/api/v1/h5/commodity-pick-interfaces/pc/pick-rule-result/feeds/info - 发现请求体中存在sign签名字段
- 全局搜索sign,定位到关键代码:
sign: p(t)
2.2 签名函数分析
function p(e) {
return f()("".concat(e ? s()(e).sort().reduce(function(t, n) {
return "".concat(t).concat(n).concat(e[n])
}, "") : "", "048a9c4943398714b356a696503d2d36"))
}
参数处理逻辑:
- 对参数对象e进行键名排序:
s()(e).sort() - 拼接格式:键名+键值,如
pickRuleId644443 - 末尾添加固定密钥:
048a9c4943398714b356a696503d2d36
2.3 MD5加密核心
e.exports = function(e, n) {
if (void 0 === e || null === e)
throw new Error("Illegal argument " + e);
var r = t.wordsToBytes(a(e, n));
return n && n.asBytes ? r : n && n.asString ? i.bytesToString(r) : t.bytesToHex(r)
}
MD5算法特征:
- 输入处理:字符串转字节数组
- 核心运算:包含标准MD5的四个辅助函数(_ff, _gg, _hh, _ii)
- 输出格式:支持字节数组、字符串、十六进制三种格式
三、JSRPC+Flask+autoDecoder实现方案
3.1 技术架构原理
Burp Suite → autoDecoder → Flask中间件 → JSRPC → 浏览器环境 → 返回签名
3.2 具体实现步骤
步骤一:注入JSRPC客户端
在浏览器控制台执行JsEnv_Dev.js内容,建立WebSocket连接
步骤二:暴露签名函数到全局
window.signFunction = p; // 将原始签名函数p暴露为全局可访问
步骤三:注册JSRPC调用方法
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=dewu&name=burp");
demo.regAction("generate_sign", function(resolve, param) {
try {
if (typeof window.signFunction !== 'function') {
throw new Error("签名函数未定义");
}
var signature = window.signFunction(param);
console.log("生成的签名:", signature);
resolve(signature);
} catch (error) {
console.error("签名生成错误:", error);
resolve("ERROR_" + Date.now());
}
});
步骤四:Flask中间件开发
from flask import Flask, request, jsonify
import requests
import json
import logging
logging.basicConfig(level=logging.DEBUG)
app = Flask(__name__)
@app.route('/encode', methods=['POST'])
def handle_encode():
app.logger.info("--- 收到来自Burp/autoDecoder的编码请求 ---")
data_body = request.form.get('dataBody', '')
data_headers = request.form.get('dataHeaders', '')
app.logger.debug(f"原始请求头: {data_headers}")
app.logger.debug(f"原始请求体: {data_body}")
if not data_body:
app.logger.error("未接收到dataBody")
return data_headers + "\r\n\r\n" + data_body if data_headers else data_body
try:
json_data = json.loads(data_body)
app.logger.info("成功解析JSON数据")
except json.JSONDecodeError as e:
app.logger.error(f"解析JSON失败: {e}")
return data_headers + "\r\n\r\n" + data_body if data_headers else data_body
# 调用JSRPC获取签名并重构请求逻辑
步骤五:测试Flask接口
curl -X POST http://127.0.0.1:8888/encode \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "dataBody={\"pickRuleId\":644479,\"pageNum\":1,\"pageSize\":24,\"filterUnbid\":true,\"showCspu\":true,\"sign\":\"testsign\"}&dataHeaders=$headers"
步骤六:配置autoDecoder
- 接口地址:http://127.0.0.1:8888/encode
- 编码类型:选择自定义编码器
- 数据格式:表单格式,使用dataBody和dataHeaders作为键
3.3 签名生成测试
通过爆破pickRuleId参数验证签名自动生成功能,确认系统能够正确处理不同参数并生成有效签名。
四、工具汇总
4.1 必需工具列表
-
AntiDebug_Breaker:反调试绕过工具
- 地址:https://github.com/0xsdeo/AntiDebug_Breaker
-
JsRpc:浏览器环境RPC通信框架
- 地址:https://github.com/jxhczhl/JsRpc
-
autoDecoder:Burp Suite自动化编码解码插件
- 地址:https://github.com/f0ng/autoDecoder
4.2 环境要求
- Python 3.x 运行环境
- 支持WebSocket的现代浏览器
- Burp Suite专业版(支持插件扩展)
五、关键技术要点
5.1 签名算法核心
- 参数排序:按字母顺序排列对象键名
- 字符串拼接:键名+键值的连续拼接方式
- 密钥追加:固定密钥
048a9c4943398714b356a696503d2d36 - MD5哈希:标准MD5算法生成最终签名
5.2 调试技巧
- 断点设置:在sign: p(t)处设置断点跟踪参数传递
- 函数跟踪:逐步进入p()、f()、a()函数分析加密流程
- 控制台调试:实时查看变量值验证分析结果
5.3 错误处理
- 签名函数未定义检查
- JSON解析异常处理
- 网络通信超时重试机制
- 错误签名标识(ERROR_前缀)
本教学文档详细记录了某物官网JS逆向的全过程,从反调试对抗到签名算法分析,再到完整的自动化实现方案,为类似网站的逆向分析提供了完整的技术参考。