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

Как я распаковал реальный семпл трояна на собеседовании на реверс-инженера и что спросили после

Как я распаковал реальный семпл трояна на собеседовании на реверс-инженера и что спросили после
Время чтения: 11 мин.

На одном из собеседований в ИБ-компанию мне передали флешку с единственным файлом и сказали: «Два часа, ноутбук, любые инструменты. Расскажите, что делает этот бинарник.» Файл весил 183 КБ. Detect It Easy показал секции UPX0 и UPX1, энтропия основной секции — 7.83. Классическая упаковка. За полтора часа я распаковал семпл, вытащил строки, восстановил таблицу импортов и показал поведение трояна. А потом начались вопросы, которые оказались сложнее самого задания. Ниже — разбор процесса и всё, что стоит знать, если готовишься к тестовому заданию реверс-инженера.

Зачем на собеседовании реверс-инженера дают реальный семпл

Тестовое задание реверс-инженера — не экзамен на знание ассемблера наизусть. Интервьюер наблюдает за процессом: как ты выстраиваешь приоритеты, с какого инструмента начинаешь, замечаешь ли упаковку по косвенным признакам, вовремя ли переключаешься между статическим и динамическим анализом. Результат важен, но путь к нему важнее.

В Лаборатории Касперского, по описанию Алексея Маланова (руководитель отдела антивирусных исследований, опубликовал детальный разбор процесса найма на Хабре), кандидату заранее высылают крэкми — компактный бинарник для домашнего анализа. Некоторые соискатели гуглят имя файла и копируют чужое решение. Вскрывается на первом же уточняющем вопросе о конкретных инструкциях внутри.

На моём собеседовании задание было серьёзнее крэкми: реальный упакованный семпл без подсказок. Вот что оценивалось:

  • Триаж — умение за минуты определить тип файла, архитектуру, наличие упаковки
  • Методичность — последовательная работа по шагам вместо хаотичного тыканья в дизассемблере
  • Выбор инструмента — понимание, когда дизассемблер бесполезен и пора запускать отладчик
  • Коммуникация — способность проговаривать вслух, что видишь и почему принял конкретное решение

Бизнес-логика задания прямая: malware analyst каждый день получает десятки подозрительных файлов. По данным IBM X-Force Threat Intelligence Index 2025, infostealers составляют 32% всего детектируемого malware — и почти каждый использует минимум один слой упаковки. Если каждый семпл анализировать часами — конвейер встанет. Интервьюер проверяет, способен ли кандидат быстро отсеять шум и сосредоточиться на реальном поведении вредоноса.

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

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

Что нужно: Windows-машина или виртуалка с Detect It Easy (DIE) и PE-bear. Оба инструмента бесплатные. На Linux подойдёт radare2.

Первое действие — загрузить файл в DIE. Detect It Easy определяет компилятор, линковщик и пакер по сигнатурам. DIE покажет три вещи:

  • Формат: PE32 или PE64. PE (Portable Executable) — стандартный формат исполняемых файлов Windows
  • Пакер: если файл упакован UPX, ASPack, VMProtect или чем-то кастомным — DIE определит по сигнатуре
  • Энтропия секций: число от 0 до 8. Значение выше 7 говорит о сжатых или зашифрованных данных. Нормальный скомпилированный код — 5–6

В моём случае DIE показал: UPX, энтропия основной секции 7.83. Названия секций подтвердили диагноз — UPX0 (пустая секция, куда распакуется код) и UPX1 (сжатые данные). По данным HackMag, имена секций — один из самых надёжных индикаторов упаковки, хотя авторы малвари могут их переименовывать, чтобы сбить автодетект.

