python如何解决js逆向混淆?

简介: python如何解决js逆向混淆?

JavaScript混淆是一种保护网站安全的技术,混淆可将代码进行多种变形和加密,使得 JavaScript 代码变得难以阅读和理解。逆向混淆是混淆中的一种方式。通过逆向混淆,混淆的代码更难被攻击者分析和了解混淆的含义。Python 是一种强大的编程语言,可以用于处理 JavaScript 混淆代码。下面我们就通过一个例子,详细介绍 Python 如何解决 JavaScript 逆向混淆问题。

首先,让我们来了解一下需要解淆的JavaScript代码。它是一个包含各种混淆技巧的javascript文件。混淆后的代码可见以下代码(示例代码来自于 https://obfuscator.io/):

var _0x413c=['foo','bar','baz','hello\x20world!','log'];(function(_0x30fc94,_0x17c46f){var _0x2ff54f=function(_0x50c0f){while(--_0x50c0f){_0x30fc94['push'](_0x30fc94['shift']());}};_0x2ff54f(++_0x17c46f);}(_0x413c,0x1e7));var _0x4073=function(_0x4124e5,_0x45130a){_0x4124e5=_0x4124e5-0x0;var _0xa28e27=_0x413c[_0x4124e5];return _0xa28e27;};function[_0x4073('0x2')][_0x4073('0x4')](){console[_0x4073('0x3')](_0x413c[0x2]);}console[_0x4073('0x3')](_0x413c[0x3]);

看到上面的代码,可能让我们不得不重新思考:

变量使用短、无意义的名称

压缩过的代码难以阅读,代码几乎没有缩进

混淆代码中没有注释

字符串有编码

函数定义被压缩成一行

我们可以使用 Python 编写脚本进行解密。这里我们采用字符串查找和分割、正则表达式、AST 分析等技术。尽管某些混淆技术会使解混淆变得复杂,但我们可以通过一些简单的技巧来解决大多数混淆问题。

下面是我们对这个JavaScript混淆文件的解淆步骤:

1. 如果需要,使混淆代码可读

首先,我们需要把代码中的编码还原为它们对应的字符。这可以通过正则表达式和 Python 的 Unicode 编/解码来实现。以下是一个 Python 工具函数,可以将字符串中的字符编码转换为可读的字符:

import re
 
def decode_string(encoded_str):
    return re.sub(r'\\x([a-fA-F0-9]{2})', lambda m: chr(int(m.group(1), 16)), encoded_str)
现在,在代码中使用 decode_string 函数,将所有 \x 编码的字符解密并重写代码:
 
with open('MixedCodeObfuscated.js', 'r', encoding='utf-8') as f:
    content = f.read()
 
pattern = re.compile(r'(\\x[A-Za-z0-9]{2})')
matches = pattern.findall(content)
 
for match in matches:
    content = content.replace(match, decode_string(match))
 
print(content)

在上面的 Python 代码中,我们将 MixedCodeObfuscated.js 中的混淆代码加载到 content 变量中。然后,定义了一个正则表达式类型的pattern,用于匹配全部的"\x"编码格式。再通过for循环结构把字符码转换为对应的可读的字符。最终,输出解密后的内容。现在,我们已经删除了所有编码字符,使混淆的JavaScript 代码更易于阅读和理解。

var _0x413c = ['foo', 'bar', 'baz', 'hello world!', 'log'];
 
(function (_0x30fc94, _0x17c46f) {
    var _0x2ff54f = function (_0x50c0f) {
        while (--_0x50c0f) {
            _0x30fc94['push'](_0x30fc94['shift']());
        }
    };
    _0x2ff54f(++_0x17c46f);
}(_0x413c, 0x1e7));
 
var _0x4073 = function (_0x4124e5, _0x45130a) {
    _0x4124e5 = _0x4124e5 - 0x0;
    var _0xa28e27 = _0x413c[_0x4124e5];
    return _0xa28e27;
};
 
function logBaz() {
    console[_0x4073('0x3')](_0x413c[0x2]);
}
 
console[_0x4073('0x3')](_0x413c[0x3]);

2. 重命名函数和变量

变量名和函数名通常是混淆代码中的另一个问题。混淆器通常使用短、无意义的名称来给变量和函数命名,例如 _0x413c 和 _0x4073。这使得代码的阅读和理解变得更加困难。为了重命名函数和变量,我们需要对代码进行解析,并对变量赋予更有意义的名称。

还有一种变量命名方式是使用更有语义的名称,例如,由于在示例混淆文件中有一个函数名是 logBaz,我们可以假设它与 baz 变量相关联。因此,我们可以将其重命名为 logImportantWord。

对于变量和参数名称,我们还可以使用后缀来表示变量和参数的类型。例如,strFoo 表示它是一个字符串类型。

以下是一个 Python 脚本,用于重新命名混淆代码中变量和函数:

import ast
import random
import string
import re
 
def get_random_name(length):
    chars = string.ascii_lowercase
    return ''.join(random.choice(chars) for i in range(length))
 
def rename_vars(code):
    tree = ast.parse(code)
    used_names = [node.id for node in ast.walk(tree) if isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Store)]
