跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptAI大前端算法

AI 赋能 JS 逆向:MCP+Skill+autoDecoder 自动化加密分析方案

一种结合 AI 技术的 JS 逆向自动化方案。通过 chrome-devtools-mcp 连接浏览器,利用 Skill 规范 AI 操作,生成 JSRPC 注入代码与 Flask 代理服务,配合 Burp autoDecoder 实现参数加密的自动化处理。方案涵盖工具链介绍、配置流程及实战测试,旨在提升 JS 逆向效率,减少人工对抗成本。

心动瞬间发布于 2026/4/6更新于 2026/5/2135 浏览
AI 赋能 JS 逆向:MCP+Skill+autoDecoder 自动化加密分析方案

0x01 前言

随着前端防护手段日益复杂,参数加密场景广泛且生成逻辑经过多层混淆与封装,人工逆向方法耗时费力且高度依赖经验。本文旨在结合 chrome-devtools-mcp 的能力与 Skill 规范,实现基于 JSRPC、Flask 和 autoDecoder 的前端 JS 逆向自动化分析方案,提升逆向效率。

本文内容仅供技术学习与交流使用,请遵守相关法律法规,因违规使用产生的一切后果由使用者自行承担。

0x02 漏洞详情

传统 JS 逆向方法回顾

传统 JS 逆向工程实践中已形成一系列技术路径,主要归纳为四类:

  1. 直接修改变量法:进入调试模式,在参数加密前直接在作用域中修改参数。
  2. 中间劫持法(JS-forward):通过 JS-forward 实现在明文点处插入代码,将请求内容发送给 Burp Suite 拦截并修改后返回。
  3. 远程调用法(JS-RPC):注入到浏览器页面中的客户端,通过 WebSocket 与本地 Python 服务端相连,直接调用浏览器上下文中预先注册的 JavaScript 函数。
  4. 硬核对抗法(JS 原生):通过反混淆分析代码逻辑研究参数作用添加补环境,最终通过本地运行 JS 来加解密。

在接下来的方案中,选择远程调用法(JS-RPC)作为 MCP 赋能 JS 逆向的底座。它能将浏览器环境直接转化为加密服务接口,避免纯手动逆向的低效,又绕开了纯 JS 还原的高复杂度,适配复杂场景下的 JS 逆向对抗。

MCP 赋能的集成方案

工具链介绍

  • JSRPC:注入到浏览器页面中的客户端,建立通过 WebSocket 协议的远程过程调用机制,直接调用在浏览器上下文中预先注册好的 JavaScript 函数。
  • Flask:接收来自自动化工具如 Burp Suite 插件的请求,提取出需要加密的参数,然后通过 JSRPC 调用浏览器中的函数进行加密,最后重构请求并转发至目标服务器。
  • autoDecoder:Burp Suite 的插件,用于自动化处理应用中的加密/编码接口,自动将明文参数发送至该服务器,并完成加密请求的构建。
  • chrome-devtools-mcp:通过 Chrome DevTools Protocol 与浏览器实例建立连接,将浏览器的底层控制能力封装成一系列标准化的工具,并通过 MCP 协议暴露给 AI 客户端。

流程设计

针对远程调用法初始配置阶段中定位加密函数、编写注册代码等繁琐操作,引入 AI 技术进行赋能,让 AI 自动完成函数发现与注册代码生成,最终实现从'半自动'到'高自动'的跨越。

MCP 配置

  1. 使用 codex 来调用 MCP 服务,首先将 MCP 服务器写进 Codex 的配置。
codex mcp add chrome-devtools npx -y chrome-devtools-mcp@latest
  1. 修改 Codex 的配置文件(MAC 在 ~/.codex/config.toml),添加如下字段。
[mcp_servers.chrome-devtools]
  1. 检测是否生效。

  2. 启动 MCP 服务,当看到打开浏览器后 MCP 服务就配置好了。

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome

Skill 配置

Skill 是能否一次性完成 JS 分析和代码生成的关键,创建 3 个 markdown 文件用于规范 AI 的操作以及输出。

1、主技能模板 (js-reverse-automation)

负责整体流程控制和协调,规范 AI 通过 MCP 协议连接和控制浏览器环境。

- name: js-reverse-automation description: 通过 MCP 连接浏览器,为目标自动化搭建 JS 环境,定位签名/加密函数入口,生成 JSRPC 代码,创建 Flask 代理,并输出 Burp autoDecoder 配置。
...

2、JSRPC 注入模板 (jsrpc-injection-template)

提供通用的函数拦截和远程调用能力,确保代码注入的稳定性和安全性。

// 1) 建立 JSRPC 连接
var client = new Hlclient("ws://127.0.0.1:12080/ws?group=fausto&name=burp");
// 2) 配置区
var JSRPC_CONFIG = {
    actionName: "generate_sign",
    entry: { type: "global", path: "signFunction" },
    bindThis: null,
    async: false,
    normalizeInput: function(param) { return param; },
    normalizeOutput: function(result) { return result; },
    onError: function(err) { return "ERROR_" + Date.now(); }
};
...

