L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

reverse-engineering-rust-malware

reverse-engineering-rust-malware

使用 IDA Pro 和 Ghidra 对 Rust 编译的恶意软件进行逆向工程,掌握处理非空终止字符串、提取 crate 依赖项和 Rust 特有控制流分析的专项技术。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: reverse-engineering-rust-malware description: 使用 IDA Pro 和 Ghidra 对 Rust 编译的恶意软件进行逆向工程,掌握处理非空终止字符串、提取 crate 依赖项和 Rust 特有控制流分析的专项技术。 domain: cybersecurity subdomain: malware-analysis tags: [rust, reverse-engineering, malware-analysis, ghidra, ida-pro, binary-analysis, rust-malware] version: "1.0" author: mahipal license: Apache-2.0

对 Rust 恶意软件进行逆向工程

概述

由于 Rust 的跨平台编译能力、内存安全保证,以及对逆向工程师造成的复杂性,它在恶意软件开发中越来越受欢迎。Rust 二进制文件包含完整的静态链接标准库,生成的二进制文件体积较大且包含大量样板代码。主要挑战包括:非空终止字符串(Rust 使用胖指针,包含指针和长度两部分)、单态化(monomorphization)导致泛型代码重复、复杂的错误处理(Result/Option 解包链),以及不熟悉的调用约定。与 C/C++ 二进制文件相比,将 Rust 反编译为 C 代码的效果很差。Ghidra crate 提取脚本和针对 Rust 特有模式(2024-2025 年)的专项培训有助于应对这些挑战。典型的 Rust 恶意软件包括 BlackCat/ALPHV 勒索软件、Hive 勒索软件变种和 Buer Loader。

前置条件

  • IDA Pro 8.0+ 或 Ghidra 11.0+
  • Rust 工具链,用于参考编译
  • Python 3.9+,用于辅助脚本
  • 理解 Rust 内存模型(所有权、借用)
  • 熟悉 Rust 字符串类型(String、&str、CString)

实践步骤

步骤 1:识别并解析 Rust 二进制文件元数据

#!/usr/bin/env python3
"""分析 Rust 恶意软件二进制元数据并提取 crate 依赖项。"""
import re
import sys
import json


def identify_rust_binary(data):
    """检查二进制文件是否为 Rust 编译并提取版本信息。"""
    indicators = {
        "rust_panic_strings": bool(re.search(rb'panicked at', data)),
        "rust_unwrap": bool(re.search(rb'called.*unwrap.*on.*None', data)),
        "core_panic": bool(re.search(rb'core::panicking', data)),
        "std_rt": bool(re.search(rb'std::rt::lang_start', data)),
        "cargo_path": bool(re.search(rb'\.cargo[/\\]registry', data)),
        "rustc_version": None,
    }

    version = re.search(rb'rustc\s+(\d+\.\d+\.\d+)', data)
    if version:
        indicators["rustc_version"] = version.group(1).decode()

    is_rust = sum(1 for v in indicators.values() if v) >= 2
    return is_rust, indicators


def extract_crates(data):
    """从二进制字符串中提取 Rust crate(依赖项)名称。"""
    crate_pattern = re.compile(
        rb'(?:crates\.io-[a-f0-9]+/|\.cargo/registry/src/[^/]+/)'
        rb'([\w-]+)-(\d+\.\d+\.\d+)'
    )
    crates = {}
    for match in crate_pattern.finditer(data):
        name = match.group(1).decode()
        version = match.group(2).decode()
        crates[name] = version

    # 检查常见的恶意软件相关 crate
    suspicious_crates = {
        "reqwest": "HTTP 客户端",
        "hyper": "HTTP 库",
        "tokio": "异步运行时",
        "aes": "AES 加密",
        "chacha20": "ChaCha20 加密",
        "rsa": "RSA 加密",
        "ring": "密码学库",
        "base64": "Base64 编码",
        "winapi": "Windows API 绑定",
        "winreg": "注册表访问",
        "sysinfo": "系统信息",
        "screenshots": "屏幕截图",
        "clipboard": "剪贴板访问",
        "keylogger": "键盘记录",
    }

    capabilities = []
    for crate_name, description in suspicious_crates.items():
        if crate_name in crates:
            capabilities.append({
                "crate": crate_name,
                "version": crates[crate_name],
                "capability": description,
            })

    return crates, capabilities


def extract_rust_strings(data):
    """提取字符串时处理 Rust 的非空终止格式。"""
    # Rust 字符串以指针+长度方式存储,但字符串字面量
    # 通常在 .rodata 段中以连续序列存放
    strings = []
    ascii_pattern = re.compile(rb'[\x20-\x7e]{8,500}')
    for match in ascii_pattern.finditer(data):
        s = match.group().decode('ascii')
        # 过滤出与恶意软件相关的字符串
        keywords = ['http', 'socket', 'encrypt', 'decrypt', 'shell',
                    'exec', 'cmd', 'upload', 'download', 'persist',
                    'registry', 'mutex', 'pipe', 'inject']
        if any(kw in s.lower() for kw in keywords):
            strings.append(s)

    return strings


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"用法: {sys.argv[0]} <rust二进制文件>")
        sys.exit(1)

    with open(sys.argv[1], 'rb') as f:
        data = f.read()

    is_rust, indicators = identify_rust_binary(data)
    print(f"[{'+'if is_rust else '-'}] Rust 二进制文件: {is_rust}")
    print(json.dumps(indicators, indent=2, default=str))

    crates, capabilities = extract_crates(data)
    print(f"\n[+] Crate(共 {len(crates)} 个):")
    for name, ver in sorted(crates.items()):
        print(f"  {name} v{ver}")

    if capabilities:
        print(f"\n[!] 可疑能力:")
        for cap in capabilities:
            print(f"  {cap['crate']} -> {cap['capability']}")

    strings = extract_rust_strings(data)
    if strings:
        print(f"\n[+] 可疑字符串(共 {len(strings)} 个):")
        for s in strings[:20]:
            print(f"  {s}")

验证标准

  • 正确识别二进制文件为 Rust 编译并附带版本信息
  • 提取 crate 依赖项以揭示恶意软件能力
  • Rust 特有字符串提取处理了胖指针格式
  • 识别主入口点和核心逻辑函数
  • 定位加密、网络和持久化相关代码

参考资料

Skills enregistrées