mcpField
D
deobfuscating-javascript-malware

deobfuscating-javascript-malware

github.com/mukul975安全35.2k187 次安装8 周前更新
代码仓库

关于 deobfuscating-javascript-malware

这是一项面向安全分析人员的 JavaScript 恶意软件混淆分析技能,涵盖安全提取、逐层解码和载荷检查,并强调在隔离环境中操作。

主要功能

  1. 01安全提取并检查脚本
  2. 02识别常见混淆技术
  3. 03移除反分析陷阱
  4. 04逐层解码字符串
  5. 05安全解析 eval 链
  6. 06提取恶意载荷指标

适用场景

  1. 01调查钓鱼页中的混淆脚本
  2. 02分析电商网站注入的网页盗刷程序
  3. 03检查含脚本的恶意邮件附件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill deobfuscating-javascript-malware

安装后在 Claude Code 中输入/deobfuscating-javascript-malware确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
agent.py

详细介绍

反混淆 JavaScript 恶意软件

何时使用

  • 调查包含混淆 JavaScript 的钓鱼页面,该脚本执行凭据窃取或重定向
  • 分析注入到电商网站中的网页窃密脚本(Magecart 式)
  • 反混淆下载并执行二阶段恶意软件的 JavaScript 投放器
  • 检查包含嵌入混淆脚本的 HTML 文件的恶意电子邮件附件
  • 分析使用重度 JavaScript 混淆来隐藏漏洞利用投递的浏览器漏洞利用工具包

不要使用于仅仅是压缩过的生产代码的混淆 JavaScript;请改用标准的美化工具。