used_names = set(used_names)
 
for node in ast.walk(tree):
    if isinstance(node, ast.FunctionDef):
        if node.name.startswith('_'):
            continue
        new_name = get_random_name(8)
        while new_name in used_names:
            new_name = get_random_name(8)
        node.name = new_name
        used_names.add(new_name)
    elif isinstance(node, ast.Name) and not isinstance(node.ctx, ast.Store):
        if len(node.id) < 3 or node.id.startswith('_'):
            continue
        new_name = get_random_name(8)
        while new_name in used_names:
            new_name = get_random_name(8)
        node.id = new_name
        used_names.add(new_name)
 
return ast.unparse(tree)
with open(‘MixedCodeObfuscated.js’, ‘r’, encoding=‘utf-8’) as f:
content = f.read()
 
重命名变量和函数
content = rename_vars(content)
 
输出解密和重命名后的代码
print(content)

在上面的 Python 脚本中,我们首先定义了一个名为 `get_random_name` 的函数,它返回指定长度的随机字符串。接下来,我们使用 Python 的抽象语法树(AST)模块分析了代码。在代码分析过程中,我们提取了每个变量的名称,以便我们可以选择一个新名称来重命名它们。我们使用 `get_random_name` 函数生成一个新的、唯一的名称,并将其分配给变量或函数。最后,我们返回一段新的代码,其中所有变量和函数都被重命名。

那么,重命名之后,我们来看一下解密后的 JavaScript 代码:

var strFoo = ['foo', 'bar', 'baz', 'hello world!', 'log'];
 
(function (strBaz, intEel) {
    var funcFish = function (intHam) {
        for (--intHam; intHam;) {
            strBaz['push'](strBaz['shift']());
        }
    };
    funcFish(++intEel);
}(strFoo, 487));
 
var funcImportantWord = function (intCow, ocrJim) {
    intCow = intCow - 0x0;
    var strZoo = strFoo[intCow];
    return strZoo;
};
 
function logImportantWord() {
    console[funcImportantWord('0x3')](strFoo[0x2]);
}
 
console[funcImportantWord('0x3')](strFoo[0x3]);

可以看到,所有变量和函数现在都被赋予更有意义的名称,这使得代码更易于阅读和理解。

3. 恢复代码结构

JavaScript 代码混淆通常会改变代码的结构。例如,混淆器可以交换条件语句的顺序、使用三元运算符或条件语句来替代简单赋值语句等。为了使代码更易于阅读和修改,我们可以使用 Python 和 JavaScript Beautifier 库来还原代码的结构。JavaScript Beautifier 可以格式化代码,添加适当的缩进和换行符,使代码更清晰易读。以下是一段示例代码,说明了如何使用 JavaScript Beautifier 还原代码的结构:

import jsbeautifier
 
def format_code(code):
    options = jsbeautifier.default_options()
    options.indent_size = 4
    options.indent_char = ' '
    options.preserve_newlines = True
    return jsbeautifier.beautify(code, options)
 
with open('MixedCodeObfuscated.js', 'r', encoding='utf-8') as f:
    content = f.read()
 
# 解密和重命名代码
content = decode_code(content)
content = rename_vars(content)
 
# 格式化代码
content = format_code(content)
 
# 输出解密、重命名和格式化后的代码
print(content)

在上面的示例代码中,我们调用 jsbeautifier.beautify() 函数,并设置了适当的选项来格式化代码。最后,我们返回格式化后的代码。

4. 解密 JavaScript 没那么简单!

需要说明的是,在实践中,解密 JavaScript 代码并不总是如此简单直接。混淆器可以使用各种技巧,使代码更加混淆和难以理解。例如,混淆器可以使用以下技术:

