Шифровальщики | 22 января 2026

Охота за «Золотым ключом»: Криптография шифровальщиков и извлечение ключей дешифровки из оперативной памяти

Охота за «Золотым ключом»: Криптография шифровальщиков и извлечение ключей дешифровки из оперативной памяти

Почему это последняя линия защиты

Вы обнаружили ransomware. Компьютер изолирован. Дамп памяти лежит на чистой машине. Резервные копии скомпрометированы или недоступны.

Впереди единственное, что осталось: поиск симметричного ключа, который был использован для шифрования ваших файлов. Если вы найдёте его — данные восстановлены. Если нет — остаётся только выплата выкупа или полная потеря.

Эта статья — для форензиков, специалистов по инцидентам (Incident Responders) и технических экспертов, которые хотят понять, почему извлечение ключа является одновременно возможным и чрезвычайно сложным техническим процессом.


Часть I: Архитектура шифрования современного ransomware

Парадокс эффективности и безопасности

Когда разработчик malware строит систему для шифрования данных без интернета на скомпрометированной машине, он сталкивается с инженерной трилеммой. Необходимо выбрать баланс между скоростью, безопасностью и автономностью.

Рассмотрим три основных архитектурных подхода:

Вариант 1: Только симметричное шифрование (AES)

  • Быстро: Скорость шифрования достигает 5 GB за 30 секунд (при использовании AES-NI).
  • Проблема ключа: Ключ должен находиться где-то на диске или в памяти в открытом виде, чтобы процесс мог работать.
  • Результат: Форензики легко находят ключ на диске → все файлы восстанавливаются бесплатно.
  • История: Старые семейства ransomware использовали этот подход, что позволило антивирусным компаниям быстро выпустить декрипторы.

Вариант 2: Только асимметричное шифрование (RSA)

  • Безопасно: Публичный ключ шифрует, приватный (для расшифровки) никогда не передается жертве.
  • Медленно: Одна операция RSA-2048 занимает ~100 ms. На диске с 100,000 файлов это займет 2.7 часа чистого времени процессора.
  • Зависимость: Требует интернет для скачивания уникального публичного ключа или генерации пар.
  • Результат: Если компьютер offline → ransomware зависает или не может работать.

Вариант 3: Гибридное шифрование (HYBRID)

  • Быстро: Для шифрования тела файлов используется AES.
  • Безопасно: AES-ключ шифруется асимметричным алгоритмом (RSA/ECC), приватный ключ находится у атакующего.
  • Автономно: Работает offline, так как ключи генерируются локально.
  • Риск: Уязвимость существует только в момент генерации ключа в оперативной памяти (ОЗУ).

Все современные семейства ransomware (LockBit, Conti, BlackCat) используют Вариант 3. Мы разберем, почему это дает нам шанс.


Часть II: Гибридное шифрование — простым языком

Упрощённая аналогия с почтовым ящиком

Чтобы понять механику атаки, представим следующую ситуацию:

  • Ваш дом = Компьютер жертвы.
  • Ваши письма = Файлы (документы, фото, базы данных).
  • Золотой ключ от ящика = AES-256 (симметричный ключ).
  • Публичный почтовый замок = RSA Public Key (вшит в код malware).
  • Приватный мастер-ключ = RSA Private Key (находится только у хакера).

Процесс атаки выглядит так:

  • Вторжение: Ransomware приходит в ваш дом (компьютер).
  • Генерация: Создает «Золотой ключ», уникальный именно для вашего дома (AES-256).
  • Шифрование данных: Запирает все письма «Золотым ключом». Это происходит быстро.
  • Защита ключа: Берёт «Золотой ключ» и кладёт его в специальный контейнер, запирая его Публичным почтовым замком (RSA). Это медленная операция, но так как ключ маленький (32 байта), это не тормозит процесс.
  • Доставка требования: Оставляет запечатанный контейнер (зашифрованный ключ) в вашем почтовом ящике — технически это метаданные в конце зашифрованного файла.
  • Уничтожение улик: Сжигает оригинальный «Золотой ключ» — удаляет plaintext-ключ из памяти и с диска.
  • Отход: Уходит. У атакующего есть только мастер-ключ.

