mcpField
A
analyzing-ransomware-encryption-mechanisms

analyzing-ransomware-encryption-mechanisms

github.com/mukul975セキュリティ35.2k304 回インストール8 週間前に更新
リポジトリ

analyzing-ransomware-encryption-mechanisms について

インシデント対応者や研究者がランサムウェアの暗号化方式と復旧可能性を調べるためのマルウェア分析スキルです。アルゴリズムや鍵管理のリバースエンジニアリング、実装上の弱点の検証、復号可能性の報告を扱います。

主な機能

  1. 01暗号アルゴリズムとモードの特定
  2. 02鍵生成と保存方法の分析
  3. 03ファイル暗号化処理の調査
  4. 04暗号実装の弱点の検証
  5. 05鍵回収の可能性の評価
  6. 06分析結果の整理

活用シーン

  1. 01感染後の復旧方法を評価
  2. 02ランサムウェア検体の暗号化方式を調査
  3. 03特定した欠陥に基づく復号ツールの開発

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill analyzing-ransomware-encryption-mechanisms

インストール後、Claude Code で/analyzing-ransomware-encryption-mechanismsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

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

詳細

ランサムウェアの暗号化メカニズムを分析する

使用する場面

  • ランサムウェアに感染し、復旧のために使用された暗号化方式を把握する必要がある場合
  • 身代金を支払わずに復号できるか評価する場合(実装上の欠陥、既知の復号ツール)
  • ランサムウェアをリバースエンジニアリングし、暗号化アルゴリズム、鍵導出方式、鍵の保存メカニズムを特定する場合
  • ランサムウェアの暗号実装に脆弱性が見つかった際に、復号ツールを開発する場合
  • 暗号化方式に基づいてランサムウェアのサンプルを分類し、既知のファミリーに帰属させる場合

使用しないでください:暗号化されたファイルのテストコピーで復号方法を事前に検証せずに、本番データの復旧作業を行う場合。

前提条件

  • ランサムウェアのバイナリをリバースエンジニアリングするための Ghidra または IDA Pro
  • 暗号化/復号ルーチンのテストに使う pycryptodome ライブラリを含む Python 3.8 以降
  • 暗号化されたファイルのサンプルと、それに対応する元の平文ファイル(既知平文のペア)
  • ランサムウェアのバイナリへのアクセス(該当する場合はパック解除済みのもの)
  • 共通鍵暗号(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:定数やコードパターンに基づいて暗号アルゴリズムを特定するツール

よくあるシナリオ

シナリオ:ランサムウェアインシデントにおける復号可能性の評価

コンテキスト:組織がランサムウェアの被害に遭い、ファイルサーバーが暗号化されました。管理部門は、復旧方針を決定する前に、身代金を支払わずに復号できるかどうかを把握する必要があります。

アプローチ:

  1. 身代金要求メッセージ、ファイル拡張子、サンプルのハッシュからランサムウェアのファミリーを特定します(ID Ransomware で確認します)
  2. NoMoreRansom.org で、このファミリーに対応する既存の無料復号ツールを確認します
  3. Ghidra で暗号化ルーチンをリバースエンジニアリングし、アルゴリズムと鍵管理の方法を特定します
  4. 実装上の弱点(鍵の再利用、予測可能なシード、ECB モード)を検証します
  5. インシデント時の PCAP に、C2 への鍵の送信が記録されているか確認します(暗号化前に鍵が送信された場合)
  6. 影響を受けたマシンのメモリダンプをスキャンし、RAM 内に AES の鍵スケジュールがないか確認します
  7. 調査結果を報告します:具体的な技術的根拠とともに、復号の可否を示します

注意点:

  • 暗号化されたファイルの唯一のコピーで復号方法を試すこと(必ずコピーで作業します)
  • 検証せずに、すべてのファイルが同じ鍵を使用していると仮定すること(一部のランサムウェアはファイルごとに異なる鍵を使用します)
  • ボリュームシャドウコピー(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)

コメント