文章目录
前言
JavaScript 压缩、混淆和加密技术
对于网页来说,其逻辑是依赖于JavaScript来实现的,JavaScript 有如下特点:
- JavaScript 代码运行于客户端,也就是它必须要在用户浏览器端加载并运行。
- JavaScript 代码是公开透明的,也就是说浏览器可以直接获取到正在运行的 JavaScript 的源码。
声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除,请各位自觉遵守相关法律法规。
一. JS简介
压缩、混淆、加密技术简述如下
- 代码压缩:即去除JavaScript 代码中的不必要的空格、换行等内容,使源码都压缩为几行内容,降低代码可读性,当然同时也能提高网站的加载速度。
- 代码混淆:使用变量替换、字符串阵列化、控制流平坦化、多态变异、僵尸函数、调试保护等手段,使代码变得难以阅读和分析,达到最终保护的目的。但这不影响代码原有功能。是理想、实用的JavaScript保护方案
- 代码加密:可以通过某种手段将 JavaScript 代码进行加密,转成人无法阅读或者解析的代码,如将代码完全抽象化加密,如 eval 加密。另外还有更强大的加密技术,可以直接将 JavaScript 代码用 C/C++ 实现,JavaScript 调用其编译后形成的文件来执行相应的功能,如Emscripten 还有 WebAssembly。
二. OB混淆
OB 混淆全称 Obfuscator,Obfuscator 其实就是混淆的意思
官方文档:https://obfuscator.io/
作者是一位叫 Timofey Kachalov 的俄罗斯JavaScript开发工程师,早在 2016 年就发布了第一个版本。
1. OB混淆特征
- 1、一般由一个大数组或者含有大数组的函数、一个自执行函数、解密函数和加密后的函数四部分组成;
- 2、函数名和变量名通常以 _0x 或者 0x 开头,后接 1~6 位数字或字母组合;
- 3、自执行函数,进行移位操作,有明显的 push、shift 关键字;
例如在上面的例子中,_0x3f26() 方法就定义了一个大数组,自执行函数里有 push、shift 关键字,主要是对大数组进行移位操作,_0x1fe9() 就是解密函数,hi() 就是加密后的函数。
2. OB混淆介绍
JavaScript 混淆完全是在 JavaScript 上面进行的处理,它的目的就是使得 JavaScript 变得难以阅读和分析,大大降低代码可读性,是一种很实用的 JavaScript 保护方案。
JavaScript 混淆技术主要有以下几种:
- 变量混淆
将带有含意的变量名、方法名、常量名随机变为无意义的类乱码字符串,降低代码可读性,如转成单个字符或十六进制字符串。
- 字符串混淆
将字符串阵列化集中放置、并可进行 MD5 或 Base64 加密存储,使代码中不出现明文字符串,这样可以避免使用全局搜索字符串的方式定位到入口点。
- 属性加密
针对 JavaScript 对象的属性进行加密转化,隐藏代码之间的调用关系。
- 控制流平坦化
打乱函数原有代码执行流程及函数调用关系,使代码逻变得混乱无序。
- 僵尸代码
随机在代码中插入无用的僵尸代码、僵尸函数,进一步使代码混乱。
- 调试保护
基于调试器特性,对当前运行环境进行检验,加入一些强制调试 debugger 语句,使其在调试模式下难以顺利执行 JavaScript 代码。
- 多态变异
使 JavaScript 代码每次被调用时,将代码自身即立刻自动发生变异,变化为与之前完全不同的代码,即功能完全不变,只是代码形式变异,以此杜绝代码被动态分析调试。
- 锁定域名
使 JavaScript 代码只能在指定域名下执行。
- 反格式化
如果对 JavaScript 代码进行格式化,则无法执行,导致浏览器假死。
- 特殊编码
将 JavaScript 完全编码为人不可读的代码,如表情符号、特殊表示内容等等。
总之,以上方案都是 JavaScript 混淆的实现方式,可以在不同程度上保护 JavaScript 代码。
3.OB混淆JS模块
在前端开发中,现在 JavaScript 混淆主流的实现是 javascript-obfuscator 这个库,利用它我们可以非常方便地实现页面的混淆,它与 Webpack 结合起来,最终可以输出压缩和混淆后的 JavaScript 代码,使得可读性大大降低,难以逆向。
下面我们会介绍下 javascript-obfuscator 对代码混淆的实现,了解了其实现,那么自然我们就对混淆的机理有了更加深刻的认识。
官方文档:https://obfuscator.io/
它是支持 ES8 的免费、高效的 JavaScript 混淆库,它可以使得你的 JavaScript 代码经过混淆后难以被复制、盗用,混淆后的代码具有和原来的代码一模一样的功能。
怎么使用呢?首先,我们需要安装好 Node.js,可以使用 npm 命令。
然后新建一个文件夹,比如 js-obfuscate,随后进入该文件夹,初始化工作空间:
npm init
提示我们输入一些信息,创建一个 package.json 文件,这就完成了项目初始化了。
接下来我们来安装 javascript-obfuscator这个库:
npm install javascript-obfuscator -g
安装完成后,javascript-obfuscator就是一个独立的可执行命令了。
接下来我们就可以编写代码来实现混淆了
1. 代码压缩
这里javascript-obfuscator也提供了代码压缩的功能,使用其参数 compact即可完成JavaScript 代码的压缩,输出为一行内容。默认是 true,如果定义为 false,则混淆后的代码会分行显示。
var code = `
let x = '1' + 1
console.log('x', x)
`
const options = {
compact: true, // 代码压缩配置
}
const obfuscator = require('javascript-obfuscator')
function obfuscate(code, options) {
return obfuscator.obfuscate(code, options).getObfuscatedCode()
}
console.log(obfuscate(code, options))
2. 变量名混淆
变量名混淆可以通过配置identifierNamesGenerator 参数实现,我们通过这个参数可以控制变量名混淆的方式,如hexadecimal则会替换为 16 进制形式的字符串,在这里我们可以设定如下值:
- hexadecimal:将变量名替换为 16 进制形式的字符串,如 0xabc123。
- mangled:将变量名替换为普通的简写字符,如 a、b、c 等。
该参数默认为hexadecimal。
我们将该参数修改为 mangled 来试一下:
const code = `
let hello = '1' + 1
console.log('hello', hello)
`
const options = {
compact: true,
identifierNamesGenerator: 'mangled'
}
3 字符串混淆
字符串混淆,即将一个字符串声明放到一个数组里面,使之无法被直接搜索到。我们可以通过控制 stringArray 参数来控制,默认为 true。
const code = `
var a = 'hello world'
`;
const options = {
compact: false,
unicodeEscapeSequence: true //对字符串进行 Unicode 转码
};
三. 实战案例分析
1. 混淆专题逆向
- 逆向目标:极简壁纸
- 逆向思路:
进行抓包
发现预览响应部分有加密数据
然后进行抓包,发现该网站有JS混淆,对其进行parse hook技术
获取到所需要的密文params,继续下一步到明文,然后挨个看其启动器
获取到可疑位置
_0x5bb208 || 0x0 != _0x3c6b83['data']['code'] || (_0x3c6b83['data']['result'] = JSON['parse'](_0xf79b3e['a']['decipher'](_0x3c6b83['data']['result'])))
分析一下这一部分(该部分即为所需的图片id部分)
JSON['parse'](_0xf79b3e['a']['decipher'](_0x3c6b83['data']['result']))
通过控制台
_0x3c6b83['data']['result'] 部分为响应部分的result密文内容
所以对前一部分推测:_0xf79b3e['a']['decipher']为加解密部分
function _0x563330(_0x1e29f9) {
// return _0x3ed467(_0x4207c2(_0x1e29f9));
return _0x3ef903(_0x3ed467(_0x4207c2(_0x1e29f9)));
}该部分为需要解决的JS逆向部分
然后对该部分进行扣JS即可
结果展示:
2. octet-stream类型混淆破解
- 逆向目标:产业政策大数据平台
- 逆向参数:载荷参数加密
进入之后,发现有无限debugger,先用hook过debugger
该位置为请求拦截器位置
找到该请求拦截器中的载荷参数加密部分
对该部分进行JS逆向即可
最后结果展示
参考文档:
https://blog.csdn.net/weixin_38819889/article/details/107188552
写在最后:
本人写作水平有限,如有讲解不到位或者讲解错误的地方,还请各位大佬在评论区多多指教,共同进步.如有需要代码和讲解交流,可以加本人微信18847868809