mcpField
R
reverse-engineering-ransomware-encryption-routine

reverse-engineering-ransomware-encryption-routine

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

关于 reverse-engineering-ransomware-encryption-routine

面向授权安全研究人员的勒索软件加密例程逆向分析指南,适用于受控环境中的恶意软件样本和攻击产物分析。内容聚焦算法、密钥生成与加密流程,以评估潜在解密机会。

主要功能

  1. 01识别加密算法与系统 API
  2. 02分析文件加密流程
  3. 03检查密钥生成与 IV 使用
  4. 04提取文件目标模式和扩展名
  5. 05评估实现缺陷与解密机会

适用场景

  1. 01在受控环境分析勒索软件样本
  2. 02开展授权渗透测试或红队演练
  3. 03根据攻击技术构建检测能力

安装

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

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill reverse-engineering-ransomware-encryption-routine

安装后在 Claude Code 中输入/reverse-engineering-ransomware-encryption-routine确认已加载。

包含的文件

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

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

逆向工程勒索软件加密例程

概述

现代勒索软件使用混合加密,将用于文件加密的对称算法(AES-256-CBC/CTR、ChaCha20、Salsa20)与用于密钥保护的非对称算法(RSA-2048/4096、Curve25519)相结合。加密例程通常为每个文件生成一个随机对称密钥,加密文件内容,然后使用攻击者嵌入的公钥加密该对称密钥。逆向工程这些例程可以识别具体算法、密钥派生方法、初始化向量、文件目标选择模式,以及可能无需支付赎金即可实现解密的潜在实现缺陷。著名示例包括 Rhysida(AES-256-CTR + RSA-4096)、Qilin.B(AES-256-CTR,带 AES-NI 或 ChaCha20 回退)和 Medusa(AES-256 + RSA)。

何时使用

  • 在执行涉及逆向工程勒索软件加密例程的授权安全测试时
  • 在受控环境中分析恶意软件样本或攻击产物时
  • 在开展红队演练或渗透测试项目时
  • 在基于攻击技术理解构建检测能力时

前提条件

  • 用于静态反汇编的 IDA Pro 或 Ghidra
  • 用于动态调试的 x64dbg/WinDbg
  • Python 3.9+ 以及 pycryptodome、pefile
  • 理解 AES、RSA、ChaCha20、Curve25519 算法
  • 了解 Windows CryptoAPI 和 CNG(BCrypt)函数
  • 用于安全执行的沙箱环境

关键概念

混合加密模型

勒索软件为每个文件生成唯一的 AES 密钥和 IV。文件内容使用此对称密钥加密。随后,对称密钥使用攻击者的 RSA 公钥(嵌入在二进制文件中或从 C2 获取)加密。加密后的密钥被追加或前置到加密文件中。只有持有 RSA 私钥的攻击者才能解密每个文件的对称密钥。

加密 API 识别

Windows 勒索软件通常使用 CryptoAPI(CryptAcquireContext、CryptGenKey、CryptEncrypt)或 CNG(BCryptGenerateSymmetricKey、BCryptEncrypt)。有些使用 OpenSSL 或自定义实现。识别这些 API 调用可以立即洞察算法、密钥大小和操作模式。

实现缺陷

解密机会来自:硬编码加密密钥、用于密钥生成的弱 PRNG(使用 GetTickCount 或 time() 作为种子)、跨文件重用 IV、使用 ECB 模式、加密后密钥仍留在内存中,以及可在加密期间捕获密钥的竞态条件。

工作流

步骤 1:识别加密函数
#!/usr/bin/env python3
"""Identify cryptographic functions in ransomware PE files."""
import pefile
import sys

CRYPTO_APIS = {
    # Windows CryptoAPI
    "CryptAcquireContextA": "CryptoAPI context acquisition",
    "CryptAcquireContextW": "CryptoAPI context acquisition",
    "CryptGenKey": "Key generation",
    "CryptDeriveKey": "Key derivation",
    "CryptEncrypt": "Encryption operation",
    "CryptDecrypt": "Decryption operation",
    "CryptImportKey": "Key import (public key?)",
    "CryptExportKey": "Key export",
    "CryptGenRandom": "Random number generation",
    "CryptCreateHash": "Hash creation",
    "CryptHashData": "Hashing operation",
    # Windows CNG (BCrypt)
    "BCryptOpenAlgorithmProvider": "CNG algorithm initialization",
    "BCryptGenerateSymmetricKey": "CNG symmetric key generation",
    "BCryptEncrypt": "CNG encryption",
    "BCryptDecrypt": "CNG decryption",
    "BCryptGenerateKeyPair": "CNG key pair generation",
    "BCryptImportKeyPair": "CNG key import",
    # OpenSSL
    "EVP_EncryptInit_ex": "OpenSSL encrypt init",
    "EVP_EncryptUpdate": "OpenSSL encrypt update",
    "EVP_EncryptFinal_ex": "OpenSSL encrypt final",
    "RSA_public_encrypt": "OpenSSL RSA encryption",
    "AES_set_encrypt_key": "OpenSSL AES key setup",
    # File operations
    "CreateFileW": "File open (target files)",
    "ReadFile": "File read (before encryption)",
    "WriteFile": "File write (after encryption)",
    "FindFirstFileW": "File enumeration (targeting)",
    "FindNextFileW": "File enumeration",
    "MoveFileW": "File rename (extension change)",
    "DeleteFileW": "File deletion (originals)",
}

