Перейти к содержимому

Анализ вредоносного ПО: разбор дампа крипто-стилера — где тонет самоучка без структуры IDA и Ghidra

Анализ вредоносного ПО: разбор дампа крипто-стилера — где тонет самоучка без структуры IDA и Ghidra
Время чтения: 11 мин.

По данным IBM X-Force Threat Intelligence Index 2025, инфостилеры вышли на первое место среди всех типов вредоносного ПО — 32% образцов за 2024 год, обогнав ransomware. Стилер — программа, которая ворует данные: пароли из браузеров, cookie-сессии, ключи от криптокошельков, содержимое буфера обмена. Разобрать такой семпл — задача, которая звучит понятно: открыть дизассемблер, найти функции кражи, извлечь адреса C2-сервера (Command & Control — сервер управления, куда стилер отправляет украденные данные). А на практике новичок открывает Ghidra, видит 1200 функций с именами вроде FUN_00401a3c, 15 минут крутит граф вызовов — и закрывает программу. Проблема не в инструменте. Проблема в отсутствии структуры анализа. Дальше покажу конкретный workflow реверс-инжиниринга крипто-стилера: от триажа до извлечения C2-адресов, и разберу точки, на которых самоучка буксует.

Бизнес-логика крипто-стилера: зачем разбирать и кому это нужно

Перед тем как лезть в дизассемблер, стоит понимать цепочку монетизации. Крипто-стилер — не самостоятельная атака, а звено конвейера:

  1. Доставка — фишинговое письмо, фейковый «крякнутый» софт, вредоносная реклама в поисковой выдаче
  2. Установка — дроппер распаковывает и запускает стилер в системе жертвы
  3. Сбор — стилер обходит файлы браузеров, кошельков, буфер обмена, иногда делает скриншот рабочего стола
  4. Эксфильтрация — собранные данные шифруются и уходят на C2
  5. Монетизация — оператор продаёт «логи» (пачки украденных данных) на теневых маркетплейсах или сам выводит криптовалюту

Задача аналитика — извлечь артефакты на шагах 3 и 4: что именно ворует стилер, куда отправляет, по какому протоколу. Эти данные превращаются в detection-правила для SOC (Security Operations Center — центр мониторинга безопасности) и в IoC (индикаторы компрометации — IP-адреса, URL, хеши файлов), по которым стилер блокируется в инфраструктуре.

Структура анализа бинарного файла: что видит новичок и почему теряется

Допустим, распакованный дамп уже получен — PE-файл (Portable Executable — стандартный формат исполняемых файлов Windows). Упаковщик снят, бинарник готов к анализу. Вы загрузили его в Ghidra (бесплатный декомпилятор от NSA) или IDA Pro (коммерческий стандарт индустрии с декомпилятором Hex-Rays).

Первое, что видит новичок — дерево функций слева: сотни записей. Большинство — сгенерированные имена: sub_00401000, FUN_004023a8. Декомпилятор справа показывает псевдокод, похожий на C, но переменные называются iVar1, uVar2, local_28. Граф вызовов — паутина без начала и конца.

Типичная реакция: начать читать код с первой функции и двигаться вниз. Это ловушка. В бинарнике на 500 КБ может быть 300–500 функций, из которых реально нужны 15–20. Остальное — обёртки CRT (C Runtime — стандартная библиотека языка C), инициализация, обработка ошибок, мусорный код от компилятора. Без понимания структуры PE-файла и методики навигации вы утонете за двадцать минут.

Структура PE — каркас, от которого зависит весь дальнейший анализ вредоносного ПО:

Секция Что хранит На что обращать внимание
.text Исполняемый код Логика стилера: сбор, шифрование, отправка
.data Глобальные переменные Зашифрованные конфиги, ключи
.rdata Read-only данные Строковые литералы, таблица импортов, константы
.rsrc Ресурсы Иконки, манифесты, иногда зашифрованный payload