Текущая ситуация:

  • Вы видите запечатанный ключ, но не можете его открыть (нет приватного RSA).
  • Письма запечатаны, и вы не можете их прочитать без «Золотого ключа».
  • Attacker имеет мастер-ключ и может открыть замок, достать «Золотой ключ» и расшифровать всё.

Наша работа как форензика: Найти копию или обгоревшего остатка этого «Золотого ключа» в мусоре (памяти) ДО того, как он был окончательно уничтожен.


Часть III: Симметричный ключ — «Золотой ключ»

AES-256: Главное оружие

AES (Advanced Encryption Standard) — это стандарт, используемый военными, банками и криптовалютами. Теперь это стандарт и для киберпреступников.
256 бит означают 256 нулей и единиц, случайно выбранных компьютером. Данные проходят 14 раундов трансформации.

Почему именно AES?

ПараметрAESChaCha20Twofish
Скорость3–5 GB/s (аппаратное ускорение AES-NI)1.3 GB/s (всегда программно)0.3 GB/s
БезопасностьСтандарт NISTБоков-безопасенРедко используется
Популярность в Ransomware80% семейств15% (BlueSky, Babuk)<5% (устаревший)
Уязвимость (Брутфорс)
2^256

попыток (невозможно)

2^256

попыток (невозможно)

2^128

(медленнее)

Как ключ генерируется в памяти

В момент инфекции происходит следующий процесс на низком уровне:

  • Компьютер вызывает криптографически стойкий генератор: CryptGenRandom() (Windows) или /dev/urandom (Linux).
  • Система выдаёт 32 байта (256 бит) полностью случайных данных.
  • Эти 32 байта становятся Master AES Key.
  • Процессор берёт этот ключ и производит процедуру Key Schedule Expansion:
    • Из 32 байт создаёт массив размером 176 байт (44 раундовых ключа).
    • Каждый раундовый ключ используется в одном из раундов шифрования.
  • Процессор использует этот расширенный ключ для шифрования КАЖДОГО ФАЙЛА.
  • После окончания работы (обычно через 5–30 минут) ключ должен быть стёрт.

Где находится ключ в памяти?

Типичное расположение в Heap (куче) памяти процесса Windows:

[Heap memory процесса ransomware]
    ├─ Original AES key (32 байта) - ЕСЛИ генерируется на лету
    │  Offset: 0x12345678
    │  Content: 6A9B3F2D...E8C7B9A3
    │
    ├─ Expanded AES keys (176 байт = 44 round keys * 4 bytes)
    │  Offset: 0x123456A0 (обычно рядом с оригиналом)
    │  Content: сложная структура с раундовыми ключами
    │
    └─ Временные буферы для шифрования
       Offset: различные
       Content: plaintext файлов перед шифрованием

Временное окно возможности (Time of Opportunity)

Почему форензики могут найти ключ:

  • 0 минут: Процесс запущен, генерирует первый ключ → ключ в памяти
  • 5 минут: Генерирует 5-й файл, ключ процесса всё ещё в памяти
  • 15 минут: Генерирует 15-й файл → ключ ещё в памяти
  • 30 минут: Шифрование завершено → ключ ДОЛЖЕН быть удалён (но часто остаются остатки/артефакты).
  • 60 минут: Процесс завершён → память помечена как свободная, может быть перезаписана
  • 120 минут / Перезагрузка: Питание отключено, ВСЯ ОЗУ стёрта

Вывод: Если вы создадите дамп памяти в течение первых 30–60 минут после начала инцидента, вероятность найти ключ составляет > 80%. Если дамп сделан через 2+ часа: вероятность падает ниже 5%.


Часть IV: Асимметричный шифровальщик — Мастер-ключи

RSA-2048: Публичный + Приватный

