JS混淆
混淆是一种将代码转换为难以理解但仍然保持其功能的过程。
- JS混淆技术主要有以下几种:
- 变量和函数名混淆
- 字符串混淆
- 属性加密
- 控制流平坦化
- 僵尸代码
- 调试保护
- 多态变异
- 锁定域名
- 反格式化
- 特殊编码
OB混淆
OB混淆(Obfuscator) 是一种通过工具(如
javascript-obfuscator)将 JavaScript 代码转换为难以阅读和逆向工程形式的技术。其核心目标是通过复杂化代码结构、隐藏逻辑关系,大幅增加攻击者的分析成本。
- ob混淆的特点:
- 一般由一个大数组或者还有大数组的函数、一个自执行函数、解密函数和加密后的函数四个部分组成
- 函数名和变量名通常以
_0x或者0x开头,后接1~6位数字或字母组合 - 自执行函数进行移位操作,有明显的
push、shift关键字
常用的几种ob混淆方法
本文主要介绍Javascript Obconfusor、Terser、Google Closure Compiler、JShaman四中常用的OB混淆方法,并以演示Javascript Obconfusor为主(当然不是因为懒)
Javascript Obconfusor
Javascript Obconfusor诞生于 2016 年,由俄罗斯开发者 Timofey Kachalov 创建。其初衷是解决前端代码易被逆向工程的问题,尤其适用于金融、政务等高安全需求场景。随着 Web 应用安全威胁的加剧,该工具通过多层混淆机制成为代码保护的行业标杆。官网
下面以如下hi()函数的原代码来演示:
function hi(){
console.log("Hello world");
}
hi();
使用Javascript Obconfusor混淆后(采用网站上的默认参数),进行beautifty得到如下代码:
(function(_0x5c2c3f, _0x569530) {
var _0x4986f3 = _0x509a,
_0x470026 = _0x5c2c3f();
while (!![]) {
try {
var _0x2f7808 = -parseInt(_0x4986f3(0xc2)) / 0x1 * (-parseInt(_0x4986f3(0xc3)) / 0x2) + -parseInt(_0x4986f3(0xc1)) / 0x3 + -parseInt(_0x4986f3(0xba)) / 0x4 * (-parseInt(_0x4986f3(0xb9)) / 0x5) + -parseInt(_0x4986f3(0xbb)) / 0x6 * (parseInt(_0x4986f3(0xc0)) / 0x7) + -parseInt(_0x4986f3(0xc5)) / 0x8 * (parseInt(_0x4986f3(0xbe)) / 0x9) + parseInt(_0x4986f3(0xbc)) / 0xa * (-parseInt(_0x4986f3(0xbd)) / 0xb) + parseInt(_0x4986f3(0xc4)) / 0xc;
if (_0x2f7808 === _0x569530) break;
else _0x470026['push'](_0x470026['shift']());
} catch (_0x4f8edb) {
_0x470026['push'](_0x470026['shift']());
}
}
}(_0x49ff, 0x2c517));
function hi() {
var _0x43b1cc = _0x509a;
console['log'](_0x43b1cc(0xbf));
}
hi();
function _0x509a(_0x36eff7, _0x502dd9) {
var _0x49ffc8 = _0x49ff();
return _0x509a = function(_0x509ae5, _0x21b3b2) {
_0x509ae5 = _0x509ae5 - 0xb9;
var _0x2de676 = _0x49ffc8[_0x509ae5];
return _0x2de676;
}, _0x509a(_0x36eff7, _0x502dd9);
}
function _0x49ff() {
var _0x3f1f96 = ['4344uzHEdl', '10DqfmiX', '3366033zgDIbh', '1290501cenYHg', 'Hello\x20world', '3395GLvJNk', '160749sYIEuH', '23386inwzbS', '6maggcZ', '10548000ZoLwRp', '8EGWNGi', '5IaWZEW', '345936ABpjqw'];
_0x49ff = function() {
return _0x3f1f96;
};
return _0x49ff();
}
采用前面介绍的ob混淆后函数的组成对混淆后的代码进行分析:
- 混淆后我们从原来的一个函数得到了上述所示的四个函数
- 其中第一个函数包含
while(!![])等循环结构,以及对大数组的移位操作push、shift等,显然他就是自执行函数 - 第二个函数显然就是加密后的主函数
- 第三个函数在多处均有调用传入十六进制数,显然他就是解密函数
- 第四个函数有一个明显的
大数组,显然它就是大数组函数
- 其中第一个函数包含
- 以上,我们就大致可以了解javascript obconfusor混淆后的函数是长什么样的
Terser
Terser是 UglifyJS 的进化版,发布于 2018 年,专注于代码压缩和性能优化。作为现代构建工具(如 Webpack、Vite)的默认压缩器,其处理速度比传统工具快 3 倍以上。官网
Google Closure Complier
Google Closure Complier由 Google 于 2009 年开源,最初用于优化 Gmail 和 Google Maps 的 JS 代码。基于 Java 实现,提供工业级深度优化能力。官网
JShaman
JShaman 是一款专注于 JavaScript 代码混淆与加密 的商业级工具,诞生于中国并在国际范围内广泛使用(支持中英文版本及多国语言界面)2。其主要目标是保护代码安全,防止逆向工程、代码盗用及恶意篡改,适用于前端 JS、H5 应用、Node.js 后端及微信/支付宝小程序等场景。官网
实战
本案例对某电商平台的进行jjs逆向并获取到目标数据项
-
访问目标网址,在网络中查看
Fetch/xhr一栏(没有返回数据刷新一下),随机选择一项作为我们的实验对象。这里我们选择第一项GetPageList,经分析得到以下结论:- 该请求为POST请求
- 请求参数都经过算法加密
- 返回值也是加密值
-
很显然,我们需要通过js逆向找出POST请求参数的加密函数和响应的解密函数


-
接下来我们就进行js逆向来到源代码页面设置
xhr断点

-
刷新页面后,开发者工具就成功拦截到了我们想要跟踪的页面,通过步步跟栈,我们找到了请求参数所在地,这里可以简单看出这些奇奇怪怪的参数名和函数名正是前面所说的
OB混淆,那么接下来的任务就很简单了

-
我们从上到下一一设置断点调试,找到涉及到的代码,补全我们的js代码。整体过程比较枯燥乏味,最终我得到了大约5000行代码。

-
写好接口,通过简单的python爬虫代码调用完即可,最终效果如下:

-
总结下来就是
- 确认目标,分析并确认目标请求参数
- 设置xhr断点拦截目标请求,通过跟栈+设置断点调试找到目标参数
- 步步断点调试,找到目标代码
- 扣下代码,加入自己的js逆向代码当中,基本上只需要在最后写下接口函数就可以了,其他代码基本与原网站一致
- 写好python代码,调用js逆向代码提供的接口,向目标网站发送请求,拿到目标数据
- 将目标数据传入解密函数,得到解密后的参数
3144

被折叠的 条评论
为什么被折叠?



