kareemheshaam/jsunveil

GitHub: kareemheshaam/jsunveil

一款基于模式识别的 JavaScript 反混淆工具,通过沙箱执行解码器并利用 AST 变换恢复 obfuscator.io 风格字符串数组混淆中的原始字符串。

Stars: 0 | Forks: 0

# jsunveil 一个小巧的、基于模式的反混淆工具,专为受**字符串数组(字符串表)混淆**保护的 JavaScript 设计——这类混淆由 `obfuscator.io` 等工具及基于相同理念构建的众多引擎生成(旋转的字符串数组、通过单一解码器路由所有字面量、诱饵/死代码,以及每次构建时随机生成的标识符)。 它**不**针对任何特定的网站或样本。它攻击的是*技术*本身,因此当受保护的脚本使用全新的名称、新的字母表和不同的旋转偏移量重新生成时,同一工具依然有效。 ## 功能介绍 给定一个混淆过的 `.js` 文件,`jsunveil` 将: 1. **定位字符串数组及其解码器**(每个字面量都会经过的 `f(idx)`),以及在加载时应用的旋转步骤。 2. **重建明文字符串映射表**,只需在密封的沙箱中运行数组和解码器即可——绝不运行完整程序。 3. **在 AST 层面内联所有解码器调用**(`_d(0x1f) → "deviceMemory"`),使用 Babel 实现。 4. **剥离常见的诱饵**——逗号操作符无操作、死 `if (false)` 分支以及自保护包装器——并重新输出易读、格式化的 JS。 它适用于构建生成的任何解码器,因为它是在沙箱中实时运行该解码器,而不是手动重新实现各种字符串方案(base91、自定义 base-N、rotate/XOR 等)。 ## 为什么是“基于模式,而非基于样本” 字符串数组混淆器在每次构建时都会随机化其*表层结构*——标识符名称、字母表、旋转偏移量、诱饵位置——但其*结构*是稳定的:总是有一个字符串数组,总是有一个单一解码器,总是有一个旋转。`jsunveil` 依赖于这种结构(形态和调用模式),因此它能在重新生成后继续工作,而不会在下一次下载时就失效。 ## 安装 ``` git clone https://github.com/kareemheshaam/jsunveil cd jsunveil npm install ``` 需要 Node 18+。 ## 用法 ``` # 反混淆文件 node src/cli.js examples/obfuscated.sample.js -o clean.js # 仅 dump 恢复的 string map(非常适合 triage) node src/cli.js examples/obfuscated.sample.js --strings ``` 编程方式调用: ``` const { deobfuscate } = require('./src'); const clean = deobfuscate(fs.readFileSync('input.js', 'utf8')); ``` ## 工作原理(简述) 这类混淆的难点在于解码器本身就*在*文件中,但与其它所有内容纠缠在一起。诀窍在于提取并**仅**在隔离环境中运行解码器,这样你就可以在不执行 payload 的情况下,获取每一个索引对应的值: ``` // Pull the string array + decoder out, run them in a sandbox, map every index. const vm = require('vm'); const sandbox = {}; vm.createContext(sandbox); vm.runInContext(arrayAndDecoderSource, sandbox, { timeout: 1000 }); const map = {}; for (let i = 0; i < sandbox.__arr.length; i++) map[i] = sandbox.__decode(i); ``` 接下来就是普通的 Babel 处理流程:用映射表替换 `decoder(idx)` 字面量,丢弃诱饵,然后输出。 请参阅[详细文章](https://medium.com/@kareem.hesham/i-spent-a-week-inside-a-top-tier-web-anti-bot-stack-heres-what-i-found-4d8b67166f07)了解完整内幕,包括无头执行方面的内容(在 Node 中伪装足够多的浏览器环境以运行指纹挑战)。 ## 适用范围与局限性 - 针对的是**字符串数组 / 字符串表**混淆。它*不是*通用的 VM-devirtualizer(虚拟机去虚拟化工具);控制流平坦化的 VM 需要不同的方法。 - 输出结果旨在供**阅读**,不一定能重新运行——内联字符串和剥离自保护代码会改变运行时的行为,这是设计使然。 - 仓库中内置的 `examples/obfuscated.sample.js` 是由一个使用公共混淆器处理的一次性代码片段生成的——本仓库中没有任何特定于供应商的内容。 ## 许可证 MIT — 查看 [LICENSE](LICENSE)。
标签:Babel, CMS安全, JavaScript, MITM代理, 代码分析, 代码反混淆, 凭证管理, 数据可视化, 自定义脚本