Концепция асимметрии в ransomware:

  • Attacker генерирует пару ключей.
  • Публичный ключ (PUBLIC KEY):
    • Можно отдавать кому угодно.
    • Вшивается в исполняемый файл malware.
    • Используется ТОЛЬКО для шифрования AES-ключа.
    • Зашифровать данные может кто угодно (сам вирус).
  • Приватный ключ (PRIVATE KEY):
    • Держится в секрете у attacker.
    • Никогда не покидает C2-сервер.
    • Используется ТОЛЬКО для расшифровки.

Сравнение алгоритмов:

РазмерДлина ключаВремя на операциюБрутфорс (сложность)
RSA-10241024 бита10 ms
2^512

операций (Считается взломанной!)

RSA-20482048 бит100 ms
2^1024

операций (Безопасна)

RSA-40964096 бит500 ms
2^2048

операций (Очень безопасна)

Curve25519256 бит50 ms
2^128

операций (Быстрее RSA, надежно)

Почему Curve25519 лучше?

Эллиптическая криптография (ECC) использует математику кривых, а не факторизацию больших чисел. 256-битная кривая эквивалентна 3072-битной RSA по безопасности, но:

  • Быстрее (50 ms против 100 ms).
  • Ключи меньше (32 байта против 256 байт).
  • Меньше векторов атак (side-channels).

Использование в семействах Ransomware:

СемействоАсимметричный алгоритмПримечание
LockBit 3.0RSA-2048Per-victim pair (пара ключей на жертву)
ContiRSA-4096Повышенная безопасность
WannaCryRSA-2048Реализация была уязвима (взломано)
NotPetyaRSA-1024УЯЗВИМ! (1024 бита можно факторизовать)
BlueSky/BabukCurve25519Современный подход (ECC)
Ragnar LockerRSA-2048Per-victim pair

Часть V: Процесс гибридного шифрования в деталях

Разберем пошаговую схему на примере реального поведения LockBit 3.0.

ИНИЦИАЛИЗАЦИЯ

Шаг 1: Генерируется симметричный ключ

  • Вызов: CryptGenRandom(32 bytes)
  • Результат: AES_MASTER_KEY[256 bits] = "6A9B3F2D...E8C7B9A3"
  • Хранилище: heap память процесса (адрес 0x12345678)

Шаг 2: Загружается публичный ключ RSA (встроен в malware)

  • Из resource раздела: .rsrc section
  • Декодируется из Base64
  • Импортируется: CryptImportPublicKeyInfo()

ШИФРОВАНИЕ ФАЙЛА (повторяется для каждого файла)

Шаг 3: Открыть файл на чтение

  • Файл: "document.docx" (10 MB)
  • Режим: read entire file into buffer

Шаг 4: Зашифровать файл с AES

  • Режим: CBC (Cipher Block Chaining)
  • IV (Initialization Vector): 16 random bytes
  • Алгоритм: AES-256-CBC с AES_MASTER_KEY
  • Время: ~3 секунды (на современном CPU)
  • Результат: encrypted_data[10 MB]

Шаг 5: Шифровать сам AES ключ

  • Берём: AES_MASTER_KEY[32 bytes]
  • Шифруем: CryptEncrypt(AES_MASTER_KEY, RSA_PUBLIC_KEY)
  • Время: ~100 ms (медленно!)
  • Результат: encrypted_aes_key[256 bytes] (выход RSA-2048 всегда 256 байт)

Шаг 6: Записать шифрованный файл + ключ

  • Файл: "document.docx.locked"
  • Содержимое:
    • encrypted_data[10 MB]
    • encrypted_aes_key[256 bytes] ← зашифрованный ключ
    • footer with metadata
  • Оригинальный файл: удалён SecureDeleteFile()

Шаг 7: Удалить оригинальный AES ключ из памяти

  • Если хороший malware: memset_s(AES_MASTER_KEY, 0, 32)
  • Если плохой malware: просто «забыл» о переменной (утечка памяти)
  • Результат: память может быть перезаписана ОС

ПОВТОРЕНИЕ

Повторить шаги 3–7 для каждого файла в системе.

  • Результат: 100,000 файлов * (3 sec encryption + 0.1 sec RSA) = ~5 часов работы.

ФИНАЛИЗАЦИЯ

