Источник: https://github.com/AnaktaCTF/CTF/blob/main — Forensic/Анализ дампов памяти Windows.md
Введение
Оперативная память — это «рабочая область» современных операционных систем, в которой хранятся данные активных процессов, сетевые соединения, расшифрованные строки и даже учетные записи пользователей в виде открытых структур. В отличие от файлов на диске, которые могут быть зашифрованы, удалены или модифицированы, данные в ОЗУ отражают текущее состояние системы в момент захвата дампа. Это делает Memory Forensics одним из важнейших инструментов при расследовании инцидентов: будь то анализ целевого взлома, исследование вредоносного ПО или аудит утечек.
При исследовании дисковых артефактов следы активности злоумышленника зачастую оказываются фрагментарными и смытыми обновлениями, дефрагментацией или политиками перезаписи. В оперативной же памяти, до момента перезагрузки или завершения процессов, сохраняется полный стек вызовов, данные сетевых сокетов, открытые файлы, ключи шифрования и даже текстовые пароли. С их помощью аналитик получает практически непрерывную «картину» внутренних механизмов работы системы на момент захвата дампа.
Например, при работе атакующего, внедряющего вредоносную DLL в процесс браузера, статический анализ бинарника на диске не покажет, какой код был запущен, каким образом он взаимодействовал с памятью других процессов и какие данные он расшифровал в рантайме. Подобные детали доступны только при анализе снимка оперативной памяти, что позволяет раскрыть скрытые инъекции, перехватить личные ключи и выявить сетевые туннели.
1. Подготовка тестового стенда и инструменты для съёмки дампа
Для корректного анализа важна изолированная среда: лучше всего использовать виртуальную машину (VirtualBox, VMware или Hyper-V) со снимком («снэпшотом») «чистой» системы. Это позволяет быстро вернуть исходное состояние, избежать фоновых шумов сторонних приложений и обеспечить воспроизводимость экспериментов.
На виртуальной машине устанавливают актуальные обновления безопасности, основные сервисы и целевые приложения, а затем создают контрольный снэпшот. При возникновении подозрений запускают на этой же виртуальной машине потенциально опасный код, а после его работы — снимают дамп памяти.
Существует два основных инструмента для съёмки дампа на Windows:
- WinPmem – утилита проекта [OSForensics] , позволяющая захватить всю ОЗУ в формате raw. Она вызывается из командной строки и поддерживает опции для сжатия, шифрования и сохранения в формате AFF4;
- DumpIt – портативный исполняемый файл, не требующий установки, который после запуска автоматически собирает дамп и сохраняет его рядом с исполняемым файлом.
Использование любого из них сводится к запуску от имени администратора. В случае WinPmem достаточно перейти в папку утилиты и выполнить команду:
winpmem.exe -o memory.raw --format raw
DumpIt же не требует подготовки: двойной клик по DumpIt.exe запустит процедуру съёмки и выдаст файл memory.raw. В обоих случаях необходимо дождаться завершения всех операций, не перезагружая виртуальную машину, чтобы полученный дамп был целостным.
2. Установка и базовая настройка Volatility 3
Volatility 3 — это современный фреймворк для анализа дампов памяти, написанный на Python и обладающий модульной архитектурой. Он умеет работать с образами разных форматов (RAW, EWF, HPAK, AFF4), поддерживает Windows, Linux и macOS, а также допускает расширение за счёт плагинов.
Для установки Volatility 3 в рамках изолированного окружения выполните следующие действия:
-
Создание виртуального окружения.
Откройте терминал (или PowerShell) и в каталоге проекта запустите команду:python3 -m venv venv-vol3После этого активируйте окружение:
source venv-vol3/bin/activate # В Linux/macOS venv-vol3\Scripts\activate # В Windows -
Обновление pip и установка Volatility 3.
pip install --upgrade pip setuptools pip install volatility3 -
Проверка корректности установки.
Введите командуvol -h, и вы должны увидеть справку по основным параметрам запуска, доступным командам и списку встроенных плагинов. -
Подключение сторонних плагинов (по необходимости).
Многие исследователи дополняют стандартный набор своими разработками. Обычно для установки требуется клонировать репозиторий и выполнить в нём:pip install .или указать ссылку на пакет в
requirements.txt.
В результате у вас появится исполняемый скрипт vol (или volatility3) в venv-vol3/bin, готовый к анализу любых дампов памяти.
3. Основные плагины Volatility 3
3.1 pslist и psscan: процессы «на виду» и скрытые
Плагин pslist опирается на связные списки EPROCESS, поддерживаемые ядром Windows. При запуске он выводит все процессы, зарегистрированные в списке активных. Для исследования используйте команду:
vol -f memory.raw windows.pslist
Вы получите таблицу с полями: PID, PPID, имя процесса, время создания и приоритета. Однако злоумышленник может удалить свой процесс из этого списка, и тогда его уже не покажет pslist. Здесь на помощь приходит psscan, сканирующий память на предмет сигнатур структур EPROCESS независимо от списка:
vol -f memory.raw windows.psscan
Сравнение выходных данных обеих команд позволяет обнаружить процессы, «спрятанные» от стандартного списка, и выявить завершённые процессы, скрытые от обычных механизмов.
3.2 malfind: поиск инъекций и «подозрительных» страниц
malfind анализирует виртуальные адресные пространства процессов на предмет участков с атрибутом «исполняемая+неизвестная» память. Это классический признак внедрения DLL или shellcode. Пример запуска:
vol -f memory.raw windows.malfind --dump-dir dumps
Утилита сохранит каждый обнаруженный участок в отдельный файл в папке dumps. Аналитик может открыть эти фрагменты в дизассемблере (Ghidra, IDA Pro) и понять, какой именно код был внедрён и откуда он пришёл.
3.3 dlllist и handles: библиотеки и ресурсы
Плагин dlllist отображает список модулей, загруженных каждым процессом, включая путь к файлу и базовый адрес. Например:
vol -f memory.raw windows.dlllist --pid 3456
Он полезен при анализе DLL-хиддинга, когда вредоносный загрузчик внедряет в легитимный процесс свои библиотеки.
handles возвращает открытые дескрипторы объекта ядра (файлы, реестр, сокеты):
vol -f memory.raw windows.handles --pid 3456
Зная, какие файлы и ключи реестра держит процесс открытыми, можно восстановить логи его активности и понять, какие внешние ресурсы он задействовал.
3.4 Дополнительные плагины: vadinfo, connscan, clipboard
- vadinfo показывает детальную информацию о Virtual Address Descriptors (VAD) каждого процесса: диапазоны виртуальной памяти, атрибуты страниц, права доступа. Анализ этих данных выявляет участки, которые могли быть динамически созданы злоумышленником;
- connscan и netscan ищут в памяти структуры для TCP/UDP соединений, отображая локальные и удалённые адреса, PID процесса и состояние соединения. Это помогает восстановить сетевую активность без логов в файрволе;
- clipboard извлекает содержимое буфера обмена Windows, где могут храниться скопированные пароли или другие ценные сведения.
Каждый из этих плагинов позволяет исследовать специфические аспекты работы системы и в совокупности дает полную картину активности.
4. Создание собственного Python-скрипта на базе API Volatility 3
Когда ручное применение плагинов становится рутинным, имеет смысл автоматизировать некоторые задачи. Volatility 3 предоставляет Python-API, позволяющее вызывать плагины из кода, обрабатывать их результаты и формировать собственные отчеты.
4.1 Структура скрипта: контекст и конфигурация
В основе лежит создание объекта Context и конфигурация путей до образа памяти и символов:
import json
import logging
from volatility3.framework import contexts
from volatility3.framework.configuration import requirements
from volatility3.plugins.windows import lsa_secrets, netscan
# Настройка логирования
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Создаем контекст Volatility
ctx = contexts.Context()
# Указываем местоположение памяти и таблицу символов Windows
ctx.config['plugins.LayerStacker.single_location'] = 'memory.raw'
ctx.config['plugins.LayerStacker.primary.symbol_table'] = 'nt_symbols'
Здесь важно скорректировать путь к файлу памяти и загрузить таблицу символов (nt_symbols), которая описывает структуры ядра выбранной версии Windows.
4.2 Вызов плагинов и обработка результатов
После инициализации контекста можно создавать экземпляры плагинов и запускать их метод run(). Ниже — пример извлечения LSA secrets (хэшей и паролей пользователей):
def extract_lsa_secrets():
plugin = lsa_secrets.LsaDecrypt(ctx, config_path='plugins.LayerStacker')
for secret in plugin.run():
name = secret.Name
try:
value = secret.Data.decode('utf-16le')
except Exception:
value = repr(secret.Data)
yield {'name': name, 'value': value}
Для сетевых соединений используется плагин netscan:
def extract_network_sessions():
plugin = netscan.NetScan(ctx, config_path='plugins.LayerStacker')
for entry in plugin.run():
yield {
'pid': entry.ProcessId,
'process_name': entry.ProcessName,
'local': f"{entry.LocalAddress}:{entry.LocalPort}",
'remote': f"{entry.RemoteAddress}:{entry.RemotePort}",
'state': entry.State
}
Каждую запись удобно преобразовать в словарь и собрать в список для дальнейшего экспорта.
4.3 Основной блок исполнения и сохранение артефактов
Завершающий фрагмент скрипта объединяет данные и сохраняет в JSON:
if __name__ == '__main__':
secrets = list(extract_lsa_secrets())
sessions = list(extract_network_sessions())
report = {
'lsa_secrets': secrets,
'network_sessions': sessions
}
with open('memory_report.json', 'w', encoding='utf-8') as f:
json.dump(report, f, ensure_ascii=False, indent=2)
logger.info("Отчет сохранен в memory_report.json")
При необходимости можно добавить обработку ошибок, таймауты, многопоточность для ускорения анализа больших дампов, а также логирование прогресса.
5. Расширение скрипта: анализ реестра и вытягивание артефактов Windows
Нередко исследователю требуется не только LSA-секреты и сетевые данные, но и информация из реестра, активных сессий пользователя, недавно открытых файлов. Volatility 3 включает плагины registry_hive и userassist, которые можно вызвать аналогичным образом:
from volatility3.plugins.windows.registry_hive import HiveList
from volatility3.plugins.windows.userassist import UserAssist
def extract_regristries():
hive_plugin = HiveList(ctx, config_path='plugins.LayerStacker')
for hive in hive_plugin.run():
yield {'hive_path': hive.FileFullPathName, 'description': hive.HiveName}
def extract_userassist():
ua = UserAssist(ctx, config_path='plugins.LayerStacker')
for entry in ua.run():
yield {
'user_sid': entry.SID,
'exe_path': entry.Application,
'run_count': entry.RunCount
}
Подобные расширения позволяют автоматически получать практически все доступные артефакты, включая историю команд PowerShell, содержимое буфера обмена, ключи автозапуска.
6. Формирование отчёта и визуализация результатов
После получения JSON-отчёта удобнее представить данные в читаемом виде и подготовить к дальнейшему анализу и хранению.
6.1 Конвертация в CSV
С помощью Python-библиотеки pandas выполнить преобразование элементов массива в отдельные таблицы:
import pandas as pd
report = pd.read_json('memory_report.json')
lsa_df = pd.json_normalize(report['lsa_secrets'])
net_df = pd.json_normalize(report['network_sessions'])
lsa_df.to_csv('lsa_secrets.csv', index=False, encoding='utf-8-sig')
net_df.to_csv('network_sessions.csv', index=False, encoding='utf-8-sig')
Каждая строка CSV будет содержать поля, соответствующие имени секрета, значению или параметрам сетевой сессии.
6.2 Построение графа сетевых соединений
Для наглядности сетевой активности можно воспользоваться библиотеками networkx и matplotlib. Пример кода:
import networkx as nx
import matplotlib.pyplot as plt
df = pd.read_csv('network_sessions.csv')
G = nx.Graph()
for _, row in df.iterrows():
src = row['local']
dst = row['remote']
G.add_edge(src, dst, pid=row['pid'], label=row['process_name'])
plt.figure(figsize=(12, 8))
pos = nx.spring_layout(G, k=0.5)
nx.draw_networkx_nodes(G, pos, node_size=300)
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos, font_size=8)
plt.title('Граф сетевых соединений, извлечённых из дампа памяти')
plt.axis('off')
plt.show()
Такой граф позволит сразу визуализировать, какие процессы с каким удалённым адресом соединялись и сколько сессий они открыли.
7. Интеграция с SIEM и Osquery
Для систем централизованного сбора и корреляции событий (ELK, Splunk) или инструментов постановки целевых запросов (Osquery) можно настроить автоматическую подачу артефактов.
7.1 Filebeat + Elasticsearch + Kibana
-
Установите Filebeat на сервер аналитики или отдельную машину.
-
В
filebeat.ymlзадайте input для папки с CSV:filebeat.inputs: - type: log enabled: true paths: - /opt/memory_analysis/*.csv fields: source: memory_forensics -
Настройте Ingest Pipeline в Elasticsearch, чтобы парсить CSV-строки и преобразовывать поля
pid,local,remoteв отдельные атрибуты. -
В Kibana создайте дашборды: карта сети, гистограмму количества открытых соединений по PID, таблицу LSA secrets с возможностью фильтрации по имени.
7.2 Расширение Osquery
Osquery поддерживает плагины-расширения, написанные на Python. Можно адаптировать наш скрипт как extension, отвечающий на SQL-запросы:
SELECT pid, process_name, local, remote, state FROM memory_sessions;
SELECT name, value FROM memory_lsa_secrets;
Для этого используется библиотека osquery-extension-sdk и регистрация таблиц с колбэк-функциями, возвращающими строки из JSON-файла.
8. Защита дампов памяти и рекомендации по безопасности
Дампы памяти содержат критическую информацию, включая учетные записи, сетевые ключи и расшифрованные данные. Чтобы минимизировать риски:
- Шифрование и контроль доступа. Храните дампы только во внутренних сегментах, с правами доступа по принципу наименьших привилегий. Используйте BitLocker, VeraCrypt или LUKS для шифрования каталогов с анализируемыми образами.
- Журналы аудита. Любое чтение или копирование файлов дампа должно фиксироваться службой аудита ОС и перенаправляться в SIEM. Анализ этих логов позволит выявить попытки несанкционированного доступа.
- Изоляция среды. Привилегированные исследовательские машины должны быть физически либо виртуально отделены от продакшена. Запускать анализ только на стендах, подготовленных для этой цели.
- Автоматическое удаление устаревших дампов. Настройте скрипт очистки, удаляющий образы старше заранее установленного периода (например, 7–14 дней). Это предотвратит накопление конфиденциальной информации без надобности.
- Сегментация сети. Храните дампы в недоступном для внешних сетей хранилище, ограничьте доступ с помощью VLAN и межсетевых экранах.
Эти меры не только защитят артефакты расследования, но и предотвратят случайную утечку данных из оперативной памяти.