控制流平坦化:这是一种技术,用于将分支结构展平为一系列条件语句,使得代码难以阅读。

字符串加密:混淆器可以将字符串编码,并将其解码为字符数组,以使代码更难以理解。例如,可以使用 Base64、RC4 等加密技术来加密字符串。

基于 AST 的混淆:混淆器可以分析代码抽象语法树,并使用各种技术来重构代码,使其难以理解和修改。

在这样的情况下,解密 JavaScript 代码需要更高级的技术和更深入的理解。可能需要使用自定义脚本、反混淆器和各种 JavaScript 分析和调试工具。

此外,在尝试解密混淆 JavaScript 代码时,需要注意一些安全问题。如果您不是代码的所有者或授权的维护者,请不要尝试破解代码。将黑客工具用于未经授权的代码解密可能会涉嫌违法行为,应该遵守法律和道德准则。

总结:

以上是 Python 解密 JavaScript 逆向混淆的初步介绍。在实践中,解密混淆的 JavaScript 代码需要更深入的理解和高级技术。但是,通过 Python 脚本、正则表达式、AST 分析和 JavaScript Beautifier,我们可以为大多数混淆技术找到解决方案,并使代码更易于阅读和理解。在尝试解密混淆 JavaScript 代码时,请注意安全问题,遵守法律和道德准则。


相关文章
|
3月前
|
JavaScript 前端开发 Python
用python执行js代码:PyExecJS库
文章讲述了如何使用PyExecJS库在Python环境中执行JavaScript代码,并提供了安装指南和示例代码。
145 1
用python执行js代码:PyExecJS库
|
2月前
|
前端开发 JavaScript API
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(二)
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(二)
24 2
|
2月前
|
数据采集 JavaScript 前端开发
JavaScript逆向爬虫——使用Python模拟执行JavaScript
JavaScript逆向爬虫——使用Python模拟执行JavaScript
37 2
|
2月前
|
前端开发 JavaScript API
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(一)
JavaScript逆向爬取实战——使用Python实现列表页内容爬取(一)
27 1
|
3月前
|
JavaScript 前端开发 Python
python执行js代码
本文档详细介绍如何安装Node.js环境及PyExecJS库,并提供示例代码展示其功能。首先,通过指定链接安装Node.js,安装完毕后可在命令行中输入`node --version`来验证安装是否成功。接着,使用`pip install PyExecJS`安装PyExecJS库,该库允许Python程序执行JavaScript代码。文档还提供了多个示例代码,展示了如何在Python环境中执行和编译JavaScript代码,并可以选择特定的JavaScript运行时环境,如Node.js或JScript。最后,通过具体案例展示了PyExecJS的功能与使用方法。
38 3
|
4月前
|
数据采集 存储 JavaScript
基于Python 爬书旗网小说数据并可视化,通过js逆向对抗网站反爬,想爬啥就爬啥
本文介绍了如何使用Python编写网络爬虫程序爬取书旗网上的小说数据,并通过逆向工程对抗网站的反爬机制,最后对采集的数据进行可视化分析。
203 2
基于Python 爬书旗网小说数据并可视化,通过js逆向对抗网站反爬,想爬啥就爬啥
|
3月前
|
JSON JavaScript 前端开发
6-19|Python数据传到JS的方法
6-19|Python数据传到JS的方法
|
4月前
|
Web App开发 JavaScript 前端开发
使用Python调用JavaScript进行网页自动化操作
使用Python调用JavaScript进行网页自动化操作
|
4月前
|
JavaScript 算法 前端开发
国标哈希算法基础:SHA1、SHA256、SHA512、MD5 和 HMAC,Python和JS实现、加盐、算法魔改
国标哈希算法基础:SHA1、SHA256、SHA512、MD5 和 HMAC,Python和JS实现、加盐、算法魔改
580 1
|
4月前
|
Web App开发 JavaScript 前端开发
探索Node.js后端开发之旅深入浅出Python装饰器
【8月更文挑战第29天】在数字化时代,掌握一门后端编程语言变得尤为重要。Node.js作为一种基于JavaScript的服务端平台,因其高性能、轻量级的特性而广受欢迎。本文将引导读者了解Node.js的基本概念、核心模块以及如何利用它来构建一个简易的Web服务器。通过本文的学习,你将获得使用Node.js进行后端开发的初步技能,并理解其在现代Web开发中的应用价值。