Шаг 8: Удалить процесс (обычно)

  • Процесс завершён: taskkill /IM ransomware.exe
  • При этом ОЗУ, используемая процессом, помечается свободной и может быть перезаписана другими приложениями.
  • Но остатки часто остаются в unallocated memory.

Шаг 9: Оставить ransom note

  • Файл: RECOVERY_INFO.txt
  • Содержимое: "Your files encrypted. Contact us..."

Ключевой момент: Per-File vs Per-Victim

Старый подход (Per-Victim — один ключ на все файлы):

[Ransomware запущен]
    └─ AES_KEY_FOR_ALL_FILES = CryptGenRandom()
         └─ Зашифровать: file1, file2, file3, ..., file100000
              └─ ВСЕХ используем один и тот же AES_KEY_FOR_ALL_FILES
  • Проблема форензика: Найти один ключ → восстановлены ВСЕ 100,000 файлов.
  • Преимущество: Нужно найти всего 32 байта в 16 ГБ памяти.

Новый подход (Per-File — разные ключи):

[Ransomware запущен]
    ├─ file1.aes = CryptGenRandom() → encrypt file1 → delete file1.aes
    ├─ file2.aes = CryptGenRandom() → encrypt file2 → delete file2.aes
    ├─ file3.aes = CryptGenRandom() → encrypt file3 → delete file3.aes
    └─ ...
  • Проблема форензика: Нужно найти 100,000 разных ключей (практически невозможно).
  • Преимущество: Если убить процесс на 30-м файле, можно восстановить только эти 30 файлов, чьи ключи еще «горячие» в памяти.
  • Примечание: LockBit 3.0 использует per-file подход, но иногда сохраняет последние использованные ключи в стеке памяти.

Часть VI: Поиск ключа в памяти

Метод 1: Поиск по энтропии

Теория:
Все данные в компьютере имеют определённую энтропию (меру хаотичности):

  • Текстовый файл (ABCDEFG...): энтропия ~4–5 bits/byte (много повторяющихся символов).
  • Изображение JPG (сжатое): энтропия ~7–7.5 bits/byte (выглядит как шум).
  • AES ключ (32 случайных байта): энтропия ~7.9–8.0 bits/byte (максимально случайные данные).

По формуле Шеннона для AES ключа (256 random bits) каждый из 256 возможных байтов встречается примерно 1 раз, что дает энтропию близкую к 8.0.

Python-код для расчета энтропии:

import math

def calculate_entropy(data):
    entropy = 0
    for i in range(256):
        freq = data.count(bytes([i])) / len(data)
        if freq > 0:
            entropy -= freq * math.log2(freq)
    return entropy

# Пример
aes_key = bytes.fromhex("6A9B3F2D...E8C7B9A3")  # 32 bytes random
entropy = calculate_entropy(aes_key)
print(f"Entropy: {entropy:.2f} bits/byte")
# Output: Entropy: 7.95 bits/byte ← это точно кандидат в ключи!

Практическое применение:

# Используя Volatility для сканирования дампа
volatility -f memory.dump --profile=Win10x64_19041 \
  filescan --entropy-threshold 7.8 > potential_keys.txt

# Вручную через Python (one-liner)
python3 -c "
import struct, math
data = open('memory.dump', 'rb').read()
for i in range(0, len(data)-32, 16):
    chunk = data[i:i+32]
    # Быстрый entropy calculation
    counts = [chunk.count(bytes([j])) for j in range(256)]
    entropy = sum(-c/32 * math.log2(c/32+1e-10) for c in counts if c)
    if entropy > 7.8:
        print(f'Offset 0x{i:x}: {chunk.hex()}')
"

Метод 2: Поиск по структурным паттернам (Round Keys)

Теория:
Когда AES-ключ инициализируется, он расширяется в памяти в предсказуемый паттерн:

Original AES-256 key (32 bytes):
[Master Key: 32 random bytes]

Expanded Round Keys (176 bytes = 44 words * 4 bytes):
[RoundKey0: 4 32-bit words]
[RoundKey1: 4 32-bit words]
...
[RoundKey13: 4 32-bit words]

