
На DEFCON 2019 Memory Forensics CTF — challenge, который до сих пор доступен на CyberDefenders — первая задача требовала SHA1-хеш дампа, последняя — текст из Notepad, вытащенный из адресного пространства процесса. Между ними 16 вопросов, каждый завязан на конкретный плагин Volatility. Я проходил этот challenge дважды: в первый раз потерял час на выборе профиля, во второй — уложился в 40 минут. Разница не в знании инструмента, а в понимании порядка действий. Вот этот порядок: от запуска Volatility до извлечения флага, с конкретными командами, разбором ошибок и decision tree для выбора плагинов.
Требования к окружению: Подробнее — в нашем статье о расследование кибератаки.
- ОС: Linux (Kali, SIFT Workstation, Ubuntu 16.04+) или Windows 10+
- RAM: минимум 4 ГБ свободных (тяжёлые плагины вроде yarascan требуют запаса сверх размера дампа)
- Python 2.7 для Volatility 2 или Python 3.8+ для Volatility 3
- Зависимости: pycryptodome, distorm3 (Vol2); pycryptodome (Vol3)
- Дисковое пространство: минимум 2x размера дампа (для выходных файлов memdump, procdump)
Volatility 2 (репозиторий volatilityfoundation/volatility, Python 2, статус: архивный — последний коммит в 2021, активная разработка прекращена) по-прежнему востребован на CTF: подавляющее большинство writeup'ов и forensics-задач заточены под его синтаксис с флагом --profile. Volatility 3 (репозиторий volatilityfoundation/volatility3, Python 3.8+, статус: активная разработка, коммиты в 2024-2025) работает быстрее и определяет ОС автоматически через таблицы символов — без необходимости угадывать профиль.
| Критерий | Volatility 2 | Volatility 3 |
|---|---|---|
| Python | 2.7 (EOL) | 3.8+ |
| Выбор профиля | Ручной через --profile |
Автоматический |
| Количество плагинов | 200+ | Меньше, но активно растёт |
| Скорость | Медленнее | Быстрее на крупных дампах |
| CTF-совместимость | Старые challenge (GrrCon, DEFCON 2019) | Новые challenge, реальный IR |
| Статус поддержки | Архивный | Активная разработка |
| Когда использовать | Writeup требует Vol2-синтаксис; нужен плагин notepad или iehistory |
Новые задачи; нужна скорость; не хочется возиться с профилями |
| Когда НЕ использовать | Нужна скорость и Python 3; challenge на Linux без готового профиля | Challenge явно требует Vol2; нужен специфичный community-плагин |
Установка Vol3: git clone https://github.com/volatilityfoundation/volatility3.git и pip3 install -r requirements.txt. Для Vol2 аналогично: клонируете репозиторий, затем pip2 install distorm3 pycryptodome. На Ubuntu 16.04 установка Vol2 проходит без проблем; на более свежих дистрибутивах Python 2 нужно ставить отдельно — и это отдельное приключение.
На CTF держите оба инструмента. Начинайте с Vol3 — если challenge требует специфичный Vol2-плагин, переключитесь.
Любой анализ дампа памяти Volatility начинается с идентификации операционной системы. Без корректного профиля все последующие плагины либо выдадут мусор, либо упадут с ошибкой. По сути это System Information Discovery (T1082, Discovery) из MITRE ATT&CK, только задом наперёд: атакующий собирает информацию о живой системе, а мы восстанавливаем её по дампу.
Команда vol.py -f memory.dmp imageinfo вернёт список предложенных профилей — например, Win7SP1x64, Win7SP0x64, Win2008R2SP0x64. Какой правильный? Формальный способ — сверить значение KDBG с документацией Microsoft. Быстрый способ — прогнать vol.py -f memory.dmp --profile=Win7SP1x64 pslist с каждым кандидатом: неправильный профиль выдаёт нечитаемые имена процессов или пустой вывод вместо знакомых System, svchost.exe, explorer.exe.
Более надёжная альтернатива — плагин kdbgscan, который анализирует блок отладки ядра и даёт точное совпадение. На практике kdbgscan экономит минуты, которые иначе уходят на тупой перебор профилей.
В Volatility 3 профиль определяется автоматически. Команда python3 vol.py -f memory.dmp windows.info покажет версию Windows, номер сборки, системное время, корневой каталог. Для Linux-дампов — python3 vol.py -f dump.mem banners.Banners выведет строку ядра, по которой можно определить дистрибутив и версию. Если Vol3 не распознаёт образ автоматически, для Linux потребуется ISF (Intermediate Symbol Format) — файл символов, сгенерированный под конкретное ядро. Для Windows готовые символы скачиваются с сервера Microsoft автоматически.
Чтобы не вбивать путь к файлу и профиль каждый раз, настройте окружение перед началом анализа. Для Vol2:
export VOLATILITY_LOCATION=file:///path/to/memory.dmp
export VOLATILITY_PROFILE=Win7SP1x64
# Теперь достаточно: vol.py pslist
# Или через alias:
alias v="vol.py -f /path/to/memory.dmp --profile=Win7SP1x64"
# Использование: v pslist | tee pslist.txt
Для Vol3: alias v3="python3 vol.py -f /path/to/memory.dmp", далее — v3 windows.pslist. Команда tee сохраняет вывод одновременно в терминал и в файл — это критично, потому что тяжёлые плагины работают минуты, и перезапускать их ради повторного grep — потеря времени, которого на CTF и так нет.
После определения профиля — ключевой этап: анализ процессов. В терминах MITRE ATT&CK это Process Discovery (T1057, Discovery). Те же артефакты, которые атакующий оставляет при запуске малвари, форензик-аналитик использует для реконструкции инцидента.
Плагин pslist (Vol2: vol.py pslist, Vol3: python3 vol.py -f dump.mem windows.pslist) выводит все процессы из двусвязного списка PsActiveProcessHead. Ключевые колонки: PID, PPID (идентификатор родительского процесса), ImageFileName, CreateTime.
Что искать в дампе памяти CTF-задачи:
UQkpjFjFzM.exe из DEFCON-challenge или SkypeC2AutoUpdate.exe из GrrCon (название мимикрирует под легитимный софт, но запущен из %TEMP%)%TEMP%, %APPDATA%, Downloads вместо C:\Windows\System32Плагин pstree отображает процессы деревом, и вот тут начинается самое интересное — аномальные цепочки видны сразу. Классический паттерн из GrrCon-challenge: OUTLOOK.EXE → открытие вложения → cmd.exe → wscript.exe → SkypeC2AutoUpdate.exe. Без pstree эту цепочку пришлось бы восстанавливать вручную по PPID — удовольствие сомнительное.
Атакующие часто маскируют малварь под легитимные процессы Windows: svchost.exe, taskhostw.exe, lsass.exe. Настоящие процессы Windows всегда запускаются из фиксированных путей (%systemroot%\system32\) и имеют предсказуемых родителей (по данным блога Varonis). Если svchost.exe порождён не services.exe, а explorer.exe — это маркер компрометации. Точка.
Плагин psscan сканирует весь дамп по сигнатурам структур _EPROCESS, находя процессы, удалённые из активного списка — скрытые руткитами или просто завершённые. Сравните количество записей pslist и psscan: разница указывает на скрытые или завершённые процессы, которые стоит рассмотреть отдельно.
Для подозрительного PID следующий шаг — cmdline -p <PID> (аргументы командной строки) и getsids -p <PID> (учётная запись, под которой работает процесс — System Owner/User Discovery, T1033). В GrrCon-challenge через getsids установили, что вредонос запущен от имени доменного пользователя phillip.price после интерактивного входа.
Плагин netscan показывает TCP/UDP-соединения на момент снятия дампа: локальные и удалённые адреса, порты, PID процесса-владельца, состояние соединения.
Типичный CTF-сценарий: подозрительный процесс установил соединение на порт 4444 — дефолтный порт Meterpreter. В DEFCON 2019 challenge через netscan и фильтрацию по порту 4444 определили PID инфицированного процесса и IP атакующего (по данным walkthrough Gravitywall). Знание дефолтных конфигураций атакующих инструментов — навык, который напрямую конвертируется в скорость решения forensics-задач. Порт 4444 — Meterpreter. 8080 — часто Jenkins или обратный прокси. 1337 — «элитный» порт, любимый авторами CTF.
В GrrCon-challenge netscan показал соединения SkypeC2AutoUpdate.exe с IP 54.174.131.235:80 — адрес C2-сервера, который позже подтвердился при анализе VBA-макроса из фишингового письма.
Плагин filescan (File and Directory Discovery, T1083) сканирует файловые объекты в памяти. Вывод — тысячи записей, поэтому без фильтрации утонете:
vol.py filescan | grep -i ".pst$" — почтовые архивы Outlook (в GrrCon так нашли .pst файл с фишинговым письмом)vol.py filescan | grep -i "flag" — прямой поиск флага по имени файла (работает чаще, чем можно ожидать — авторы CTF тоже люди)vol.py filescan | grep -i "\.doc\|\.xls\|\.pdf" — документы с потенциальными макросамиvol.py filescan | grep -i "desktop\|downloads" — файлы из пользовательских директорийПосле обнаружения нужного файла — извлечение: vol.py dumpfiles -n -i -r <filename_pattern> -D output_dir/ (Vol2). В Vol3 синтаксис: python3 vol.py -f dump.mem windows.dumpfiles --virtaddr <offset>.
Плагин hivelist показывает кусты реестра в памяти, printkey --key <path> — значения конкретных ключей. Плагин envars извлекает переменные окружения процессов — имя компьютера (COMPUTERNAME), имя пользователя, пути к домашним директориям (System Information Discovery, T1082). В Vol3 аналогичную функцию выполняет windows.envars.
Плагин dlllist -p <PID> покажет загруженные DLL для конкретного процесса. В GrrCon-challenge именно через анализ DLL обнаружили атаку DLL Side-Loading: легитимный SkypeC2AutoUpdate.exe импортировал вредоносную avicap32.dll, подброшенную в ту же директорию %TEMP%. Этот паттерн характерен для реальных APT-кампаний — и регулярно всплывает на CTF.
Финальный этап — самый вариативный. Флаги прячут по-разному, но набор воспроизводимых техник покрывает большинство случаев.
Команда vol.py memdump -p <PID> -D . (Vol2) извлекает полное адресное пространство процесса в файл <PID>.dmp. Этот файл содержит всё, что процесс держал в памяти: строки, сетевые буферы, расшифрованные данные (Data from Local System, T1005). Дальше по этому файлу работает утилита strings.
strings -a 1364.dmp | grep -i "flag{\|ctf{\|key{"
strings -el 1364.dmp | grep -A4 "password"
strings -el 1364.dmp | grep -A10 "54.174.131.235"
Флаг -a сканирует весь файл. Флаг -el переключает на little-endian Unicode (UTF-16LE) — и это критично для Windows-дампов, где многие строки хранятся в 16-битной кодировке и невидимы при обычном strings. Я на этом терял время в первом прохождении DEFCON 2019: искал строки обычным strings, ничего не находил, думал что дамп битый. Добавил -el — и всё посыпалось: версия TeamViewer, ID удалённого доступа, данные, недоступные ни через один плагин Volatility напрямую.
Вредоносы в CTF активно используют кодирование (Obfuscated Files or Information, T1027; Deobfuscate/Decode Files or Information, T1140). Классический кейс из GrrCon-challenge: VBA-макрос запускал PowerShell с -encodedCommand, содержащим base64-строку. Декодирование через echo "<base64>" | base64 -d раскрыло массив имён файлов, URL загрузки с C2-сервера и команду запуска вредоноса — ответы сразу на несколько вопросов challenge.
Паттерн для поиска: strings -a <file> | grep -i "powershell\|encodedcommand\|base64\|frombase64". Нашли base64-строку — декодируйте и ищите в ней флаг или следующие подсказки.
Плагин malfind обнаруживает аномальные регионы памяти: участки с правами PAGE_EXECUTE_READWRITE, не привязанные к файлу на диске. Стандартный маркер инъекции шеллкода, reflective DLL injection и Meterpreter-сессий. Если malfind что-то нашёл — с вероятностью 90% вы смотрите на payload.
Плагин procdump -p <PID> --dump-dir . извлекает исполняемый файл процесса из памяти. Полученный бинарь можно хешировать: md5sum executable.<PID>.exe — в DEFCON-challenge это был отдельный вопрос. Плагин hashdump извлекает LM/NTLM-хеши учётных записей из SAM (LSASS Memory, T1003.001, Credential Access) — в forensics-задачах часто просят хеш конкретного пользователя.
Пошаговая последовательность, которая работает для подавляющего большинства forensics-задач CTF с дампами памяти:
Шаг 1 — идентификация ОС. Vol2: imageinfo → выбрать профиль → подтвердить через pslist. Vol3: windows.info (автодетект).
Шаг 2 — обзор процессов. pslist + pstree → выписать подозрительные PID. psscan → сравнить с pslist, найти скрытые.
Шаг 3 — контекст подозрительного процесса. cmdline -p <PID> → аргументы. getsids -p <PID> → учётная запись. dlllist -p <PID> → загруженные библиотеки.
Шаг 4 — сетевая активность. netscan → C2-соединения, нестандартные порты. Сопоставить IP и порты с PID подозрительных процессов.
Шаг 5 — поиск файлов. filescan | grep <pattern> → документы, письма, скрипты. dumpfiles → извлечь.
Шаг 6 — дамп процесса и строки. memdump -p <PID> → файл .dmp. strings -a и strings -el с grep по паттернам флага, IP, доменам, паролям.
Шаг 7 — специализированные плагины. hashdump → LM/NTLM-хеши. malfind → инъекции кода. procdump → извлечение бинаря для хеширования. yarascan --yara-file=rules.yar → поиск по YARA-правилам. notepad (только Vol2) → текст из Notepad.
Связь между плагинами и техниками ATT&CK помогает строить гипотезы по условию задачи:
| Что ищем | Плагин Volatility | Техника ATT&CK |
|---|---|---|
| Список и дерево процессов | pslist, pstree, psscan | Process Discovery (T1057) |
| Сетевые соединения, C2 | netscan | Сетевые артефакты C2 |
| Файлы в памяти | filescan, dumpfiles | Data from Local System (T1005) |
| Учётные данные | hashdump, lsadump | LSASS Memory (T1003.001) |
| Кодированные команды | cmdline + base64 -d | Obfuscated Files (T1027), Decode (T1140) |
| Информация о системе | imageinfo, envars | System Information Discovery (T1082) |
| Владелец процесса | getsids | System Owner/User Discovery (T1033) |
| Инъекция шеллкода | malfind | Инъекция кода в процессы |
Задача намекает на фишинг — ищите OUTLOOK.EXE в netscan и .pst-файлы в filescan. Упоминается persistence — смотрите autoruns и загруженные DLL. Lateral movement — PsExec, RDP-сессии, нетипичные SMB-соединения в netscan.
Volatility — отличный инструмент анализа дампа памяти, но у него есть границы, и лучше знать о них заранее.
Неправильный профиль — самая частая ошибка на CTF. Симптомы: pslist выдаёт нечитаемые имена, пустой вывод или ошибку. Решение: перебрать профили из вывода imageinfo или использовать Vol3 с автодетектом. Если застряли — kdbgscan даст точный ответ.
Обрезанный или повреждённый дамп. Если дамп снят некорректно, часть плагинов вернёт неполные данные. Первое действие — проверить целостность хешем (sha1sum, md5sum) и сравнить с эталоном, если он указан в условии задачи.
Несовместимость плагинов между версиями. Плагины notepad, iehistory, часть community-расширений существуют только в Vol2. Если challenge старый (GrrCon 2015, DEFCON 2019), Vol2 может быть единственным работающим вариантом. Это реальность, а не недостаток — просто надо знать.
Linux-дампы без профиля/символов. Для Linux в Vol2 требуется профиль, собранный под конкретную версию ядра. Для CentOS 7.7 с ядром 3.10.0-1062 нужен профиль, скомпилированный именно под это ядро — универсального «Linux profile» не существует. В Vol3 аналогичная история с ISF-символами, хотя процесс генерации упрощён утилитой dwarf2json.
Крупные дампы замедляют анализ. Дампы 16 ГБ и выше делают каждый запуск плагина минутным. Используйте tee для кэширования вывода: v pslist | tee pslist.txt, затем grep -i "notepad" pslist.txt — без повторного запуска Vol. Этот приём описан в walkthrough DEFCON 2019 (Gravitywall) и экономит десятки минут на длинных challenge'ах.
strings без Unicode. На Windows большинство строк хранится в UTF-16LE. Команда strings без флага -el пропустит их. Всегда запускайте оба варианта: strings -a (ASCII) и strings -el (Unicode) на каждом дампе процесса. Я уже упоминал эту ошибку выше — повторяю, потому что на ней спотыкается каждый второй.
Девять из десяти forensics-задач CTF решаются одной и той же последовательностью: профиль, процессы, сеть, строки. Не нужно знать все 200 плагинов — достаточно семи-восьми ключевых и понимания, когда переключиться с Volatility на strings + grep. Проблема большинства writeup'ов в том, что они показывают финальный путь к решению, но не объясняют, как аналитик пришёл к выбору конкретного плагина на конкретном шаге. В реальности выбор — это цепочка гипотез: вижу процесс из %TEMP% → проверяю сеть → нахожу C2 → дамплю адресное пространство → ищу строки. Цепочка строится от аномалии, а не от инструмента.
Ещё один момент, который мало кто проговаривает вслух: Volatility 2 фактически мёртв как проект — Python 2, архивный репозиторий, ноль коммитов за последние годы. Но в CTF-экосистеме он продолжает жить: большинство публичных challenge'ей, от DEFCON 2019 до GrrCon, заточены под синтаксис Vol2 с --profile=. Это создаёт ловушку для тех, кто учится через CTF с прицелом на карьеру в DFIR: человек осваивает Vol2, привыкает к профилям и imageinfo, а потом приходит на реальное расследование — и там Vol3 с другим синтаксисом, автоопределением и таблицами символов. Я бы рекомендовал строить рабочий workflow вокруг Vol3, а Vol2 держать как инструмент для конкретных challenge'ей, где он требуется условием. Инвестиция в понимание архитектуры ISF-символов и плагинной системы Vol3 окупается быстрее, чем заучивание устаревших профилей — хотя бы потому, что навыки Vol3 напрямую переносятся в рабочую среду IR-команды. Формула на бумаге понятна, но memory forensics по-настоящему ощущается только когда сам прогоняешь анализ на реальном дампе. Готовые стенды есть на HackerLab.pro — российская CTF-платформа экосистемы Codeby с категориями forensics и crypto, где можно отработать именно этот навык от начала до конца.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...