前提条件

  • 已安装 Node.js 18+,用于在受控环境中执行和调试 JavaScript
  • Python 3.8+ 及 jsbeautifier 库,用于代码格式化
  • 浏览器开发者工具(Chrome DevTools),用于在隔离浏览器中进行受控执行
  • CyberChef(https://gchq.github.io/CyberChef/),用于编码/解码操作
  • de4js 或 JStillery,用于自动化 JavaScript 反混淆
  • 隔离的分析虚拟机,无法访问生产系统或敏感数据

工作流

步骤 1:安全提取并检查混淆脚本

在不执行的情况下隔离恶意 JavaScript:

# Extract JavaScript from HTML file
python3 << 'PYEOF'
from html.parser import HTMLParser

class ScriptExtractor(HTMLParser):
    def __init__(self):
        super().__init__()
        self.in_script = False
        self.scripts = []
        self.current = ""

    def handle_starttag(self, tag, attrs):
        if tag == "script":
            self.in_script = True
            self.current = ""

    def handle_endtag(self, tag):
        if tag == "script":
            self.in_script = False
            if self.current.strip():
                self.scripts.append(self.current)

    def handle_data(self, data):
        if self.in_script:
            self.current += data

with open("malicious_page.html") as f:
    parser = ScriptExtractor()
    parser.feed(f.read())

for i, script in enumerate(parser.scripts):
    with open(f"script_{i}.js", "w") as f:
        f.write(script)
    print(f"Extracted script_{i}.js ({len(script)} bytes)")
PYEOF

# Beautify the extracted JavaScript
npx js-beautify script_0.js -o script_0_pretty.js
步骤 2:识别混淆技术

对所使用的混淆方法进行分类:

Common JavaScript Obfuscation Techniques:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
String Encoding:
  - Hex encoding:          "\x68\x65\x6c\x6c\x6f" -> "hello"
  - Unicode escapes:       "\u0068\u0065\u006c\u006c\u006f" -> "hello"
  - Base64:                atob("aGVsbG8=") -> "hello"
  - charCodeAt/fromCharCode: String.fromCharCode(104,101,108,108,111)
  - Array-based lookup:    var _0x1234 = ["hello","world"]; _0x1234[0]

Eval Chains:
  - eval(atob("..."))
  - eval(unescape("..."))
  - new Function("return " + decoded)()
  - document.write("<script>" + decoded + "</script>")
  - setTimeout(decoded, 0)

Control Flow:
  - Switch-case dispatcher with shuffled case order
  - Opaque predicates (always-true/false conditions)
  - Dead code insertion
  - Variable name mangling (_0x4a3b, _0xab12)

Anti-Analysis:
  - Debugger traps: setInterval(function(){debugger;}, 100)
  - Console detection: overriding console.log
  - Timing checks: performance.now() deltas
  - DevTools detection: window.outerWidth - window.innerWidth > 100
步骤 3:移除反分析保护

消除反调试和反分析陷阱:

// Remove debugger traps before analysis
// Replace in the obfuscated script:

// Before:
setInterval(function() { debugger; }, 100);

// After (neutralized):
setInterval(function() { /* debugger removed */ }, 100);

// Neutralize DevTools detection
// Before:
if (window.outerWidth - window.innerWidth > 160) { window.location = "about:blank"; }

// After:
if (false) { window.location = "about:blank"; }

// Neutralize timing checks
// Override performance.now to return consistent values
const originalNow = performance.now;
performance.now = function() { return 0; };
步骤 4:解码字符串混淆层

逐步解码经过编码的字符串:

# Python script to decode common JS obfuscation patterns
import re
import base64
import urllib.parse

def decode_hex_strings(code):
    """Replace \\xNN sequences with ASCII characters"""
    def hex_replace(match):
        hex_str = match.group(0)
        try:
            return bytes.fromhex(hex_str.replace("\\x", "")).decode("ascii")
        except:
            return hex_str
    return re.sub(r'(?:\\x[0-9a-fA-F]{2})+', hex_replace, code)

def decode_unicode_escapes(code):
    """Replace \\uNNNN sequences with characters"""
    def unicode_replace(match):
        return chr(int(match.group(1), 16))
    return re.sub(r'\\u([0-9a-fA-F]{4})', unicode_replace, code)

def decode_charcode_arrays(code):
    """Resolve String.fromCharCode calls"""
    def charcode_replace(match):
        codes = [int(c.strip()) for c in match.group(1).split(",")]
        return '"' + "".join(chr(c) for c in codes) + '"'
    return re.sub(r'String\.fromCharCode\(([0-9,\s]+)\)', charcode_replace, code)

def decode_base64_strings(code):
    """Resolve atob() calls with static strings"""
    def atob_replace(match):
        try:
            decoded = base64.b64decode(match.group(1)).decode("utf-8")
            return f'"{decoded}"'
        except:
            return match.group(0)
    return re.sub(r'atob\(["\']([A-Za-z0-9+/=]+)["\']\)', atob_replace, code)

# Apply all decoders
with open("script_0.js") as f:
    code = f.read()

code = decode_hex_strings(code)
code = decode_unicode_escapes(code)
code = decode_charcode_arrays(code)
code = decode_base64_strings(code)

with open("script_0_decoded.js", "w") as f:
    f.write(code)
print("Decoded strings written to script_0_decoded.js")
步骤 5:安全解析 Eval 链

在不执行的情况下展开 eval/Function 构造函数链:

// Node.js script to safely resolve eval chains
// Run in isolated environment: node --experimental-vm-modules deobfuscate.js

const vm = require('vm');

// Create sandboxed context with logging
const sandbox = {
    eval: function(code) {
        console.log("=== EVAL INTERCEPTED ===");
        console.log(code.substring(0, 500));
        console.log("========================");
        return code; // Return the code instead of executing it
    },
    document: {
        write: function(html) {
            console.log("=== DOCUMENT.WRITE INTERCEPTED ===");
            console.log(html.substring(0, 500));
        },
        getElementById: function() { return { innerHTML: "" }; }
    },
    window: { location: { href: "" } },
    atob: function(s) { return Buffer.from(s, 'base64').toString(); },
    unescape: unescape,
    setTimeout: function(fn) { if (typeof fn === 'string') console.log("TIMEOUT CODE:", fn); },
    console: console,
    String: String,
    Array: Array,
    parseInt: parseInt,
    RegExp: RegExp,
};

const context = vm.createContext(sandbox);

// Load and execute the obfuscated script in sandbox
const fs = require('fs');
const code = fs.readFileSync('script_0.js', 'utf8');

try {
    vm.runInContext(code, context, { timeout: 5000 });
} catch(e) {
    console.log("Execution error (expected):", e.message);
}
步骤 6:分析反混淆后的载荷

检查所揭示的恶意逻辑:

Deobfuscated Malware Categories and IOC Extraction:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Credential Harvester:
  - Form action URLs (exfiltration endpoints)
  - XMLHttpRequest/fetch destinations
  - Targeted input field names (username, password, cc_number)

Web Skimmer (Magecart):
  - Payment form overlay injection
  - Card data exfiltration URLs
  - Keylogger event listeners (onkeypress, oninput)

Redirect Script:
  - Destination URLs in location.href assignments
  - Conditional redirects based on user-agent or referrer
  - Cloaking logic (show benign content to bots)

Exploit Kit Landing:
  - Browser/plugin version checks
  - Exploit payload URLs
  - Shellcode embedded as arrays or encoded strings

关键概念

术语定义
Eval 链嵌套的 eval()、Function() 或 document.write() 调用层,每一层在传递给下一层之前解码一层混淆
字符串数组轮转一种混淆技术,将所有字符串存储在一个打乱顺序的数组中,并通过计算索引访问它们以隐藏字符串字面量
死代码插入添加永远不会执行的非功能性代码块,以增加分析复杂度并干扰模式匹配
不透明谓词结果预先确定但难以静态确定的条件表达式;用于模糊控制流
反调试用于检测和阻止浏览器 DevTools 或调试器使用的 JavaScript 技术,包括 debugger 语句和计时检查
网页窃密脚本注入到电商网站中,用于从结账表单窃取支付卡数据的恶意 JavaScript(Magecart 攻击)
CyberChefGCHQ 的基于 Web 的工具,用于编码/解码转换,有助于展开多层混淆

工具与系统

  • CyberChef:GCHQ 的基于 Web 的工具,用于编码/解码转换,有助于展开多层混淆
  • de4js:在线 JavaScript 反混淆器,支持常见混淆工具(obfuscator.io、JScrambler)
  • Node.js VM 模块:沙箱化的 JavaScript 执行环境,用于在拦截 API 的情况下安全评估混淆代码
  • Chrome DevTools:浏览器开发者工具,用于通过断点和控制台访问单步调试 JavaScript 执行
  • JSDetox:JavaScript 恶意软件分析工具,提供执行模拟和反混淆

常见场景

场景:反混淆 Magecart 网页窃取程序

背景:一个被入侵的电商网站,其结账页面被注入了混淆过的 JavaScript。需要对该脚本进行反混淆,以识别数据外传端点,并确定哪些客户数据被窃取。

方法:

  1. 从页面源代码中提取注入的脚本(通常附加在合法的 JS 文件末尾,或从外部域加载)
  2. 美化代码并识别混淆技术(通常是字符串数组 + 轮转 + 十六进制编码)
  3. 使用 Python 解码脚本解码各层字符串编码(十六进制 -> Unicode -> base64)
  4. 通过求值数组定义和轮转函数来还原字符串数组
  5. 识别表单定向逻辑(针对支付表单字段的 querySelector)
  6. 从 XMLHttpRequest 或 fetch 调用中提取外传 URL
  7. 记录被窃取的数据字段和外传端点,用于事件响应

陷阱:

  • 在联网系统上执行混淆脚本(脚本可能在分析期间回连)
  • 在使用浏览器 DevTools 之前未移除反调试陷阱(无限 debugger 循环)
  • 遗漏从外部 URL 动态加载的额外混淆层
  • 忽略可能包含额外脚本的 base64 编码内联图片或 data URI

输出格式

JAVASCRIPT MALWARE DEOBFUSCATION REPORT
=========================================
Source:           checkout.js (injected into example-shop.com)
Obfuscation:      obfuscator.io (string array + rotation + hex encoding)
Layers Removed:   3

OBFUSCATION TECHNIQUES IDENTIFIED
[1] String array with 247 entries, rotated by 0x1a3
[2] Hex-encoded string references (\x68\x65\x6c\x6c\x6f)
[3] Base64-wrapped eval chain (2 layers)
[4] Anti-debugging: setInterval debugger trap

DEOBFUSCATED FUNCTIONALITY
Type:             Magecart Payment Card Skimmer
Target Forms:     input[name*="card"], input[name*="cc_"]
Data Captured:    Card number, expiration, CVV, cardholder name
Exfil Method:     POST via XMLHttpRequest
Exfil URL:        hxxps://analytics-cdn[.]com/collect
Exfil Format:     JSON { "cn": card_number, "exp": expiry, "cv": cvv }
Trigger:          Form submit event on checkout page

EXTRACTED IOCs
Domains:          analytics-cdn[.]com
IPs:              185.220.101[.]42
URLs:             hxxps://analytics-cdn[.]com/collect
                  hxxps://analytics-cdn[.]com/gate.js

评论

支持 Markdown