Каждый Round Key создается с использованием S-box (таблицы подстановок) и констант. Это создает математическую связь между блоками памяти, которую можно проверить.

Python-скрипт для Pattern Matching:

def find_aes_key_by_expansion(memory_dump):
    """
    Find AES-256 by looking for key schedule expansion pattern
    """
    import itertools
    
    # Ищем 256-битный блок с последующим 176-битным (round keys)
    for offset in range(0, len(memory_dump) - 208, 16):
        # Получить предполагаемый master key
        master_key = memory_dump[offset:offset+32]
        
        # Вычислить expected round keys (псевдокод функции расширения)
        expected_rounds = aes_key_schedule_expansion(master_key)
        
        # Проверить, совпадает ли с памятью
        if memory_dump[offset+32:offset+32+176] == expected_rounds:
            print(f"FOUND AES KEY at offset 0x{offset:x}:")
            print(f"  Master Key: {master_key.hex()}")
            return master_key
    return None

def aes_key_schedule_expansion(key):
    """
    Используя известный AES алгоритм,
    рассчитывает, какие круглые ключи должны получиться
    """
    # Используем PyCryptodome для симуляции
    from Crypto.Cipher import AES
    
    # Хак: создаём AES объект и извлекаем expanded keys (через internal structs)
    cipher = AES.new(key, AES.MODE_ECB)
    return cipher_internal_expansion # (упрощено для примера)

Метод 3: Использование aeskeyfind

aeskeyfind — это специализированный Open Source инструмент на C, который реализует поиск по расширению ключей максимально эффективно.

# Установка
sudo apt install aeskeyfind

# Использование
aeskeyfind memory.dump > found_keys.txt

# Пример вывода
# aeskeyfind 1.1
# 
# Address: 0x4d8080 (little endian)
# 6A9B3F2DE8C7B9A32F5D1E8C0A6B3F2D E8F9A0B1C2D3E4F5061728394A5B6C7D
#
# Address: 0x5e2040 (little endian)
# 2F5D1E8C0A6B3F2D6A9B3F2DE8C7B9A3 (partial key)

Интерпретация результатов:

  • Little endian vs Big endian: AES ключи могут храниться в памяти в разном порядке байтов.
  • Полный ключ vs Partial: Если найдено 32 байта подряд с корректным расширением → это точно ключ.
  • Количество: 1–5 результатов — отличный признак. 100+ результатов — много ложных срабатываний (false positives).

Часть VII: От ключа к файлам — Дешифрование

Шаг 1: Проверка найденного ключа

Не все 32-байтные блоки с высокой энтропией — это ключи от ваших файлов. Нужна верификация на реальном зашифрованном файле.

#!/usr/bin/env python3
from Crypto.Cipher import AES
import os

def verify_aes_key(key, sample_encrypted_file):
    """
    Verify if the key correctly decrypts a known file
    """
    try:
        # Читаем зашифрованный файл
        with open(sample_encrypted_file, 'rb') as f:
            # Берём first 16 bytes (первый AES блок в CBC mode)
            ciphertext_block = f.read(16)
            # Прочитаем IV из footer файла (смещение зависит от ransomware!)
            f.seek(-256-16-20, 2)  # размеры: 256 (RSA) + 16 (IV) + 20 (footer)
            iv_encrypted = f.read(16)
        
        # Попытаемся расшифровать
        cipher = AES.new(key, AES.MODE_CBC, iv_encrypted)
        plaintext = cipher.decrypt(ciphertext_block)
        
        # Проверяем, выглядит ли результат как валидный файл
        # PDF начинается с "%PDF", ZIP с "PK"
        if plaintext[:4] == b'%PDF' or plaintext[:2] == b'PK':
            print(f"✓ KEY VERIFIED: {key.hex()}")
            return True
        else:
            print(f"✗ Key не подходит (plaintext: {plaintext[:4].hex()})")
            return False
    except Exception as e:
        print(f"✗ Error: {e}")
        return False

# Использование
key = bytes.fromhex("6A9B3F2DE8C7B9A32F5D1E8C0A6B3F2DE8F9A0B1C2D3E4F5061728394A5B6C7D")
if verify_aes_key(key, "document.docx.locked"):
    print("Ключ работает! Можно расшифровать файлы")

