【JS逆向系列】ob混淆

5,972 阅读2分钟

项目场景:

写了好几篇JS逆向的文章,作为一名热爱爬虫的工作者,想必一定会接触到JS混淆,JS混淆有很多种,这里举几个:UglifyJS,JScrambler,jsbeautifier.org,JSDetox,obfuscator.io 等,具体的大家可以看看这篇文章 blog.csdn.net/hefeng6500/…,既然能混淆JS,那么就会有反混淆的方法,这次给大家带来obfuscator(ob)混淆的入门级解密。


解决方案:


1.这里贴一个obfuscator混淆的网站,访问页面可以看到下面的一个例子。

在这里插入图片描述

2.就用他默认的JS代码,看看混淆后的样子,变量跟方法名已经完全替换,然后第一行可以看到明显的一个数组,这就是ob混淆的常见特性。
var _0x30bb = ['log', 'Hello\x20World!'];

(function (_0x38d89d, _0x30bbb2) {
    var _0xae0a32 = function (_0x2e4e9d) {
        while (--_0x2e4e9d) {
            _0x38d89d['push'](_0x38d89d['shift']());
        }
    };
    _0xae0a32(++_0x30bbb2);
}(_0x30bb, 0x153));

var _0xae0a = function (_0x38d89d, _0x30bbb2) {
    _0x38d89d = _0x38d89d - 0x0;
    var _0xae0a32 = _0x30bb[_0x38d89d];
    return _0xae0a32;
};

function hi() {
    console[_0xae0a('0x1')](_0xae0a('0x0'));
}

hi();

3.先看下混淆后代码整体结构,总体围绕_0x30bb 这个数组变量,先进行移位操作(明显的shift),_0xae0a是hi()方法内调用的解密函数。

在这里插入图片描述

4.我们先看看移位后的数组,直接扣代码放在浏览器的Console执行下

在这里插入图片描述

5.OK,我们得到了移位后的数组,然后有了现成的解密方法,我们只要一次执行hi()方法里带_0xae0a的解密函数,即可还原出原来的数据,那么,这里,一个一个执行是不可能的,写个代码让他自动替换,代码直接贴出来
# -*- coding: utf-8 -*-
'''
无法100%还原为源代码,只能修改变量和方法名,增加可读性
'''
import re
import execjs

func_js = """
// 直接用重组后的数组替换原来的数组
var _0x30bb = ["Hello World!", "log"]

// 解混淆用到的函数
var _0xae0a = function (_0x38d89d, _0x30bbb2) {
    _0x38d89d = _0x38d89d - 0x0;
    var _0xae0a32 = _0x30bb[_0x38d89d];
    return _0xae0a32;
};
"""

# 1.编译解混淆函数到node.js环境中
js_func_name = '_0xae0a'  # 混淆js中函数定义的名称
ctx = execjs.compile(func_js)
# 2.正则匹配出所有需要替换的函数
with open('source.js') as f1:
    js = f1.read()

be_replaced_func_set = set(re.findall(js_func_name + "\([\s\S]+?\)",js))

print(be_replaced_func_set)
# 3.循环遍历进行替换
for be_replaced_func in be_replaced_func_set:
    args_tuple = re.findall("\(([\s\S]+?)\)", be_replaced_func)[0]
    args0 = eval(args_tuple.split(',')[0]) # 截取参数

    res = ctx.call(js_func_name, args0) # 调用参数,获取返回值
    js = js.replace(be_replaced_func, "'" + res + "'")
    print('{} 替换完成'.format(res))

with open('code.js', 'w') as f2: # 重写JS输出
    js = f2.write(js)


6.然后我们Run一下,看下解密后的hi()函数和原来的对比下,大致就完成了!
# 解密后
function hi() {
    console['log']('Hello World!'); # 等价于console.log('Hello World!')
}hi();

# 解密前
function hi() {
  console.log("Hello World!");
}
hi();

在这里插入图片描述