Если энтропия (мера случайности данных, шкала 0–8) секции .text выше 7.0 — код, скорее всего, ещё упакован или обфусцирован. Декомпилятор покажет мусор, а вы потратите часы, пытаясь прочесть нечитаемое. Проверьте это до погружения в псевдокод. Серьёзно — это первое, что нужно сделать.

Статический анализ малвари: триаж за 15 минут до дизассемблера

Реверс-инжиниринг вредоносного ПО не начинается с IDA Pro. Он начинается с триажа — быстрой оценки образца, которая экономит часы. Вот конкретная последовательность.

Предпосылки: Windows или Linux, установлены Detect It Easy (DiE) и FLOSS (FLARE Obfuscated String Solver от Mandiant — умеет извлекать не только plaintext-строки, но и обфусцированные).

Шаг 1 — вычислить хеши и проверить по базам. sha256sum sample.exe (Linux) или Get-FileHash sample.exe (PowerShell). Полученный SHA-256 проверяете на VirusTotal. Если образец уже проанализирован — смотрите, какие антивирусы его детектят и под каким семейством. Это даёт начальную гипотезу: «скорее всего RedLine» или «похоже на Lumma Stealer». На выходе: строка из 64 hex-символов и хотя бы приблизительная классификация.

Шаг 2 — определить компилятор и упаковщик. Открываете образец в Detect It Easy. DiE покажет: компилятор (MSVC, MinGW, .NET), возможный упаковщик (UPX, VMProtect, Themida), энтропию по секциям. Если DiE показывает UPX — распаковка тривиальна: upx -d sample.exe. Кастомный пакер — другое дело: это техника Software Packing (T1027.002 в классификации MITRE ATT&CK — открытая база тактик и техник атак; T-коды вроде T1027 — её идентификаторы, по которым аналитики маппят поведение малвари). С кастомным пакером понадобится динамический дамп из памяти — через отладчик или песочницу. На выходе: название компилятора, наличие или отсутствие пакера, таблица энтропии секций.

Шаг 3 — извлечь строки. floss sample.exe > strings_output.txt. В выводе ищете: URL и IP-адреса (кандидаты на C2), пути к файлам браузеров (\AppData\Local\Google\Chrome\User Data), имена криптокошельков (wallet.dat, Electrum, Exodus), WinAPI-функции (CryptDecrypt, InternetOpenA). Если строк подозрительно мало — конфиг зашифрован. Для крипто-стилера это типично.

На этом этапе у вас уже есть: классификация семейства, понимание упаковки, первичные IoC. Теперь есть смысл открывать дизассемблер.

IDA Pro и Ghidra для анализа крипто-стилера: навигация и декомпиляция малвари

Загрузили распакованный дамп в Ghidra или IDA Pro. IDA отличается зрелым статическим анализом, системой плагинов и огромной базой знаний сообщества. Ghidra бесплатна, включает встроенный декомпилятор, отлично подходит для обучения реверс-инжинирингу и для реальной работы. На уровне разбора типового стилера принципиальной разницы нет — выбор зависит от лицензии и привычки. Я чаще работаю в IDA, но все примеры ниже воспроизводятся в обоих.

Первое, что нужно открыть — таблицу импортов. Импорты — это WinAPI-функции (системные вызовы Windows), которые программа использует. Они работают как карта возможностей малвари:

Группа импортов Что означает Примеры функций
Файловые операции Чтение кошельков, cookie, паролей CreateFileA, ReadFile, FindFirstFileA
Сетевые функции Отправка данных на C2 InternetOpenA, HttpSendRequestA
Криптография Расшифровка конфига или шифрование трафика CryptDecrypt, CryptImportKey
Инжекция в процессы Маскировка в легитимном процессе (T1055 — Process Injection) CreateRemoteThread, WriteProcessMemory

Но у многих стилеров таблица импортов почти пустая. Видите LoadLibraryA и GetProcAddress — и больше ничего полезного. Это Dynamic API Resolution (T1027.007): малварь не прописывает нужные функции в таблице импортов, а загружает их на лету. Декомпилятор покажет (**(code **)local_14)(param1, param2) — вызов по указателю, имя функции потеряно.