Зачем злоумышленник упаковывает бинарник? Сигнатурный антивирус сравнивает байты файла с базой. Если те же байты сжать или зашифровать — сигнатура перестаёт совпадать. В терминах MITRE ATT&CK (открытая база тактик и техник атак; каждой технике присвоен T-код, например T1027) упаковка — техника Software Packing (T1027.002), подтехника Obfuscated Files or Information (T1027). Самый дешёвый способ обойти статическое детектирование. В реальных атаках упаковка часто становится первым слоем защиты дроппера на этапе initial access — ещё до закрепления и эксфильтрации.

Второй шаг триажа — проверить таблицу импортов. IAT (Import Address Table) — список функций из системных библиотек, которые использует программа. У упакованного файла импортов минимум: обычно только LoadLibraryA и GetProcAddress из kernel32.dll. Этого хватает стабу-распаковщику, чтобы подгрузить всё остальное в рантайме. Легитимная программа импортирует десятки функций, упакованная — две-три. Малое количество импортов плюс высокая энтропия — практически безошибочный диагноз.

Для тех, кто предпочитает командную строку, энтропию секций можно проверить в radare2:

r2 -q -c "iH" suspect.exe

Команда iH выводит заголовки PE-файла с информацией о секциях. Видишь секцию с entropy > 7.0 при минимальном числе импортов — переходи к распаковке.

Распаковка трояна вручную: пошаговый разбор

Упаковка подтверждена. Три стратегии:

  1. Автоматическая: upx -d packed.exe -o unpacked.exe снимает стандартный UPX за секунду
  2. Полуавтоматическая: QuickUnpack или RL!dePacker пытаются найти OEP и сдампить процесс универсальным алгоритмом. Работает не всегда, но иногда экономит время
  3. Ручная: отладчик x64dbg, пошаговое выполнение до OEP, дамп памяти, восстановление IAT

На собеседовании я сознательно не стал запускать upx -d. Интервьюер давал семпл для проверки ручных навыков — автораспаковка заняла бы 30 секунд и ничего не показала бы о квалификации. Ручной подход ниже применим и к кастомным пакерам, когда автоматика бесполезна.

Как найти OEP в отладчике

OEP (Original Entry Point) — адрес, с которого начинается выполнение оригинальной, распакованной программы. Пакер подменяет точку входа на свой стаб — небольшой фрагмент кода-распаковщика. Стаб распаковывает оригинальный код в память, восстанавливает импорты и передаёт управление на OEP.

Механика стаба в упрощённом виде:

; Стаб UPX — пример для демонстрации концепции
pushad              ; сохранить все регистры в стек
mov esi, UPX1_addr  ; источник: сжатые данные
mov edi, UPX0_addr  ; назначение: пустая секция
call unpack_loop    ; цикл распаковки
popad               ; восстановить регистры
jmp OEP             ; передать управление оригинальному коду

Что нужно: x64dbg (бесплатный отладчик для Windows, де-факто стандарт для динамического анализа малвари) установлен в изолированной виртуальной машине. Семпл загружается строго в VM — никогда на хостовой системе.

Шаг 1. Открой семпл в x64dbg. Программа остановится на системной Entry Point. Стаб UPX начинается с инструкции pushad — она сохраняет содержимое всех регистров общего назначения (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) в стек одним вызовом. Первая видимая инструкция должна быть pushad. Если вместо неё что-то другое — пакер модифицирован и стандартный трюк не сработает.

Шаг 2. Выполни pushad (F8 — Step Over). Запомни текущее значение регистра ESP — адрес вершины стека после сохранения регистров. Поставь аппаратный брейкпоинт на доступ к этому адресу: правый клик на значении ESP в панели регистров → Follow in Dump → в окне дампа правый клик на первом байте → Breakpoint → Hardware, Access → DWORD.

Логика такая: стаб сохранил регистры через pushad, провёл распаковку и перед прыжком на OEP выполнит popad — обращение к тому же адресу стека. В этот момент брейкпоинт сработает. Нажми Run (F9).

Шаг 3. Отладчик остановится вблизи инструкции popad. Сделай несколько Step Over (F8), пока не увидишь jmp 0x00XXXXXX — это прыжок на OEP. Нажми Step Into (F7) на этом jmp. Теперь регистр EIP содержит адрес первой инструкции оригинальной программы. Запиши его — понадобится для дампа.