AES_SBOX = bytes([
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
])

CHACHA20_CONSTANT = b"expand 32-byte k"


def analyze_imports(filepath):
    """Analyze PE imports for cryptographic APIs."""
    try:
        pe = pefile.PE(filepath)
    except pefile.PEFormatError:
        print("[-] Not a valid PE file")
        return

    print("[+] Cryptographic API Analysis")
    print("=" * 60)

    crypto_imports = []
    if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
        for entry in pe.DIRECTORY_ENTRY_IMPORT:
            dll = entry.dll.decode('utf-8', errors='replace')
            for imp in entry.imports:
                if imp.name:
                    name = imp.name.decode('utf-8', errors='replace')
                    if name in CRYPTO_APIS:
                        desc = CRYPTO_APIS[name]
                        crypto_imports.append((dll, name, desc))
                        print(f"  [{dll}] {name}: {desc}")

    if not crypto_imports:
        print("  No known crypto APIs found in imports")
        print("  Malware may use custom implementation or dynamic loading")

    return crypto_imports


def find_crypto_constants(filepath):
    """Search for embedded cryptographic constants."""
    with open(filepath, 'rb') as f:
        data = f.read()

    print("\n[+] Cryptographic Constants Search")
    print("=" * 60)

    # AES S-Box
    offset = data.find(AES_SBOX)
    if offset != -1:
        print(f"  AES S-Box found at offset 0x{offset:x}")

    # ChaCha20/Salsa20 constant
    offset = data.find(CHACHA20_CONSTANT)
    if offset != -1:
        print(f"  ChaCha20 constant at offset 0x{offset:x}")

    # RSA public key markers
    rsa_markers = [
        b'-----BEGIN PUBLIC KEY-----',
        b'-----BEGIN RSA PUBLIC KEY-----',
        b'\x30\x82',  # ASN.1 SEQUENCE
    ]
    for marker in rsa_markers:
        offset = data.find(marker)
        if offset != -1:
            print(f"  RSA key marker at offset 0x{offset:x}")

    # Common ransomware file extension patterns
    import re
    ext_pattern = re.compile(rb'\.\w{3,10}(?=\x00)', re.IGNORECASE)
    extensions = set()
    for match in ext_pattern.finditer(data):
        ext = match.group().decode('ascii', errors='replace').lower()
        target_exts = [
            '.doc', '.docx', '.xls', '.xlsx', '.pdf', '.ppt',
            '.jpg', '.png', '.sql', '.mdb', '.bak', '.zip',
        ]
        if ext in target_exts:
            extensions.add(ext)

    if extensions:
        print(f"\n  Target file extensions: {', '.join(sorted(extensions))}")


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <ransomware_sample>")
        sys.exit(1)

    analyze_imports(sys.argv[1])
    find_crypto_constants(sys.argv[1])
步骤 2:分析加密流程
def analyze_encryption_pattern(filepath):
    """Analyze file encryption patterns from ransomware artifacts."""
    import os
    import struct

    with open(filepath, 'rb') as f:
        data = f.read()

    file_size = len(data)
    print(f"\n[+] Encrypted File Analysis: {filepath}")
    print(f"  Size: {file_size:,} bytes")

    # Check for appended key material (common pattern)
    # Many ransomware families append encrypted key at end of file
    tail_sizes = [256, 512, 1024, 2048]  # Common RSA ciphertext sizes
    for size in tail_sizes:
        if file_size > size + 16:
            tail = data[-size:]
            # High entropy suggests encrypted data
            entropy = calculate_entropy(tail)
            if entropy > 7.5:
                print(f"  Possible encrypted key ({size} bytes) "
                      f"at end of file (entropy: {entropy:.2f})")

    # Check for header modifications
    # Many ransomware prepend metadata
    header = data[:64]
    print(f"  First 16 bytes: {header[:16].hex()}")

    # Check if original file header is preserved
    known_headers = {
        b'PK': 'ZIP/Office',
        b'\x89PNG': 'PNG',
        b'\xff\xd8\xff': 'JPEG',
        b'%PDF': 'PDF',
        b'\xd0\xcf\x11\xe0': 'OLE (DOC/XLS)',
    }
    for magic, ftype in known_headers.items():
        if header.startswith(magic):
            print(f"  Original format preserved: {ftype}")
            break
    else:
        print("  Original header destroyed/encrypted")


def calculate_entropy(data):
    """Calculate Shannon entropy of data."""
    from collections import Counter
    import math

    if not data:
        return 0

    freq = Counter(data)
    length = len(data)
    entropy = -sum(
        (count / length) * math.log2(count / length)
        for count in freq.values()
    )
    return entropy

验证标准

  • 已识别加密算法(AES、RSA、ChaCha20 等)
  • 已确定密钥大小和操作模式
  • 已分析密钥生成方法以寻找潜在弱点
  • 已记录每文件密钥加密方案
  • 已提取文件目标选择模式和扩展名列表
  • 已提取嵌入的公钥以进行基础设施关联
  • 已评估潜在解密机会

参考资料

评论

支持 Markdown