关于 reverse-engineering-ransomware-encryption-routine
面向授权安全研究人员的勒索软件加密例程逆向分析指南,适用于受控环境中的恶意软件样本和攻击产物分析。内容聚焦算法、密钥生成与加密流程,以评估潜在解密机会。
主要功能
- 01识别加密算法与系统 API
- 02分析文件加密流程
- 03检查密钥生成与 IV 使用
- 04提取文件目标模式和扩展名
- 05评估实现缺陷与解密机会
适用场景
- 01在受控环境分析勒索软件样本
- 02开展授权渗透测试或红队演练
- 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 外,安装时一起下载的参考资料和脚本。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.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 等)
- 已确定密钥大小和操作模式
- 已分析密钥生成方法以寻找潜在弱点
- 已记录每文件密钥加密方案
- 已提取文件目标选择模式和扩展名列表
- 已提取嵌入的公钥以进行基础设施关联
- 已评估潜在解密机会