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

Сбор артефактов Windows на Python: портативный коллектор для реагирования на инциденты

Сбор артефактов Windows на Python: портативный коллектор для реагирования на инциденты
Время чтения: 12 мин.

На выезде к клиенту из финансового сектора — ноутбук бухгалтера, подозрение на компрометацию через фишинговое письмо. KAPE (Kroll Artifact Parser and Extractor — утилита для автоматического сбора Windows-артефактов, стандарт индустрии) на флешке, но корпоративный Kaspersky Endpoint Security с включённым Application Control блокирует kape.exe: файл не в белом списке. FTK Imager — та же история. Права локального администратора есть, Python 3.11 стоит для внутренних скриптов автоматизации и числится в разрешённых приложениях. За полтора часа я написал скрипт на 200 строк, который собрал Prefetch, Event Logs, кусты реестра, список процессов и сетевые соединения — хватило, чтобы найти точку входа и восстановить цепочку атаки. С тех пор этот скрипт ездит на каждый выезд рядом с KAPE — не вместо, а как план Б.

Когда стандартный форензик-тулкит не запускается

Стандартный набор для быстрого триажа (первичного сбора данных при инциденте): KAPE, FTK Imager от Exterro, Velociraptor (платформа удалённого сбора артефактов через VQL-запросы). Эти инструменты закрывают большинство задач по сбору артефактов Windows для расследования. Но на практике бывает так, что ни один из них запустить не получается.

Application Control и антивирус. Корпоративный AppLocker или антивирус с политикой контроля приложений блокирует запуск неизвестных .exe. В финансовом секторе и госструктурах белый список приложений — не рекомендация, а требование. KAPE — бинарник, и если он не числится в разрешённых, его не запустить без изменения политики. Согласование может занять часы.

Нет возможности развернуть агент. Velociraptor требует установки агента на эндпоинт. Политика безопасности клиента может запрещать сторонние сервисы на продуктивных машинах без согласования. По данным CrowdStrike Global Threat Report 2025, среднее время lateral movement после initial access — 62 минуты. Пока согласуете установку агента, окно реагирования закроется.

Изолированный сегмент. Рабочая станция в air-gapped сети (физически изолированной от интернета), куда не дотянется Velociraptor-сервер. USB-порты отключены или ограничены, но Python уже стоит на хосте.

Нестандартный набор артефактов. Иногда нужна специфическая комбинация — скажем, только PowerShell-история и SRUM со 150 машин за ночь. Подготовка кастомных targets для KAPE — отдельная задача; Python-скрипт пишется под конкретный кейс за час.

Python выручает потому, что интерпретатор часто уже стоит на хосте (автоматизация, DevOps, внутренние утилиты) и числится в белом списке. Скрипт — текстовый файл .py, не исполняемый бинарник. AppLocker его пропускает, если python.exe разрешён.

Но учтите обратную сторону: Python на хосте — ещё и вектор для атакующего. Техника T1059.006 в MITRE ATT&CK (открытая база тактик и техник атак; T-коды вроде T1059 — идентификаторы конкретных техник) описывает использование Python для выполнения вредоносного кода. Если Python установлен — это одновременно инструмент форензика и инструмент атакующего. Факт наличия python.exe на машине стоит зафиксировать в отчёте.

Порядок волатильности: что собирать первым при триаже Windows

Порядок волатильности (order of volatility) — базовый принцип DFIR (Digital Forensics and Incident Response — цифровая криминалистика и реагирование на инциденты). Смысл простой: сначала собираем то, что исчезнет быстрее. Если атакующий прямо сейчас держит сессию с C2-сервером (Command & Control — сервер управления заражёнными машинами), через минуту соединение может закрыться. Перезагрузка уничтожит данные RAM. Очистка журналов сотрёт записи о входах.

Для Python-коллектора порядок сбора артефактов Windows выглядит так:

