1.简介
使用变量替换、字符串阵列化、控制流平坦化、多态变异、僵尸函数、调试保护等手段,使代码变得难以阅读和分析,达到最终保护的目的。但这不影响代码原有功能。是理想、实用的JavaScript
保护方案。
对于网站来讲,混淆可以保护代码,防爬虫,但性能会降低。
2.ob混淆
工具网站:JavaScript Obfuscator Tool在线摩尔斯电码加密解密工具 - 图灵工具 在线工具系统JavaScript Obfuscator Tool
2.1.ob混淆的特点
-
一般由一个大数组或者含有大数组的函数、一个自执行函数、解密函数和加密后的函数四部分组成;
-
函数名和变量名通常以
_0x
或者0x
开头,后接 1~6 位数字或字母组合; -
自执行函数,进行移位操作,有明显的 push、shift 关键字
比如混淆之前的代码
// Paste your JavaScript code here
function hi() {
console.log("Hello World!");
}
hi();
混淆之后的代码
function _0x2e20() {
var _0x4a4b81 = ['Hello\x20World!', 'log', '767060iWdlRO', '2MYcNod', '4294960gKJyUV', '2056910siDDMq', '12pRRfSJ', '7034786jSFnEP', '290166eWoTCu', '740892HKcgVO', '18dLCrrz', '6168JMXYpC', '6gwNByF', '8624hTMxHT'];
_0x2e20 = function () {
return _0x4a4b81;
};
return _0x2e20();
}
(function (_0x138cb3, _0x354c39) {
var _0x48b690 = _0x1c61, _0x31a626 = _0x138cb3();
while (!![]) {
try {
var _0x3d00d0 = parseInt(_0x48b690(0x14e)) / 0x1 * (-parseInt(_0x48b690(0x14f)) / 0x2) + -parseInt(_0x48b690(0x154)) / 0x3 + -parseInt(_0x48b690(0x155)) / 0x4 + parseInt(_0x48b690(0x151)) / 0x5 * (parseInt(_0x48b690(0x158)) / 0x6) + -parseInt(_0x48b690(0x159)) / 0x7 * (-parseInt(_0x48b690(0x157)) / 0x8) + -parseInt(_0x48b690(0x156)) / 0x9 * (-parseInt(_0x48b690(0x150)) / 0xa) + -parseInt(_0x48b690(0x153)) / 0xb * (parseInt(_0x48b690(0x152)) / 0xc);
if (_0x3d00d0 === _0x354c39) break; else _0x31a626['push'](_0x31a626['shift']());
} catch (_0x2d435b) {
_0x31a626['push'](_0x31a626['shift']());
}
}
}(_0x2e20, 0x81d03));
function _0x1c61(_0x1797c0, _0x1bb9be) {
var _0x2e2025 = _0x2e20();
return _0x1c61 = function (_0x1c61ca, _0x46e97d) {
_0x1c61ca = _0x1c61ca - 0x14e;
var _0x3e613f = _0x2e2025[_0x1c61ca];
return _0x3e613f;
}, _0x1c61(_0x1797c0, _0x1bb9be);
}
function hi() {
var _0x53381b = _0x1c61;
console[_0x53381b(0x15b)](_0x53381b(0x15a));
}
hi();
2.2.大数组或包含数组的函数
2.3.自执行函数
作用把大数组进行打乱
2.4.解密函数
对数据进行还原
除此之外还有
真实代码,垃圾代码
3.混淆技术总结
1.变量混淆 将带有含意的变量名、方法名、常量名随机变为无意义的类乱码字符串,降低代码可读性,如转成单个字符或十六进制字符串。
2.字符串混淆 将字符串阵列化集中放置、并可进行 MD5 或 Base64 加密存储,使代码中不出现明文字符串,这样可以避免使用全局搜索字符串的方式定位到入口点。
3.属性加密 针对 JavaScript 对象的属性进行加密转化,隐藏代码之间的调用关系。
4.控制流平坦化 打乱函数原有代码执行流程及函数调用关系,使代码逻变得混乱无序。
5.僵尸代码 随机在代码中插入无用的僵尸代码、僵尸函数,进一步使代码混乱。
6.调试保护 基于调试器特性,对当前运行环境进行检验,加入一些强制调试 debugger 语句,使其在调试模式下难以顺利执行 JavaScript 代码。
7.多态变异 使 JavaScript 代码每次被调用时,将代码自身即立刻自动发生变异,变化为与之前完全不同的代码,即功能完全不变,只是代码形式变异,以此杜绝代码被动态分析调试。可以采用替换文件方法。
8.锁定域名 使 JavaScript 代码只能在指定域名下执行。
9.反格式化 如果对 JavaScript 代码进行格式化,则无法执行,导致浏览器假死。可以对代码进行压缩。
10.特殊编码 将 JavaScript 完全编码为人不可读的代码,如表情符号、特殊表示内容等等。
4.JS代码实现JS混淆
const JavaScriptObfuscator = require('javascript-obfuscator');
const sourceCode = `
function myFunction() {
var myVariable = 'Hello, World!';
console.log(myVariable);
}
myFunction();
`;
const options = {
compact: true, // 启用压缩
controlFlowFlattening: true, // 控制流 平坦化
controlFlowFlatteningThreshold: 0.75, // 控制流平坦化阈值
deadCodeInjection: true, // 使死代码注入
deadCodeInjectionThreshold: 0.4, // 死代码注入阈值
identifierNamesGenerator: 'hexadecimal', // 生成标识符的方式
log: false, // 关闭日志
rotateStringArray: true, // 旋转字符串数组
selfDefending: true, // 启用自我防御
stringArray: true, // 启用字符串数组
stringArrayThreshold: 0.75, // 字符串数组阈值
// domainLock: ['example.com'], // 锁定域名
debugProtection: true, // 调试保护
disableConsoleOutput: true, // 禁用控制台输出
unicodeEscapeSequence: false, // 禁用 Unicode 转义序列
rotateUnicodeArray: true, // 旋转 Unicode 数组
};
const obfuscatedCode = JavaScriptObfuscator.obfuscate(sourceCode, options).getObfuscatedCode();
console.log(obfuscatedCode);
吹一下,我的毕设就有一个JS混淆的功能,上传cursor直接生成前后端 再修修改改,感兴趣的人可以自行研究哈。
5.案例
很多加密的位置
关键字搜索
跟栈也不难,没有异步
本案例以content值为例
进入函数
发现一个参数作函数,另一个参数作函数的参数 ,注意,跟栈时时常出现这种情况,一般会嵌套好几层。
这个参数明显是载荷,翻页用的
第一步先拿核心数据,Content
很明显_0x595165这个是函数,
即可以转成这样
进入函数内部,是一个标准的AES加密
扣下来
报错定位,接下来就是扣代码
发现环境补完了还是报错
打断点进行调试
发现网页是enc,自己的环境是乱码
已知扣代码扣了大数组,差自执行重构函数,和解密函数。
然后搜索大数组变量,找到两个函数,然后就过了。
最后差两个个值
全局搜索,发现在html页面上qccppm
此网页每次刷新 qccppm会更新,所以得先请求页面获取qccppm分割,然后传入接口在请求接口数据。
最后得出
总结:
JS混淆环境扣代码,注意三个函数,大数组函数,重构函数,解密函数。