3、Flask 代理模板 (flask-jsrpc-proxy-template)

面向 Burp autoDecoder 的 Flask 代理服务模板,用于将请求体交给 JSRPC 生成加密后的结果并回填。

from flask import Flask, request
import requests
import json
import logging
logging.basicConfig(level=logging.DEBUG)
app = Flask(__name__)
JSRPC_URL = "http://127.0.0.1:12080/go"
JSRPC_GROUP = "fausto"
JSRPC_ACTION = "generate_sign"
SIGN_FIELD = "sign"
TIMEOUT = 5
@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', '')
    if not data_body:
        app.logger.error("未接收到 dataBody")
        return data_headers + "\r\n\r\n\r\n\r\n" + data_body if data_headers else data_body
    try:
        json_data = json.loads(data_body)
    except json.JSONDecodeError as e:
        app.logger.error(f"解析 JSON 失败:{e}")
        return data_headers + "\r\n\r\n\r\n\r\n" + data_body if data_headers else data_body
    old_sign = json_data.pop(SIGN_FIELD, None)
    app.logger.info(f"已移除旧签名:{old_sign}")
    params_for_jsrpc = {
        "group": JSRPC_GROUP,
        "action": JSRPC_ACTION,
        "param": json.dumps(json_data, ensure_ascii=False, separators=(',', ':'))
    }
    try:
        jsrpc_response = requests.get(JSRPC_URL, params=params_for_jsrpc, timeout=TIMEOUT)
        jsrpc_response.raise_for_status()
        result = jsrpc_response.json()
        new_sign = result.get('data', '')
    except requests.exceptions.RequestException as e:
        app.logger.error(f"调用 JSRPC 失败:{e}")
        new_sign = ""
    except json.JSONDecodeError as e:
        app.logger.error(f"解析 JSRPC 返回失败:{e}")
        new_sign = ""
    json_data[SIGN_FIELD] = new_sign
    new_data_body = json.dumps(json_data, ensure_ascii=False, separators=(',', ':'))
    if data_headers:
        new_content_length = len(new_data_body)
        new_headers = data_headers.replace(
            f"Content-Length: {len(data_body)}",
            f"Content-Length: {new_content_length}"
        )
        return new_headers + "\r\n\r\n\r\n\r\n" + new_data_body
    return new_data_body
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)

实战测试

以某大学人事管理系统为例,其 password 字段被加密,全程使用 AI 进行分析,并全程使用 AI 生成的代码进行测试。

  1. 输入触发 Skill 的提示词,AI 会提示我们需要输入的内容。
按 skill.md 的流程执行
  1. 在网页中提取我们所需的参数。

  2. 然后输入提示我们需要输入的所需参数至 codex。

目标址(URL):https://xxx/login/index
  1. 等待代码执行完成发现所需的代码均已创建完成。
Using skill js-reverse-automation (and its JSRPC/Flask/Burp templates) because the task matches the skill description.
  1. 启动 JSRPC。

  2. 在浏览器开发者工具的 Console 中,执行 JSRpc 项目中的 JsEnv_Dev.js 文件内容。

  3. 在控制台注入 AI 生成的 jsrpc_password_md5.js。

// JSRPC injection for hr.ncu.edu.cn login password MD5
// Requires Hlclient to be available in the page context.
var client = new Hlclient("ws://127.0.0.1:12080/ws?group=fausto&name=burp");
var JSRPC_CONFIG = {
    actionName: "generate_password_md5",
    entry: {
        type: "resolver",
        resolver: function () {
            if (window.$ && typeof $.md5 === "function") return $.md5;
            if (window.jQuery && typeof jQuery.md5 === "function") return jQuery.md5;
            return null;
        },
    },
    bindThis: null,
    async: false,
    normalizeInput: function (param) {
        if (param && typeof param === "object") {
            if (param.password != null) return String(param.password);
            if (param.pwd != null) return String(param.pwd);
        }
        return String(param == null ? "" : param);
    },
    normalizeOutput: function (result) {
        return result;
    },
    onError: function (err) {
        return "ERROR_" + Date.now();
    },
};
function resolveEntry(config) {
    if (config.entry.type === "resolver" && typeof config.entry.resolver === "function") {
        return config.entry.resolver();
    }
    return null;
}
client.regAction(JSRPC_CONFIG.actionName, function (resolve, param) {
    try {
        var fn = resolveEntry(JSRPC_CONFIG);
        if (typeof fn !== "function") throw new Error("md5 function not found");
        var input = JSRPC_CONFIG.normalizeInput(param);
        var ctx = JSRPC_CONFIG.bindThis || null;
        var result = fn.call(ctx, input);
        if (JSRPC_CONFIG.async && result && typeof result.then === "function") {
            result.then(function (res) {
                resolve(JSRPC_CONFIG.normalizeOutput(res));
            }).catch(function (err) {
                resolve(JSRPC_CONFIG.onError(err));
            });
            return;
        }
        resolve(JSRPC_CONFIG.normalizeOutput(result));
    } catch (error) {
        resolve(JSRPC_CONFIG.onError(error));
    }
});
  1. 测试 JSRPC 调用函数是否正常。