Приоритет Артефакт Зачем нужен Волатильность
1 Процессы и сетевые соединения Активный C2, подозрительные PID, инжектированные процессы Секунды
2 ARP-таблица, DNS-кэш Следы обращений к вредоносным хостам Минуты
3 Кусты реестра (SYSTEM, SOFTWARE, SAM) Автозагрузка, службы, ShimCache, подключённые USB Стабильны, затираются при перезагрузке
4 Prefetch (.pf) Факт и время запуска исполняемых файлов Перезаписываются при запуске новых программ
5 Event Logs (.evtx) Входы (4624), создание процессов (4688), очистка логов (1102) Перезаписываются по лимиту размера
6 Amcache.hve SHA-1 хеши когда-либо запускавшихся бинарей, включая удалённые Стабилен
7 SRUM (SRUDB.dat) Сетевой трафик и CPU-время по каждому приложению за 30 дней Несброшенные данные теряются при аварийном выключении
8 PowerShell-история Последние 4096 команд (без временных меток, кроме даты модификации файла) Перезаписывается при достижении лимита

Каждый артефакт покрывает конкретную discovery-технику из MITRE ATT&CK. Процессы — T1057 (Process Discovery), сетевые соединения — T1049 (System Network Connections Discovery), реестр — T1012 (Query Registry), файловые артефакты — T1083 (File and Directory Discovery), информация о пользователях — T1033 (System Owner/User Discovery). По сути, мы используем те же техники сбора данных, что и атакующий, но для защиты: собираем следы, которые он оставил.

Что Python НЕ может собрать без драйвера ядра: дамп оперативной памяти (нужен kernel-mode драйвер — WinPMEM, DumpIt), raw-чтение $MFT (Master File Table заблокирована ОС; теоретически доступна через \\.\C: с ctypes, но требует побайтового парсинга NTFS), hiberfil.sys и pagefile.sys (заблокированы системой). Если дамп памяти критичен — несите дампер отдельно. Python-коллектор покрывает файловую часть триажа.

Строим Python-коллектор для сбора артефактов Windows

Весь коллектор — один файл .py. Зависимости: только стандартная библиотека Python (os, shutil, subprocess, glob, hashlib, json, datetime). Никаких pip-пакетов — на клиентской машине их может не оказаться, а pip install в ходе инцидента меняет состояние системы. Если на хосте стоит psutil — можно использовать для более чистого сбора процессов, но скрипт работает и без него.

Предпосылки: Python 3.6+, права локального администратора, внешний носитель или сетевая шара для результатов.

Волатильные данные: процессы и сетевые соединения

Первое действие — снять то, что изменится через секунды. Вызываем системные утилиты Windows через subprocess.run(). Команда tasklist /V /FO CSV отдаёт список процессов в CSV с PID, именем образа, потреблением памяти и заголовком окна. netstat -anob показывает все сетевые соединения с привязкой к процессу-владельцу (флаг -b требует прав администратора). wmic process get ... /FORMAT:CSV даёт полные командные строки — именно в CommandLine видно, с какими аргументами запущен powershell.exe, и часто именно это раскрывает вредоносную активность.

def collect_volatile(out):
    cmds = {"processes.csv": "tasklist /V /FO CSV",
            "netstat.txt": "netstat -anob",
            "wmic_procs.csv": "wmic process get ProcessId,Name,CommandLine /FORMAT:CSV"}
    for fname, cmd in cmds.items():
        try:
            r = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            open(os.path.join(out, fname), "w").write(r.stdout)
        except Exception:
            pass

Для каждой команды запускаем системный процесс, перехватываем stdout и пишем в файл. Таймаут 30 секунд — защита от зависания wmic на нагруженных системах. Если команда не отработала (нет прав, утилита не найдена) — исключение ловится, коллектор идёт дальше. В боевом скрипте вместо pass стоит print(f"[!] {cmd} failed").

Сюда же добавляются arp -a (ARP-таблица — MAC-адреса хостов, с которыми машина общалась) и ipconfig /displaydns (DNS-кэш — обращения к доменам, включая C2). По одной строке на каждую.

Замечание по wmic: в Windows 11 Microsoft предупреждает о deprecation wmic.exe в пользу PowerShell-командлетов (Get-CimInstance Win32_Process). Если работаете с Windows 11 — добавьте альтернативный вызов через powershell -Command "Get-CimInstance Win32_Process | Select ProcessId,ParentProcessId,Name,CommandLine | ConvertTo-Csv".

Ожидаемый результат: в директории появятся три файла. Откройте processes.csv — там должны быть десятки строк с PID и именами процессов. Файл пустой — скрипт запущен без прав администратора.