Как с этим работать: ищите паттерн «загрузка DLL, затем получение адреса функции». Цепочка вызовов LoadLibraryA("wininet.dll") → GetProcAddress(handle, "InternetOpenA"). В IDA Pro переименуйте переменную, куда записывается результат GetProcAddress, — псевдокод сразу станет читаемым. В Ghidra то же самое: правый клик → Rename Variable. Минута работы — а функция из нечитаемой превращается в понятную. Это одна из тех мелочей, которые отличают «крутил три часа и бросил» от «нашёл C2 за полчаса».

Второй критический навык — cross-references (xrefs — перекрёстные ссылки, показывают, какие функции обращаются к данному адресу или вызывают данную функцию). Нашли строку "wallet.dat" в секции данных? Нажмите X в IDA или правый клик → References To в Ghidra. Увидите все функции, которые обращаются к этой строке. Одна из них — функция сбора крипто-кошельков. Оттуда по xrefs поднимаетесь к вызывающей функции — это диспетчер стилера, который последовательно вызывает модули: браузеры, кошельки, clipboard, скриншоты.

Метод «follow the data» — основа навигации при декомпиляции малвари. Не читайте код линейно от начала до конца. Начните с интересных строк или API-вызовов и двигайтесь по xrefs: вверх к вызывающим функциям, вниз к вызываемым. Стилер — конвейер: сбор → упаковка → шифрование → отправка. Идите по конвейеру, а не по дереву из 400 функций.

Реверс-инжиниринг вредоносного ПО: дешифровка конфига стилера

Крипто-стилер хранит конфигурацию (адрес C2, список целевых кошельков, иногда ключ шифрования для эксфильтрации) в зашифрованном виде — техника Encrypted/Encoded File (T1027.013). На диске данные выглядят как случайный набор байтов, расшифровываются только при запуске.

Задача — найти рутину дешифровки и извлечь конфиг без запуска малвари.

Находим XOR или RC4-рутину

Типичный паттерн: функция принимает указатель на зашифрованный блоб и ключ, итерирует по каждому байту, применяет XOR или RC4, результат записывает в буфер. В декомпиляторе это цикл с побитовой операцией ^:

// Пример для демонстрации концепции — типичный XOR-декрипт
void FUN_00401a3c(byte *data, byte *key, int len, int key_len) {
    int i = 0;
    while (i < len) {
        data[i] = data[i] ^ key[i % key_len];
        i = i + 1;
    }
}

Как найти такую функцию: ищите xrefs к подозрительным блобам данных в секции .data (высокая энтропия, нечитаемые байты). Функция, которая читает блоб и содержит цикл с ^, — кандидат на дешифровку. Проверьте, что результат потом передаётся в сетевые функции или парсится как URL. Это техника Deobfuscate/Decode Files or Information (T1140).

Извлекаем C2 и целевые кошельки

Когда алгоритм найден, ключ и зашифрованные данные извлечены из бинарника — пишете скрипт-расшифровку:

# Пример XOR-декрипта конфига стилера
encrypted = bytes.fromhex("4a2f195c3a0b")
key = b"\x2b\x4e\x78\x3f\x59\x6a"  # ключ из .rdata

decrypted = bytes(
    [e ^ key[i % len(key)] for i, e in enumerate(encrypted)]
)
print(decrypted)  # ожидаемый результат: URL C2 или конфиг

На выходе: читаемые строки — URL управляющего сервера, пути к целевым файлам, список расширений браузеров. Адрес C2 — главный артефакт: с ним команда SOC блокирует домен, а IoC идут в фиды обнаружения. Один XOR-декрипт на десять строк Python — и у вас артефакт, ради которого всё затевалось.

Обучение реверс-инжинирингу: пять ошибок, на которых тонет самоучка

За пару лет работы в лаборатории я наблюдал одни и те же грабли у каждого, кто учился реверсу самостоятельно.