http://127.0.0.1:12080/go?group=fausto&action=generate_password_md5&param=111111
  1. 运行 flask_proxy_password.py。
from flask import Flask, request
import requests
import json
import logging
from urllib.parse import parse_qs, urlencode
import re
logging.basicConfig(level=logging.DEBUG)
app = Flask(__name__)
JSRPC_URL = "http://127.0.0.1:12080/go"
JSRPC_GROUP = "fausto"
JSRPC_ACTION = "generate_password_md5"
PASSWORD_FIELD = "password"
TIMEOUT = 5
CONTENT_LENGTH_RE = re.compile(r"Content-Length:\s*\d+", re.IGNORECASE)
def call_jsrpc(raw_password: str) -> str:
    params_for_jsrpc = {
        "group": JSRPC_GROUP,
        "action": JSRPC_ACTION,
        "param": raw_password,
    }
    try:
        jsrpc_response = requests.get(JSRPC_URL, params=params_for_jsrpc, timeout=TIMEOUT)
        jsrpc_response.raise_for_status()
        result = jsrpc_response.json()
        return result.get("data", "")
    except requests.exceptions.RequestException as e:
        app.logger.error(f"JSRPC request failed: {e}")
        return ""
    except json.JSONDecodeError as e:
        app.logger.error(f"JSRPC response parse failed: {e}")
        return ""
@app.route('/encode', methods=['POST'])
def handle_encode():
    app.logger.info("- incoming autoDecoder request -")
    data_body = request.form.get('dataBody', '')
    data_headers = request.form.get('dataHeaders', '')
    if not data_body:
        app.logger.error("missing dataBody")
        return data_headers + "\r\n\r\n\r\n\r\n" + data_body if data_headers else data_body
    # Try JSON first
    new_body = None
    try:
        json_data = json.loads(data_body)
        raw_pwd = str(json_data.get(PASSWORD_FIELD, ""))
        if raw_pwd:
            json_data[PASSWORD_FIELD] = call_jsrpc(raw_pwd)
        new_body = json.dumps(json_data, ensure_ascii=False, separators=(',', ':'))
    except json.JSONDecodeError:
        # Fallback to x-www-form-urlencoded
        form = parse_qs(data_body, keep_blank_values=True)
        raw_pwd = form.get(PASSWORD_FIELD, [""])[0]
        if raw_pwd:
            form[PASSWORD_FIELD] = [call_jsrpc(raw_pwd)]
        new_body = urlencode(form, doseq=True)
    if data_headers:
        new_len = len(new_body)
        new_headers = CONTENT_LENGTH_RE.sub(f"Content-Length: {new_len}", data_headers)
        return new_headers + "\r\n\r\n\r\n\r\n" + new_body
    return new_body
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8888, debug=True)
  1. 测试 Flask 是否可以正常加密。
curl -X POST http://127.0.0.1:8888/encode
  1. 最后参考 Burp autoDecoder 配置说明配置 Burp 的 autoDecoder 插件,也成功加密了参数,整体完美运行下来了!

0x03 总结

本文成功实现了全自动化的 JS 分析和代码生成。对于复杂场景的 JS 代码分析可能仍需一定调试,但 AI 的优势在于可以反复迭代优化。期待更多思路交流和代码优化,共同提升安全测试能力。

目录

  1. 0x01 前言
  2. 0x02 漏洞详情
  3. 传统 JS 逆向方法回顾
  4. MCP 赋能的集成方案
  5. 工具链介绍
  6. 流程设计
  7. MCP 配置
  8. Skill 配置
  9. 实战测试
  10. 0x03 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Magic API:低代码接口开发平台完全指南
  • Linux 进程间通信实战:命名管道(FIFO)详解
  • AI 鸿蒙 App 开发中的架构逻辑转变
  • SSM 框架文件上传功能实战:从前端到后端完整流程
  • Windows 10/11 USB-Blaster 驱动安装详解
  • 系统架构与设计:空间、角色与开发流程
  • DIY 无人机电源管理电路:升压与降压模块详解
  • PyTorch 深度学习:分类任务详解
  • 19. Flutter与Web混合开发实践:打造跨平台的统一体验
  • SQL Server 2019 安装与配置指南
  • 内容创作模式全解:UGC、PGC、PUGC、OGC、MGC、BGC 与 AIGC
  • 程序员学历重要性探讨及 Python 技术成长路线
  • DeepSeek 深度使用指南:提示词技巧与本地知识库搭建
  • Buzz:基于 Whisper 的离线语音转写工具
  • 使用 Trae、Cline 与阿里云 Coding Plan 构建 AI 编程工作流
  • 17 款常用跨浏览器测试工具汇总
  • C++ STL List 容器详解与模拟实现
  • Ubuntu 20.04 安装最新版 scrcpy 工具
  • Web 前端开发入门准备指南:思维、心态与知识体系
  • 前端调用摄像头拍照,并使用 Vue Cropper 进行裁剪

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online