Detection engineering
Правило, накликанное в консоли SIEM, не имеет истории, теста и рецензента. Detection engineering обращается с детектами как с кодом — Sigma-правила в Git, проверенные на образцах логов, отрецензированные в PR, — и тюнинг становится диффом, а не кликом, который никто не помнит.
3 часа ночи, дежурный аналитик тонет. Детект «Suspicious PowerShell» сработал за ночь 4000 раз — и каждый раз это задание бэкапа, добавленное на сервер кем-то восемь месяцев назад. Аналитик делает то, что делает любой измотанный аналитик: открывает консоль SIEM, находит правило, добавляет исключение для этого хоста, жмёт «сохранить». Алерты прекращаются. Никто ничего не записывает. Через шесть недель другой инженер, глядя на то же шумное правило, удаляет условие целиком, чтобы оно замолчало, — и молча пробивает дыру, сквозь которую ровно та техника, ради которой правило и строилось, теперь проходит незамеченной. Нет ни коммита, ни диффа, ни ревью, ни теста, который бы это поймал. Правило никогда не было кодом. Оно было настройкой в коробке, а у настроек в коробке нет памяти.
К концу урока ты будешь знать, как писать, тестировать и версионировать детекты как код — Sigma-правила в Git, проверенные на образцах логов, отрецензированные в pull request, — чтобы тюнинг шумного правила был аудируемым инженерным изменением, а не забытым кликом.
Что такое detection engineering на самом деле
Ты уже знаешь, что правила SIEM превращают логи в алерты. Detection engineering — это дисциплина, которая задаёт вопрос потруднее: как строить, менять и доверять этим правилам годами, в команде, не давая набору правил сгнить в шум? Ответ, к которому пришла индустрия, — detection-as-code: обращайся с каждым детектом как с прикладным кодом. Он живёт в Git-репозитории, а не в консоли вендора. У него есть автор, сообщение коммита и рецензент. Он едет через CI. И, что критично, у него есть тесты: образцы лог-событий, которые должны его поднять (true positive), и образцы, которые не должны (негативы), прогоняемые на каждое изменение.
Модель «накликать в консоли» проваливается по тем же причинам, по каким проваливается ручная правка прода через GUI базы данных. Нет истории — ты не ответишь, кто изменил правило и зачем. Нет ревью — исключение, добавленное усталым аналитиком в 3 ночи, едет без второй пары глаз. Нет теста — правка одного символа в регулярке может тихо перестать ловить то, ради чего правило строилось, и никто не узнает до самого пробоя. Detection-as-code закрывает все три бреши, заимствуя мышцы, которые у тебя уже наработаны в доставке софта: контроль версий, код-ревью и автоматическое тестирование.
Sigma: формат правил, который путешествует
Механизм, который делает это переносимым, — Sigma: универсальный сигнатурный формат для лог-детектов на основе YAML, слой «напиши один раз, нацель на многих» для мира SIEM. Ты описываешь логику детекта в вендоронезависимой схеме Sigma, а конвертер (эталонный инструмент — sigma-cli с бэкендами pySigma) компилирует это одно правило в язык запросов того бэкенда, который у тебя крутится: Splunk SPL, query DSL у Elastic, KQL-запрос Microsoft Sentinel и так далее. Пишешь логику один раз — даёшь тулчейну выдать диалект.
Сердце Sigma-правила — два поля. detection.selection перечисляет условия поле/значение, которые должны совпасть, а condition склеивает селекции булевой логикой. Вот правило реального вида для того самого алерта, что затопил нашего аналитика:
| Поле Sigma | Пример значения | Что оно даёт тебе |
|---|---|---|
title | Encoded PowerShell command line | Человеческое имя — то, что видно в алерте |
logsource | product: windows, category: process_creation | К какому потоку логов применяется правило |
detection.selection | Image endswith \powershell.exe; CommandLine contains ‘-enc’ | Условия совпадения |
detection.filter | CommandLine contains ‘BackupAgent\run.ps1’ | Исключение тюнинга — в правиле, в Git |
condition | selection and not filter | Булев клей — собственно логика |
tags | attack.execution, attack.t1059.001 | Маппинг на ATT&CK — питает твою сетку покрытия |
Заметь: тюнинг живёт в filter, выраженный в condition как selection and not filter. Это то же самое исключение, что наш аналитик в 3 ночи сделал руками, — но теперь это строка в YAML-файле, в коммите, с сообщением о том, почему агент бэкапа исключён, доступная для ревью любому, кто позже задумается, не слишком ли широк этот вырез. Фикс не уехал в скрытую настройку консоли — он уехал в дифф.
Жизненный цикл: детект — это софт
Важно это потому, что детекты никогда не бывают «готовы». Противник меняет флаг, вендор переименовывает поле лога, приложение начинает выдавать безобидный паттерн, похожий на вредоносный, — и правило должно меняться. Detection-as-code даёт этому изменению конвейер.
Шаг тестирования — несущий, и именно его команды пропускают первым. Каждое Sigma-правило должно ехать с фикстурами: хотя бы одно лог-событие, представляющее реальную технику атаки (утверждай, что оно горит), и набор заведомо безобидных событий, поверхностно похожих (утверждай, что они молчат). Когда аналитик в 3 ночи добавляет filter: BackupAgent\run.ps1, CI перепрогоняет вредоносную фикстуру и доказывает, что правило всё ещё ловит атаку с encoded PowerShell даже с новым вырезом. Инженер, который через шесть недель попытается удалить всё условие, увидит, как true-positive тест краснеет в pull request. Тест — это то, что превращает «сделай тихо» из ставки в безопасную операцию.
▸Почему это работает
Почему false positive считается багом первого класса, а не просто раздражителем? Потому что усталость от алертов — сама по себе поверхность атаки. Аналитик, перед которым 4000 ложных тревог за ночь, не разбирает аккуратно 4001-ю — он рефлекторно сбрасывает очередь, и ровно тогда настоящая проскальзывает. Печально знаменитый пробой Target в 2013-м — канонический случай: вредонос был помечен, но алерт утонул в шуме и остался без действия. Так что доля false positive у детекта — не косметическая метрика; это разница между контролем, который работает, и тем, что обучил своих операторов его игнорировать. Тюнинг — не опциональная полировка, это поддержание контроля живым.
Сигнал, который ты на самом деле тюнишь
Каждое изменение детекта — это сделка между двумя типами ошибок, и сказать, какой из них ты оптимизируешь, — и есть весь навык. True positive — это срабатывание правила на реальной вредоносной активности, то, что тебе нужно. False positive — это срабатывание на безобидной активности, то самое задание бэкапа. Затяни логику, чтобы убить false positive, — и рискуешь создать false negative: реальные атаки, которые теперь более узкое правило уже не ловит. Ослабь её, чтобы поймать больше вариантов, — и false positive растут, пока аналитик не отключится от тебя. Нет настройки, которая обнуляет оба; detection engineering — это практика осознанного выбора точки на этой кривой, для каждой техники, с записью выбора там, где его увидит следующий инженер.
Детект «Encoded PowerShell» срабатывает 4000 раз за ночь, все — с одного хоста бэкапа, гоняющего известный скрипт. Нужно заставить его молчать, не ослепнув к атаке. Выбери зрелый ход.
Почему detection-as-code держит исключение тюнинга внутри `filter` Sigma-правила, а не как подавление в консоли SIEM?
Инженер затянул правило, чтобы заглушить false positive, и сработало — алерты упали почти до нуля. О чём первым делом беспокоится зрелый специалист?
Упорядочь жизненный цикл detection-as-code для нового правила, от написания до боевого тюнинга:
- 1 Написать Sigma-правило и пометить его техникой ATT&CK
- 2 Закоммитить в Git с автором и сообщением-обоснованием
- 3 CI конвертирует правило и прогоняет на TP- и негативных фикстурах
- 4 Коллега рецензирует и одобряет pull request
- 5 Задеплоить сконверченный запрос в SIEM; поздние FP тюнить через тот же цикл
- 01Объясни detection-as-code и почему он лучше, чем накликивание правил в консоли SIEM.
- 02Что такое Sigma, каковы его ключевые поля и как сделка false positive / true positive формирует тюнинг правила?
Detection engineering — это дисциплина построения, изменения и доверия детектам годами, не давая набору правил сгнить в шум, и её ядро — detection-as-code: правила живут в Git, а не в консоли SIEM, с автором, сообщением коммита, ревью коллеги, CI и тестами. Sigma — вендоронезависимый YAML-формат, делающий это переносимым: пишешь логику один раз (logsource, selection, опциональный filter, condition, теги ATT&CK), а конвертер выдаёт запросы Splunk, Elastic или Sentinel. Тюнинг false positive становится узко ограниченным filter, выраженным как selection and not filter, закоммиченным с обоснованием и перепроверенным CI на true-positive фикстуре, — так что убийство шума никогда не может молча создать false negative. Всё держится на отношении к false positive как к багу первого класса, потому что усталость от алертов — поверхность атаки: правило, затопляющее операторов, обучило их игнорировать тот единственный алерт, что имел значение. Так что в следующий раз перед шумным детектом твой рефлекс уже не «накликать исключение в коробке» — это «ограничить filter, написать обоснование и доказать тестом, что атака всё ещё горит».
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.
Примени это
Примени этот урок в реальном проекте.