Дамп и восстановление таблицы импортов

Код распакован в памяти, но на диске файл по-прежнему сжат. Нужно сдампить процесс — сохранить содержимое памяти как новый PE-файл — и восстановить IAT, чтобы получить пригодный для анализа бинарник.

Для этого подходит Scylla — бесплатная утилита для реконструкции импортов, встроенная в x64dbg как плагин:

  1. Не закрывая отладчик на OEP, открой Scylla через меню Plugins → Scylla
  2. Убедись, что в поле OEP указан найденный адрес. Если поле пустое — впиши вручную
  3. Нажми «IAT Autosearch» — Scylla просканирует память процесса и найдёт границы таблицы импортов
  4. Нажми «Get Imports» — на экране появится дерево восстановленных API-функций по DLL. Часть импортов помечена как невалидная? Нажми «Show Invalid» и удали битые записи
  5. Нажми «Dump» → укажи имя нового файла → затем «Fix Dump» — Scylla пропатчит дамп и впишет восстановленную IAT

Результат: новый PE-файл, который DIE определяет без пакера. Энтропия секций упала до 5–6. Таблица импортов теперь содержит десятки функций: CreateFileA, WriteFile, InternetOpenA, RegSetValueExA — реальное поведение трояна стало видно на уровне API.

В терминах MITRE ATT&CK троян при запуске выполняет T1140 (Deobfuscate/Decode Files or Information) — деобфусцирует собственный код в памяти. Мы повторили этот процесс под контролем отладчика и получили чистый бинарник для дальнейшего анализа.

Вопросы на собеседовании реверс-инженера после практической части

После демонстрации результатов распаковки (троян закреплялся через реестр и связывался с C2-сервером по HTTP) начались теоретические вопросы. Каждый привязан к конкретной рабочей задаче — интервьюер проверяет не эрудицию, а умение применить знание в бою.

«Как малварь определяет, что работает под отладчиком?»

Вопрос про anti-debug — техники обнаружения анализа. В MITRE ATT&CK это Debugger Evasion (T1622). Основные методы:

  • IsDebuggerPresent() — WinAPI-функция, проверяющая флаг BeingDebugged в PEB (Process Environment Block — служебная структура, которую ОС создаёт для каждого процесса)
  • Проверка NtGlobalFlag в PEB — при отладке содержит значение 0x70 вместо нулевого
  • Timing checks — замер времени через инструкцию rdtsc (считывает счётчик тактов процессора): под отладчиком пошаговое выполнение медленнее, разница во времени выдаёт дебаггер

Похожие по смыслу, но шире — проверки на виртуализацию и песочницу (T1497 — Virtualization/Sandbox Evasion). Малварь может искать артефакты VM: специфические MAC-адреса, имена процессов VMware Tools или VirtualBox Guest Additions, характерные значения CPUID.

Правильный ответ включает не только перечисление, но и способы обхода. Плагин ScyllaHide для x64dbg патчит PEB-флаги и перехватывает API-вызовы, скрывая факт отладки от проверяемого процесса.

«Что такое API hashing и зачем это нужно?»

Малварь не хранит имена функций в открытом виде (как CreateFileA), а сохраняет их хеши — числовые значения, вычисленные по имени функции. При запуске вредонос перебирает экспортируемые функции загруженных DLL, хеширует каждое имя и сравнивает результат с сохранённым значением. Совпало — функция найдена. Это убивает статический анализ: в строках и таблице импортов нет ничего читаемого.

Зачем спрашивают: если кандидат знает про API hashing, он справится с серьёзными семплами, где DIE и утилита strings ничего полезного не покажут.

«Объясни разницу между секциями .text, .data, .rdata и .rsrc в PE-файле.»

Базовый вопрос на понимание PE-формата:

Секция Содержимое Права доступа
.text Исполняемый код (машинные инструкции) Execute + Read
.data Изменяемые глобальные переменные Read + Write
.rdata Константы, таблица импортов Read only
.rsrc Ресурсы: иконки, строки, манифесты. Иногда — зашифрованный пейлоад второй стадии Read only

«Какие WinAPI-функции поставишь на брейкпоинт при анализе неизвестного семпла?»

Ключевой практический вопрос. Ответ — по категориям поведения:

Категория Функции для breakpoint
Файловая система CreateFileA/W, WriteFile, DeleteFileA
Сеть InternetOpenA, HttpSendRequestA, WSAStartup
Реестр RegSetValueExA, RegCreateKeyExA
Процессы и инъекция CreateProcessA, VirtualAllocEx, WriteProcessMemory
Антианализ IsDebuggerPresent, GetTickCount, Sleep

VirtualAlloc и VirtualProtect особенно важны при распаковке: через них малварь выделяет память и меняет права доступа перед записью распакованного кода. Брейкпоинт на VirtualProtect с аргументом PAGE_EXECUTE_READWRITE (0x40) — стандартный приём для перехвата момента, когда пейлоад готов к исполнению. Эта механика связана с Process Injection (T1055) — внедрение кода в чужой процесс для маскировки или повышения привилегий.

Что выдаёт новичка на собеседовании malware analyst

Прыжок в IDA без триажа. Кандидат открывает файл в дизассемблере и 40 минут блуждает по коду стаба пакера. Стаб — обёртка, не сам вредонос. Пять минут в DIE с проверкой энтропии и импортов сэкономили бы это время.

Незнание энтропии. На вопрос «почему решил, что файл упакован?» ответ «секции называются UPX» — слабый. Ответ «энтропия секции 7.83 указывает на сжатые данные, плюс в IAT всего два импорта из kernel32» — сильный. Авторы малвари переименовывают секции. Энтропия не обманет.

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

Игнорирование anti-debug. Семпл завершился при запуске в отладчике — кандидат растерялся. Проверка IsDebuggerPresent (T1622) — первое, что стоит обойти. В x64dbg достаточно включить ScyllaHide с профилем Basic.

Отсутствие привычки документировать. Не записывать адреса, хеши, найденные строки по ходу анализа — через час работы кандидат не может вспомнить адрес OEP. В ежедневной работе аналитика без структурированных заметок не продержаться и дня.

Интервьюер из Касперского (по описанию Маланова) добавил бы к техническим вопросам задачу на внимательность: «Верно ли, что если 6/a < 3, то a > 2?» Ответ «верно» — ошибка: переменная a может быть отрицательной. Это не про математику, а про привычку проверять граничные условия. В реверсе один пропущенный edge case в анализе ветвления — и вся картина поведения вредоноса рассыпается.

Тестовое задание на распаковку — не финальный экзамен, а начало разговора. Реальная ценность кандидата проявляется в вопросах после: API hashing, anti-debug обход, PE-структура — всё это отделяет человека, который посмотрел один tutorial на YouTube, от того, кто разобрал двадцать семплов руками.

Моя позиция жёсткая: 90% подготовки к собеседованию на malware analyst — не зубрёжка вопросов-ответов, а практика с живыми семплами. Десять файлов с MalwareBazaar через цепочку DIE → x64dbg → Scylla → Ghidra. После пятого распакованного инфостилера процесс станет мышечной памятью, а на собеседовании ты будешь объяснять механику, а не вспоминать чужие инструкции. Через пару лет автоматизация закроет тривиальные случаи — стандартный UPX, типовой ASPack. Кастомные крипторы, VM-протекторы, многослойная упаковка по-прежнему будут требовать ручной работы — и именно эти навыки проверяют на собеседовании. Если ищешь джуниор-роль и хочешь выстроить базу системно — на codeby.school есть IB Basics, а пара десятков разобранных семплов дадут что показать на собесе.

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