Файловые артефакты: Prefetch, Event Logs, реестр

После волатильных данных копируем файлы с диска. Prefetch (.pf в C:\Windows\Prefetch) просто копируются через shutil.copy2() — он сохраняет метаданные. С Event Logs сложнее: часть .evtx заблокирована службой Event Log Service. Обходной путь — wevtutil epl, экспортирующая журнал в файл. Для кустов реестра — reg save. И wevtutil, и reg.exe — это LOLBins (Living Off The Land Binaries — легитимные системные утилиты, которые атакующие тоже используют). Мы используем их по назначению.

Перед вызовом функции создайте поддиректории: os.makedirs(os.path.join(out, "Prefetch"), exist_ok=True) — и аналогично для Logs и Registry.

def collect_artifacts(out):
    for pf in glob.glob(r"C:\Windows\Prefetch\*.pf"):
        shutil.copy2(pf, os.path.join(out, "Prefetch", os.path.basename(pf)))
    for log in ["Security", "System", "Microsoft-Windows-PowerShell%4Operational"]:
        subprocess.run(f'wevtutil epl "{log}" "{out}\\Logs\\{log}.evtx"', shell=True)
    for hive in ["SYSTEM", "SOFTWARE", "SAM"]:
        subprocess.run(f'reg save HKLM\\{hive} "{out}\\Registry\\{hive}" /y', shell=True)

Почему именно эти журналы: Security содержит события входа (Event ID 4624/4625) и создания процессов (4688). System — установку служб и ошибки драйверов. PowerShell Operational — выполненные командлеты и скриптблоки. Для триажа этих трёх обычно хватает. Если на машине стоит Sysmon — добавьте Microsoft-Windows-Sysmon%4Operational в список.

Ожидаемый результат: в Prefetch — десятки .pf файлов (на рабочей станции обычно 80–150 штук). В Logs — три .evtx. В Registry — три бинарных файла кустов. Если reg save выдал «Access is denied» — запустите скрипт через runas /user:administrator python collector.py.

Дополнительные артефакты для полноты картины. NTUSER.DAT (куст реестра конкретного пользователя — ShellBags, RecentDocs, UserAssist) лежит в C:\Users\<username>\NTUSER.DAT. Для активного пользователя файл заблокирован, но профили других пользователей копируются через shutil.copy2(). PowerShell ConsoleHost_history.txt — последние 4096 команд, путь C:\Users\<username>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt. SRUM (C:\Windows\System32\sru\SRUDB.dat) — база использования ресурсов приложениями за 30 дней, включая объём сетевого трафика по каждому процессу. Amcache (C:\Windows\appcompat\Programs\Amcache.hve) — SHA-1 хеши когда-либо запускавшихся бинарей, даже если файл уже удалён.

Для Windows 11 (22H2 и новее): добавьте файлы PCA (Program Compatibility Assistant) из C:\Windows\appcompat\pca\. По данным исследования Sygnia, файл PcaAppLaunchDic.txt хранит пути к исполняемым файлам с временными метками последнего запуска. Нюанс: PCA фиксирует только GUI-запуски. Исполнение из командной строки, через PsExec или scheduled task — не регистрируется.

Chain of custody: хешируем собранное

Chain of custody (цепочка хранения доказательств) — принцип, по которому каждый собранный артефакт сопровождается криптографическим хешем. Без этого результаты триажа можно оспорить: нечем доказать, что файл не модифицирован после сбора.

def hash_collected(out):
    manifest = {}
    for root, _, files in os.walk(out):
        for f in files:
            path = os.path.join(root, f)
            sha = hashlib.sha256(open(path, "rb").read()).hexdigest()
            manifest[os.path.relpath(path, out)] = sha
    json.dump(manifest, open(os.path.join(out, "sha256_manifest.json"), "w"), indent=2)

На выходе — sha256_manifest.json с SHA-256 для каждого артефакта. Чтобы проверить целостность позже, пересчитайте хеш любого файла: certutil -hashfile <path> SHA256 и сравните с манифестом.

Делай раз, делай два, делай три: запуск коллектора