Шаг 2: Расшифровка одного файла

#!/usr/bin/env python3
from Crypto.Cipher import AES
import sys

def decrypt_file(key, encrypted_file, output_file):
    """
    Decrypt a file encrypted with AES-256-CBC
    """
    # Инициализация пустым режимом, IV добавим позже
    cipher = AES.new(key, AES.MODE_CBC)
    
    with open(encrypted_file, 'rb') as f_in, open(output_file, 'wb') as f_out:
        # Читаем IV (обычно в начале файла или в конце, здесь предполагаем начало)
        iv = f_in.read(16)
        
        # Создаём новый cipher с правильным IV
        cipher = AES.new(key, AES.MODE_CBC, iv)
        
        # Расшифровываем оставшиеся данные блоками
        while True:
            chunk = f_in.read(4096)
            if not chunk:
                break
            f_out.write(cipher.decrypt(chunk))

# Использование
key = bytes.fromhex("6A9B3F2DE8C7B9A32F5D1E8C0A6B3F2DE8F9A0B1C2D3E4F5061728394A5B6C7D")
decrypt_file(key, "document.docx.locked", "document.docx")
print("✓ Файл расшифрован!")

Шаг 3: Массовая расшифровка (Batch Decrypt)

Если мы нашли несколько ключей (для случая Per-file encryption) или хотим применить один ключ ко всей папке:

#!/usr/bin/env python3
import os
from pathlib import Path
from Crypto.Cipher import AES

def batch_decrypt(keys_dict, encrypted_directory, output_directory):
    """
    Decrypt multiple files using a dictionary of {filename: key}
    """
    os.makedirs(output_directory, exist_ok=True)
    
    for enc_file in Path(encrypted_directory).glob("*"):
        if enc_file.suffix == ".locked":
            original_name = enc_file.stem
            
            # Получить ключ для этого файла по имени
            if original_name in keys_dict:
                key = keys_dict[original_name]
                
                # Расшифровать
                output_path = Path(output_directory) / original_name
                decrypt_file(key, str(enc_file), str(output_path))
                print(f"✓ Decrypted: {original_name}")
            else:
                print(f"✗ No key found for: {original_name}")

# Словарь ключей (извлеченный из дампа памяти)
keys = {
    "document.docx": bytes.fromhex("6A9B3F2D..."),
    "photo.jpg": bytes.fromhex("2F5D1E8C..."),
}
batch_decrypt(keys, "/path/to/encrypted", "/path/to/recovered")

Часть VIII: Почему форензика часто НЕ работает

Фактор 1: Временное окно (Time decay)

Момент времениСостояние процессаВероятность найти ключ
0–5 минутИдёт шифрование95–100%
5–15 минутИдёт шифрование80–95%
15–30 минутПочти завершено40–70%
30–60 минутЗавершено, удаляется20–40%
60–120 минутУдалено, память перезанята<10%
После перезагрузкиОЗУ полностью стёрта<1%

Реальный сценарий:
14:00 — Инфекция.
14:15 — IT обнаруживает аномалию.
14:30 — Одобрение руководства.
14:45 — Изоляция сети.
15:00 — Начало снятия дампа.
15:30 — Дамп готов. (Прошло 1.5 часа → шанс на успех всего 30-40%).

Оптимальный сценарий: Автоматический триггер EDR снимает дамп при обнаружении ransomware поведения за <5 минут.

Фактор 2: Защита от Key Extraction

Per-file key deletion:
Хорошо написанный код вируса делает следующее:

// Хороший ransomware (защита от форензики)
for (file in files_to_encrypt) {
    file_key = CryptGenRandom();  // Generate
    encrypt_file(file, file_key);  // Encrypt
    memset_s(file_key, 0, 32);    // IMMEDIATELY DELETE from memory
}
// Результат: через 1 минуту форензики не найдут ключи от прошлых файлов

Secure Key Deletion:
Использование Windows API или .NET CryptographicOperations::ZeroMemory(), которые перезаписывают память нулями, затем случайными данными, затем снова нулями, делая восстановление невозможным даже физически (Cold Boot Attack).

