【好靶场】JS加密逆向分析笔记
字数 1616 2025-11-13 12:06:50

JS加密逆向分析教学文档

0x00 前言

JS加密逆向分析是前端安全与逆向工程领域的核心技术之一,主要针对网页、移动端H5或Electron等基于JavaScript运行的应用中,用于保护数据传输、接口请求、核心逻辑的加密机制,通过技术手段还原加密流程、推导加密算法、破解加密参数的一系列分析过程。

在安全测试中,经常遇到接口存在越权漏洞但数据包被加密的情况,此时需要分析JS进行参数伪造和数据包构造。本文基于真实案例,详细讲解JS加密逆向分析的技术要点。

0x01 JS加密逆向分析反调试对抗

靶场地址

http://www.loveli.com.cn/see_bug_one?id=379

反调试技术分析

反调试手段:

  1. 禁用快捷键和右键菜单
  2. 持续触发debugger暂停
  3. 通过窗口尺寸变化检测DevTools状态

应对方法:

  • 页面Ctrl+S保存源码到本地分析
  • 浏览器调试器中选择"一律不在此处暂停"

JavaScript逆向分析流程

1. 数据隐藏机制

页面DOMContentLoaded时拼出隐藏节点#__k

  • data-x:存储被"插隔符+反转+Base64"处理的公钥数据
  • data-s:存储分隔符(默认::

2. 加密请求构造

  • 默认id=2,用公钥对字符串"2"加密
  • 加密结果作为htccheck参数传给后端

3. 公钥还原函数d()的实现

// 还原流程:
// 1. 从data-x用data-s拼接
// 2. 反转字符串
// 3. Base64解码得到PEM文本

4. 加密算法核心

  • 算法:RSA-OAEP(SHA-256)
  • 优先使用WebCrypto API,回退使用node-forge
  • 两条路径算法保持一致

加密算法逆向步骤

PEM公钥还原:

  1. 从data-x去掉分隔符::
  2. 拼接为连续字符串
  3. 整串反转
  4. Base64解码得到标准PEM文本

加密流程:

  1. 对明文"1"执行RSA-OAEP(SHA-256)加密
  2. 对密文字节进行Base64编码
  3. 得到htccheck参数值

脚本实现

# htccheck.py 用法:
# 生成id=1:python htccheck.py
# 生成任意id:python htccheck.py --id 2

0x02 JS加密加盐逆向分析案例

代码结构分析

常量定义(main.min.js)

常量数组存储在b中,通过r(idx)取值:

b[0] = "-----BEGIN PUBLIC KEY-----"
b[1] = "-----END PUBLIC KEY-----"
b[2] = "spki"
b[3] = "RSA-OAEP"
b[4] = "SHA-256"
b[5] = "encrypt"
b[6] = "data-x"
b[7] = "data-s"

核心函数分析

1. c()函数 - 回退加载器

  • 检测全局forge.pki是否存在
  • 依次尝试3个CDN动态加载node-forge
  • 成功resolve(true),全部失败reject

2. __resolvePem()函数 - PEM公钥还原

function __resolvePem() {
    const element = document.getElementById('__k');
    if (!element) return '';
    
    const dataX = element.getAttribute('data-x');
    const dataS = element.getAttribute('data-s') || '::';
    
    // 还原流程:
    // 1. 去掉分隔符拼接
    // 2. 字符串反转
    // 3. Base64解码
    return atob(dataX.replace(new RegExp(dataS, 'g'), '').split('').reverse().join(''));
}

3. rsaEncryptWithPEM()函数 - 加密主函数

async function rsaEncryptWithPEM(g, h) {
    // 明文构造逻辑
    h = h || "2"; // 默认值
    h = h + "10086"; // 加盐处理
    
    // 加密实现...
}

详细加密流程

WebCrypto加密路径(优先)

步骤1:PEM预处理

k = g.trim()
    .replace("-----BEGIN PUBLIC KEY-----", "")
    .replace("-----END PUBLIC KEY-----", "")
    .replace(/\s+/g, '');

步骤2:Base64转ArrayBuffer

l = Uint8Array.from(atob(k), ch => ch.charCodeAt(0));
const buffer = l.buffer;

步骤3:导入公钥

const publicKey = await crypto.subtle.importKey(
    "spki",
    buffer,
    {
        name: "RSA-OAEP",
        hash: "SHA-256"
    },
    false,
    ["encrypt"]
);

步骤4:明文编码与加密

const encoder = new TextEncoder();
const plaintextBytes = encoder.encode(h);

const ciphertext = await crypto.subtle.encrypt(
    { name: "RSA-OAEP" },
    publicKey,
    plaintextBytes
);

// 转Base64输出
const uint8Array = new Uint8Array(ciphertext);
const htccheck = btoa(String.fromCharCode(...uint8Array));

node-forge回退路径

步骤1:动态加载检测

if (typeof forge === 'undefined') {
    await c(); // 加载node-forge
}

步骤2:PEM解析与加密

const publicKey = forge.pki.publicKeyFromPem(g);
const plaintext = forge.util.encodeUtf8(h);

const cipherBytes = publicKey.encrypt(plaintext, 'RSA-OAEP', {
    md: forge.md.sha256.create(),
    mgf1: forge.mgf1.create(forge.md.sha256.create())
});

const htccheck = forge.util.encode64(cipherBytes);

完整调用流程

  1. 获取PEM公钥
const pem = __resolvePem();
  1. 生成htccheck
const htccheck = await rsaEncryptWithPEM(pem, prefix);
// 不传prefix:默认明文"210086"
// 传"9":明文"910086"

其他文件说明

  • beta.min.js:生成sessionStorage.k1..k3
  • gamma.min.js:设置window.__z
  • zeta.min.js:设置window.__q
  • 注:这些文件主要起混淆作用,与核心加密逻辑无关

0x03 关键技术要点总结

1. 反调试对抗技术

  • 多维度检测调试环境
  • 需要掌握相应的绕过技巧

2. 数据隐藏技术

  • 分隔符插入
  • 字符串反转
  • Base64编码组合使用

3. 加密算法要点

  • 算法:RSA-OAEP with SHA-256
  • 双路径实现(WebCrypto + node-forge)
  • 加盐处理:明文拼接固定字符串"10086"

4. 逆向分析步骤

  1. 识别加密参数(htccheck)
  2. 定位加密函数调用
  3. 分析公钥获取方式
  4. 还原加密算法流程
  5. 编写对应加密脚本

5. 脚本开发要点

  • 准确还原PEM公钥获取流程
  • 实现双加密路径兼容
  • 支持参数化输入(不同id值)

通过掌握以上技术要点,可以系统性地分析和逆向JS加密实现,为安全测试和漏洞利用提供技术支撑。

JS加密逆向分析教学文档 0x00 前言 JS加密逆向分析是前端安全与逆向工程领域的核心技术之一,主要针对网页、移动端H5或Electron等基于JavaScript运行的应用中,用于保护数据传输、接口请求、核心逻辑的加密机制,通过技术手段还原加密流程、推导加密算法、破解加密参数的一系列分析过程。 在安全测试中,经常遇到接口存在越权漏洞但数据包被加密的情况,此时需要分析JS进行参数伪造和数据包构造。本文基于真实案例,详细讲解JS加密逆向分析的技术要点。 0x01 JS加密逆向分析反调试对抗 靶场地址 http://www.loveli.com.cn/see_ bug_ one?id=379 反调试技术分析 反调试手段: 禁用快捷键和右键菜单 持续触发debugger暂停 通过窗口尺寸变化检测DevTools状态 应对方法: 页面Ctrl+S保存源码到本地分析 浏览器调试器中选择"一律不在此处暂停" JavaScript逆向分析流程 1. 数据隐藏机制 页面DOMContentLoaded时拼出隐藏节点 #__k : data-x :存储被"插隔符+反转+Base64"处理的公钥数据 data-s :存储分隔符(默认 :: ) 2. 加密请求构造 默认id=2,用公钥对字符串"2"加密 加密结果作为htccheck参数传给后端 3. 公钥还原函数d()的实现 4. 加密算法核心 算法:RSA-OAEP(SHA-256) 优先使用WebCrypto API,回退使用node-forge 两条路径算法保持一致 加密算法逆向步骤 PEM公钥还原: 从data-x去掉分隔符 :: 拼接为连续字符串 整串反转 Base64解码得到标准PEM文本 加密流程: 对明文"1"执行RSA-OAEP(SHA-256)加密 对密文字节进行Base64编码 得到htccheck参数值 脚本实现 0x02 JS加密加盐逆向分析案例 代码结构分析 常量定义(main.min.js) 常量数组存储在b中,通过r(idx)取值: 核心函数分析 1. c()函数 - 回退加载器 检测全局forge.pki是否存在 依次尝试3个CDN动态加载node-forge 成功resolve(true),全部失败reject 2. __ resolvePem()函数 - PEM公钥还原 3. rsaEncryptWithPEM()函数 - 加密主函数 详细加密流程 WebCrypto加密路径(优先) 步骤1:PEM预处理 步骤2:Base64转ArrayBuffer 步骤3:导入公钥 步骤4:明文编码与加密 node-forge回退路径 步骤1:动态加载检测 步骤2:PEM解析与加密 完整调用流程 获取PEM公钥 生成htccheck 其他文件说明 beta.min.js :生成sessionStorage.k1..k3 gamma.min.js :设置window.__ z zeta.min.js :设置window.__ q 注:这些文件主要起混淆作用,与核心加密逻辑无关 0x03 关键技术要点总结 1. 反调试对抗技术 多维度检测调试环境 需要掌握相应的绕过技巧 2. 数据隐藏技术 分隔符插入 字符串反转 Base64编码组合使用 3. 加密算法要点 算法:RSA-OAEP with SHA-256 双路径实现(WebCrypto + node-forge) 加盐处理:明文拼接固定字符串"10086" 4. 逆向分析步骤 识别加密参数(htccheck) 定位加密函数调用 分析公钥获取方式 还原加密算法流程 编写对应加密脚本 5. 脚本开发要点 准确还原PEM公钥获取流程 实现双加密路径兼容 支持参数化输入(不同id值) 通过掌握以上技术要点,可以系统性地分析和逆向JS加密实现,为安全测试和漏洞利用提供技术支撑。