Паника при пустых импортах. Открыли таблицу, увидели три функции, решили что файл повреждён. На деле — Dynamic API Resolution (T1027.007). Малварь резолвит API на лету через GetProcAddress или хеширование имён (CRC32, djb2). Правильная реакция: искать в коде константы-хеши и паттерны вызова LoadLibrary.

Игнорирование anti-analysis. Стилер проверяет, не запущен ли он в отладчике — Debugger Evasion (T1622) — или виртуальной машине — System Checks (T1497.001). Типичное: вызов IsDebuggerPresent, чтение поля BeingDebugged в PEB (Process Environment Block — структура данных процесса Windows), запрос WMI с поиском строк "VMware", "VirtualBox". Самоучка не замечает эти проверки и удивляется, почему малварь «не работает» в песочнице. При статическом анализе достаточно найти такие проверки по xrefs и понять логику ветвления: если условие истинно — стилер завершается или уходит в код-заглушку.

Линейное чтение кода. Самая частая ошибка. Новичок начинает с entry() и пытается прочесть каждую функцию по порядку. В бинарнике 400+ функций — путь в никуда. Правильный подход — follow the data: нашли строку "Chrome" → xref → функция сбора паролей. Нашли вызов InternetOpenA → xref → функция отправки данных. Идите по конвейеру стилера, а не по дереву.

Работа без документирования. Через час вы переименовали 30 функций, нашли три блоба, определили алгоритм. Закрыли Ghidra без сохранения — всё потеряно. Или сохранили, но через неделю не помните, почему FUN_00402100 назвали maybe_c2_send. Правило: каждой переименованной функции — комментарий из одного предложения (; в IDA, правый клик → Set Comment в Ghidra). Параллельно ведите текстовый файл: оффсет, что нашли, гипотеза. Звучит скучно, но через неделю скажете себе спасибо.

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

Маппинг крипто-стилера на MITRE ATT&CK

Когда пишете отчёт об анализе, маппинг поведения стилера на MITRE ATT&CK позволяет команде защиты быстро понять, какие детектирующие правила нужны. Зачем это вам: каждый T-код — ключ к конкретному detection-правилу (Sigma, YARA или правило для EDR). Без маппинга отчёт остаётся набором технических деталей; с маппингом — инструментом, который SOC может взять в работу в тот же день.

Карта типичного крипто-стилера:

Техника T-код Что делает стилер
Software Packing T1027.002 Упаковка бинарника для обхода антивирусов
Dynamic API Resolution T1027.007 Скрытие API от таблицы импортов
Encrypted/Encoded File T1027.013 Шифрование конфига с адресом C2
Deobfuscate/Decode T1140 Расшифровка конфига при запуске
Debugger Evasion T1622 Обнаружение отладчика
System Checks T1497.001 Проверка на VM или песочницу
Process Injection T1055 Инжекция в легитимный процесс для маскировки
Keylogging T1056.001 Перехват нажатий клавиш (не во всех семействах)

Большинство людей, которые бросают реверс-инжиниринг вредоносного ПО после первых попыток, бросают не из-за сложности ассемблера. Они бросают, потому что открывают дизассемблер без плана и тонут в объёме. Workflow — триаж, импорты, xrefs, follow the data, дешифровка конфига — это 80% результата. Оставшиеся 20% — знание ассемблера x86 и специфика конкретного семейства, они нарабатываются практикой на реальных семплах. Я видел, как люди за полгода выходят с нуля на уровень «самостоятельно разбираю типовой стилер и пишу отчёт с IoC» — но только при наличии структуры: последовательность задач с нарастающей сложностью и обратной связью, а не хаотичные попытки между YouTube-роликами. Инструменты — не проблема: Ghidra бесплатна, семплы доступны на MalwareBazaar, документации хватает. Проблема в отсутствии того, кто скажет «эту функцию пропусти, а вон ту разбери по байтам». Самоучки буксуют не на технике, а на навигации — не знают, куда смотреть и что игнорировать. Если ищете структурированный вход в профессию — на IB Basics эта база закрывается за пару месяцев, без воды.

Эту тему и смежные навыки разбирают на практике в курсе «Профессия Реверс-инженер» Codeby Academy.