Фактор 3: Intel SGX (Software Guard Extensions)

Обычный процесс:
[User Mode] → [Kernel Memory] → [Hardware]
Форензик может читать всё в User/Kernel mode.

С Intel SGX:
[User Mode] → (Не может прочитать) → [SGX Enclave - protected by CPU]
Даже ядро (Kernel) не может прочитать память внутри анклава.

  • Защита: Ключ генерируется ВНУТРИ анклава, никогда не видимого ОС.
  • Использование: Редко (требует совместимого CPU, компиляции, включения пользователем).

Часть IX: Реальные примеры

Пример 1: NotPetya (2017) — Успех форензиков 

  • Почему ключ найден: Использовал один ключ для ВСЕХ файлов (не per-file).
  • Ошибки: Использовал Salsa20 для шифрования MFT, генерировал ключ один раз в начале и не удалял его корректно.
  • Elastic Defend: Исследователи смогли захватить ключ через хук функции CryptGenRandom().
  • Результат: Found key: 2A3B4C...ALL FILES RECOVERED.

Пример 2: WannaCry (2017) — Трудность форензиков 

  • Сложность: Per-file keys (разные для каждого файла).
  • Реализация: Использовал CryptGenRandom() с трюками привязки к ядрам CPU. Ключи удалялись после использования.
  • Результат: Найдены ключи только для ~5% файлов (тех, что шифровались в момент снятия дампа). Для остальных — требовался бэкап.

Пример 3: LockBit 4.0 — Отказ форензиков 

  • Сложность: Per-file keys. Использование Curve25519 (ECC) вместо RSA.
  • Защита: Немедленное удаление ключа (memset). Прерывистое шифрование (Intermittent encryption) — шифрует только 10% файла, процесс идет очень быстро, ключ не задерживается в памяти.
  • Quiet mode: Нет записки с требованием выкупа до конца процесса, меньше артефактов.
  • Результат: Found keys: 0%. Восстановление невозможно без приватного ключа.

Заключение: Иерархия надежды

Когда происходит ransomware атака, ваши действия должны следовать четкой иерархии:

Уровень 1 — Резервные копии (ПЛАН A)

  • Вероятность: 100%.
  • Время: Часы.
  • Стоимость: 0 USD (инвестиции сделаны заранее).
  • ЭТОТ УРОВЕНЬ НЕ ТРЕБУЕТ ФОРЕНЗИКИ.

Уровень 2 — Готовые декрипторы (ПЛАН B) 

  • Вероятность: 5–30% (только для старых/известных семейств).
  • Время: Часы (поиск на No More Ransom).
  • Инструменты: Emsisoft, Kaspersky, Avast.

Уровень 3 — Форензика памяти (ПЛАН C) 

  • Вероятность: 10–40% (критически зависит от тайминга).
  • Время: Дни-недели.
  • Стоимость: Высокая (экспертиза, время простоя).
  • Требуемые знания: Глубокие (Cryptography, Reverse Engineering, Volatility).

Уровень 4 — Выплата выкупа (ПЛАН D) 

  • Вероятность: 60–70% (риск обмана).
  • Стоимость: Огромная.
  • НЕ РЕКОМЕНДУЕТСЯ.

Уровень 5 — Полная потеря (ПЛАН E) 

  • Вероятность восстановления: 0%.

Главный вывод:
Если у вас нет резервных копий, форензика может стать вашим спасением, но это последний шанс, а не гарантия. Ключ может быть в памяти, а может и не быть. Не полагайтесь на чудо. Инвестируйте в резервные копии — это единственный способ пережить атаку ransomware с гарантией 100%.

Как вам статья?

Следующий пост

Аудит ОАЦ: Инсайды от пентестера. Как отвечать на каверзные вопросы аудитора и не "завалить" аттестацию

Гайд по прохождению аудита ОАЦ: разбор этапов проверки по Указу №196, скрипты ответов на технические вопросы, ошибки в документации и настройке SIEM/AD

22 января 2026