关于 analyzing-ransomware-encryption-mechanisms
面向事件响应人员和研究者的恶意软件分析技能,用于调查勒索软件的加密机制与恢复可能性。内容涵盖逆向分析算法和密钥处理、检查实现弱点,以及记录解密可行性。
主要功能
- 01识别加密算法与模式
- 02分析密钥生成和存储
- 03检查文件加密逻辑
- 04测试密码实现弱点
- 05评估密钥恢复可能性
- 06整理分析结果
适用场景
- 01感染后评估数据恢复选项
- 02调查勒索软件样本的加密方式
- 03依据发现的缺陷开发解密工具
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill analyzing-ransomware-encryption-mechanisms安装后在 Claude Code 中输入/analyzing-ransomware-encryption-mechanisms确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
分析勒索软件加密机制
何时使用
- 已发生勒索软件感染,恢复过程需要理解所使用的加密方案
- 评估在不支付赎金的情况下是否可能解密(实现缺陷、已知解密器)
- 逆向工程勒索软件,以识别加密算法、密钥派生和密钥存储机制
- 当发现勒索软件加密实现中的弱点时,开发解密工具
- 根据加密方式对勒索软件样本进行分类,以将其归因于已知家族
请勿在未先于加密文件的测试副本上验证解密方法的情况下,将其用于生产数据恢复操作。
前置条件
- Ghidra 或 IDA Pro,用于逆向工程勒索软件二进制文件
- Python 3.8+ 及
pycryptodome库,用于测试加密/解密例程 - 样本加密文件及其对应的明文原始文件(已知明文对)
- 访问勒索软件二进制文件(如适用,需已脱壳)
- 熟悉对称(AES、ChaCha20)和非对称(RSA)加密算法
- NoMoreRansom.org 数据库,用于检查现有的免费解密器
工作流
步骤 1:识别加密算法
确定勒索软件使用哪种加密算法:
# Check for Windows Crypto API usage in imports
import pefile
pe = pefile.PE("ransomware.exe")
crypto_apis = {
"CryptAcquireContextA": "Windows CryptoAPI",
"CryptAcquireContextW": "Windows CryptoAPI",
"CryptGenKey": "Windows CryptoAPI key generation",
"CryptEncrypt": "Windows CryptoAPI encryption",
"CryptImportKey": "Windows CryptoAPI key import",
"BCryptOpenAlgorithmProvider": "Windows CNG (modern crypto)",
"BCryptEncrypt": "Windows CNG encryption",
"BCryptGenerateKeyPair": "Windows CNG asymmetric key gen",
}
print("Crypto API Imports:")
for entry in pe.DIRECTORY_ENTRY_IMPORT:
for imp in entry.imports:
if imp.name and imp.name.decode() in crypto_apis:
print(f" {entry.dll.decode()} -> {imp.name.decode()}: {crypto_apis[imp.name.decode()]}")
Common Ransomware Encryption Schemes:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AES-256-CBC + RSA-2048: Most common hybrid scheme (LockBit, REvil, Conti)
AES-256-CTR + RSA-4096: Stream cipher mode variant (BlackCat/ALPHV)
ChaCha20 + RSA-4096: Modern stream cipher (Hive, Royal)
Salsa20 + ECDH: Curve25519 key exchange (Babuk)
AES-128-ECB: Weak mode - potential decryption via known-plaintext
XOR-only: Trivial encryption - always recoverable
Custom algorithm: Often contains implementation flaws
步骤 2:分析密钥生成与管理
逆向工程加密密钥的生成和存储方式:
Key Management Patterns in Ransomware:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. STRONG (no recovery possible without key):
- Per-file AES key generated with CryptGenRandom
- AES key encrypted with embedded RSA public key
- Encrypted key appended to each file or stored separately
- RSA private key held only by attacker's C2 server
2. WEAK (potential recovery):
- AES key derived from predictable seed (timestamp, PID)
- Same AES key used for all files (single key compromise = full recovery)
- Key transmitted to C2 before encryption starts (PCAP may contain key)
- XOR with short repeating key (brute-forceable)
- PRNG seeded with GetTickCount or time() (limited keyspace)
3. FLAWED IMPLEMENTATION:
- ECB mode (preserves plaintext patterns)
- Initialization vector (IV) reuse across files
- Key stored in plaintext in memory (recoverable from memory dump)
- Partial encryption (only first N bytes encrypted)
步骤 3:检查文件加密例程
逆向工程文件处理逻辑:
// Typical ransomware file encryption flow (decompiled pseudo-code from Ghidra):
void encrypt_file(char *filepath) {
// 1. Check file extension against target list
if (!is_target_extension(filepath)) return;
// 2. Generate per-file AES key (32 bytes for AES-256)
BYTE aes_key[32];
CryptGenRandom(hProv, 32, aes_key);
// 3. Generate random IV (16 bytes)
BYTE iv[16];
CryptGenRandom(hProv, 16, iv);
// 4. Read file contents
HANDLE hFile = CreateFile(filepath, GENERIC_READ, ...);
BYTE *plaintext = read_entire_file(hFile);
// 5. Encrypt with AES-256-CBC
aes_cbc_encrypt(plaintext, file_size, aes_key, iv);
// 6. Encrypt AES key with RSA public key
BYTE encrypted_key[256]; // RSA-2048 output
rsa_encrypt(aes_key, 32, rsa_pubkey, encrypted_key);
// 7. Write: encrypted_data + encrypted_key + IV to file
write_file(filepath, encrypted_data, encrypted_key, iv);
// 8. Rename file with ransomware extension
rename_file(filepath, strcat(filepath, ".locked"));
}
步骤 4:检查加密弱点
测试实现中是否存在可利用的缺陷:
from Crypto.Cipher import AES
import os
import struct
# Test 1: Check if same key is used for multiple files
# Compare encrypted versions of known files
def check_key_reuse(file1_enc, file2_enc):
with open(file1_enc, "rb") as f:
data1 = f.read()
with open(file2_enc, "rb") as f:
data2 = f.read()
# Extract IVs (location depends on ransomware family)
# If IVs are same and files share encrypted blocks -> same key
iv1 = data1[-16:] # Example: IV at end
iv2 = data2[-16:]
if iv1 == iv2:
print("[!] Same IV detected - key reuse likely")
# Test 2: Check for predictable key derivation
# If key is derived from timestamp, iterate possible values
def brute_force_timestamp_key(encrypted_file, known_header, timestamp_range):
with open(encrypted_file, "rb") as f:
encrypted_data = f.read()
for ts in timestamp_range:
# Derive key the same way ransomware does
import hashlib
key = hashlib.sha256(str(ts).encode()).digest()
iv = encrypted_data[-16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(encrypted_data[:16])
if decrypted[:len(known_header)] == known_header:
print(f"[!] Key found! Timestamp: {ts}")
return key
return None
# Test 3: Check for ECB mode (pattern preservation)
def check_ecb_mode(encrypted_file):
with open(encrypted_file, "rb") as f:
data = f.read()
# ECB produces identical ciphertext for identical plaintext blocks
blocks = [data[i:i+16] for i in range(0, len(data), 16)]
unique = len(set(blocks))
total = len(blocks)
if unique < total * 0.95:
print(f"[!] ECB mode likely: {total-unique} duplicate blocks out of {total}")
步骤 5:尝试密钥恢复
利用弱点进行密钥恢复:
# Recovery Method 1: Extract key from memory dump
# Volatility plugin to scan for AES key schedules
# vol3 -f memory.dmp windows.yarascan --yara-rule "aes_key_schedule"
# Recovery Method 2: Known-plaintext attack (weak algorithms)
def xor_key_recovery(encrypted_file, known_plaintext):
"""Recover XOR key from known plaintext-ciphertext pair"""
with open(encrypted_file, "rb") as f:
ciphertext = f.read()
key = bytes(c ^ p for c, p in zip(ciphertext, known_plaintext))
# Find repeating key length
for key_len in range(1, 256):
candidate = key[:key_len]
if all(key[i] == candidate[i % key_len] for i in range(min(len(key), key_len * 4))):
print(f"XOR key (length {key_len}): {candidate.hex()}")
return candidate
return None
# Recovery Method 3: Check NoMoreRansom for existing decryptors
# https://www.nomoreransom.org/en/decryption-tools.html
步骤 6:记录加密分析
将发现整理成结构化报告:
Analysis should document:
- Algorithm identified (AES, RSA, ChaCha20, custom)
- Key size and mode of operation (CBC, CTR, ECB, GCM)
- Key generation method (CSPRNG, predictable seed, static key)
- Key storage location (appended to file, registry, C2 transmission)
- File modification pattern (full encryption, partial, header-only)
- Targeted file extensions
- Ransom note format and payment infrastructure
- Decryption feasibility assessment (possible/impossible/partial)
- Recommended recovery approach
关键概念
| 术语 | 定义 |
|---|---|
| 混合加密 | 结合对称加密(AES)以实现快速文件加密,以及非对称加密(RSA)以实现安全密钥封装;这是勒索软件的标准方法 |
| 密钥封装 | 使用攻击者的 RSA 公钥加密每个文件的对称密钥,因此只有攻击者的私钥才能解密它 |
| ECB 模式 | 电子密码本模式独立加密每个块;会保留明文中的模式,这是一个关键弱点,可实现部分恢复 |
| 已知明文攻击 | 使用已知的原始文件及其加密版本推导加密密钥;对 XOR 和弱流密码有效 |
| 密钥调度 | AES 密钥在内存中的扩展形式;可在内存转储中扫描,以在加密密钥被擦除之前恢复它们 |
| CSPRNG | 密码学安全伪随机数生成器;使用 CryptGenRandom 的勒索软件会生成不可预测的密钥 |
| 部分加密 | 一些勒索软件为提升速度只加密前 N 个字节或每隔 N 个块加密;未加密的部分可能有助于恢复 |
工具与系统
- Ghidra:逆向工程套件,用于在汇编层面分析勒索软件加密例程
- PyCryptodome:Python 加密库,用于实现和测试解密例程
- NoMoreRansom.org:由 Europol 和安全厂商维护的免费解密工具仓库,适用于已知勒索软件家族
- Volatility:内存取证框架,用于从受感染系统的 RAM 转储中提取加密密钥
- CryptoTester:基于常量和代码模式识别加密算法的工具
常见场景
场景:评估勒索软件事件中的解密可行性
背景:某组织遭到勒索软件攻击,文件服务器被加密。管理层需要在做出恢复决策之前,了解是否有可能在不支付赎金的情况下进行解密。
方法:
- 根据勒索信、文件扩展名和样本哈希识别勒索软件家族(查询 ID Ransomware)
- 在 NoMoreRansom.org 上查询该家族是否已有免费解密器
- 在 Ghidra 中逆向工程加密例程,以识别算法和密钥管理方式
- 测试实现弱点(密钥重用、可预测种子、ECB 模式)
- 检查事件中的 PCAP 是否捕获了密钥向 C2 的传输(如果密钥在加密前已发送)
- 扫描受影响机器的内存转储,查找 RAM 中的 AES 密钥调度
- 报告发现:解密可能/不可能,并给出具体的技术依据
陷阱:
- 在加密文件的唯一副本上测试解密方法(始终在副本上操作)
- 未经验证就假设所有文件使用同一密钥(某些勒索软件使用逐文件密钥)
- 未检查卷影副本(vssadmin),勒索软件可能未能删除它们
- 在报告中混淆文件加密算法与密钥封装算法
输出格式
RANSOMWARE ENCRYPTION ANALYSIS
================================
Sample: lockbit3.exe
Family: LockBit 3.0 / LockBit Black
SHA-256: abc123def456...
ENCRYPTION SCHEME
File Cipher: AES-256-CTR (per-file unique key)
Key Wrapping: RSA-2048 (public key embedded in binary)
Key Generation: CryptGenRandom (CSPRNG - unpredictable)
IV Generation: Random 16 bytes per file
File Structure: [encrypted_data][rsa_encrypted_key(256B)][iv(16B)][magic(8B)]
TARGETED EXTENSIONS
Total: 412 extensions targeted
Categories: Documents (.doc, .xls, .pdf), Databases (.sql, .mdb),
Archives (.zip, .7z), Source code (.py, .java, .cs)
Excluded: .exe, .dll, .sys, .lnk (system files preserved)
IMPLEMENTATION ANALYSIS
Key Strength: STRONG - per-file random keys, no reuse
Mode Security: STRONG - CTR mode with unique nonces
Key Storage: RSA-encrypted key appended to each file
Shadow Copies: Deleted via vssadmin and WMI
DECRYPTION FEASIBILITY
Without Key: NOT POSSIBLE
- No implementation flaws identified
- RSA-2048 key wrapping prevents brute force
- CSPRNG prevents key prediction
- No existing free decryptor available
RECOVERY OPTIONS
1. Restore from offline backups (recommended)
2. Check for volume shadow copies (low probability - ransomware deletes them)
3. Memory forensics if machine was not rebooted (key may persist in RAM)
4. Negotiate with attacker (last resort - no guarantee of decryption)
评论
支持 Markdown