Шаг 1. Подготовь среду. Понадобится: рабочая станция Windows с Python 3.6+ и правами локального администратора. Внешний носитель (USB-диск, сетевая шара) для результатов. Собирать артефакты на тот же диск, откуда берёшь данные, нежелательно — это изменяет файловую систему и может перезаписать удалённые файлы. Скопируй collector.py на носитель. Создай структуру директорий или добавь os.makedirs() в начало скрипта.

Шаг 2. Запусти от имени администратора. Открой cmd от имени администратора (правый клик → «Запуск от имени администратора»). Выполни: python E:\collector.py --output E:\Evidence\HOSTNAME_20260724. Ожидаемый вывод:

[+] Volatile: processes.csv — OK (47 processes)
[+] Volatile: netstat.txt — OK
[+] Artifacts: Prefetch — 93 files copied
[+] Artifacts: Logs — 3 journals exported
[+] Artifacts: Registry — 3 hives saved
[+] Hashing: sha256_manifest.json — 99 entries

Видишь [!] Access denied — скрипт запущен без прав администратора. wmic завис — увеличь таймаут или замени на PowerShell-вариант.

Шаг 3. Проверь результаты. Открой sha256_manifest.json — полный список файлов с хешами. Выбери любой и пересчитай: certutil -hashfile E:\Evidence\...\Security.evtx SHA256. Совпадает — целостность подтверждена. Расходится — файл изменён после сбора.

Шаг 4. Парси собранное на своей машине. Скрипт собирает сырые артефакты. Для анализа бери парсеры из набора Eric Zimmerman: PECmd для Prefetch (покажет время и количество запусков каждого бинарника), EvtxECmd для Event Logs (выведет события в CSV с фильтрацией по Event ID), RegRipper для кустов реестра (извлечёт автозагрузку, ShimCache, USB-историю). Парсеры запускай на forensic-workstation, не на машине клиента — анализ не должен модифицировать собранные доказательства.

Ограничения скрипта и когда этого недостаточно

Python-коллектор для сбора артефактов — план Б, не замена полноценного IR-тулкита. Таблица ограничений:

Задача Python-коллектор KAPE / Velociraptor
Дамп RAM Нет (нужен kernel-драйвер) KAPE + WinPMEM: да
Raw-чтение $MFT Нет (файл заблокирован) KAPE: да (через raw read targets)
Удалённый сбор с 50+ машин Только через скриптовую обвязку Velociraptor: нативно
Работа через AppLocker Да (если python.exe в белом списке) Нет (блокируется как неизвестный .exe)
Парсинг «на лету» Нет (только сбор) KAPE modules: да
Скорость развёртывания Минута (скопировать .py) Минуты–часы (установка, согласование)

Если антивирус блокирует и python.exe — вариантов два: согласовать добавление в исключения или использовать PowerShell (доступен почти всегда, хотя Constrained Language Mode может ограничить возможности).

Когда скрипт не подходит: инцидент с fileless malware (вредонос живёт только в памяти) — без дампа RAM не обойтись. Массовый триаж сотен машин — Velociraptor эффективнее. Нужен forensic-образ диска (E01) для передачи в суд — тут FTK Imager или dc3dd.

Среди форензиков принято гордиться арсеналом: Volatility 3, KAPE с кастомными targets, Velociraptor с VQL-запросами на полстраницы. Инструменты мощные, вопросов нет. Но за три года выездов я усвоил неудобную вещь: в реальном инциденте половина арсенала не запускается. Не из-за багов — из-за политик безопасности, антивирусов, отсутствия прав и нехватки времени на согласование. На курсах по DFIR учат работать с идеальными условиями: KAPE стартует, Velociraptor деплоится, антивирус послушно молчит. На проде так не бывает. И чем жёстче у клиента политика безопасности — тем выше вероятность, что основной тулкит не заработает. Ирония: именно у таких клиентов инциденты серьёзнее. Скрипт на 200 строк, который собирает 80% нужных артефактов, в этих ситуациях — не деградация, а прагматизм. KAPE лучше по всем параметрам, но к нему нужен план Б. И этот план Б — скрипт, который вы написали сами и понимаете до последней строки. Если только начинаете разбираться в форензике и хотите понять всю цепочку от алерта до отчёта — на IB Basics это разбирают от первых шагов.

Эту тему и смежные навыки разбирают на практике в курсе «Реагирование на компьютерные инциденты» Codeby Academy.