April 8

Анализ логов: от источника до детекта

1. Что и откуда собирать

Прежде чем строить правила — нужно понимать, какие источники дают какую телеметрию и что в них есть, а чего нет.

Windows Event Log

Основной источник для большинства расследований. Ключевые каналы:

Проблема с 4688: по умолчанию командная строка в нём отсутствует. Без включённого Audit Process Creation + Include command line in process creation events (GPO) — поле ProcessCommandLine будет пустым. Это частая причина слепых пятен.

Sysmon — почему он важнее нативного аудита

Sysmon дополняет EventLog тем, чего нет нативно: хэши процессов, полный путь к образу, родительский процесс, network connections с PID, DNS-запросы, pipe events.

<!-- Минимальная конфигурация: SwiftOnSecurity/sysmon-config -->
<!-- или более агрессивная: olafhartong/sysmon-modular -->
<Sysmon schemaversion="4.82">
  <EventFiltering>
    <!-- EID 1: Process Create — логировать всё, кроме шума -->
    <RuleGroup name="ProcessCreate" groupRelation="or">
      <ProcessCreate onmatch="exclude">
        <Image condition="is">C:\Windows\System32\svchost.exe</Image>
      </ProcessCreate>
    </RuleGroup>
    <!-- EID 3: Network Connect — только нестандартные порты -->
    <RuleGroup name="NetworkConnect" groupRelation="or">
      <NetworkConnect onmatch="include">
        <DestinationPort condition="is not">80</DestinationPort>
        <DestinationPort condition="is not">443</DestinationPort>
      </NetworkConnect>
    </RuleGroup>
  </EventFiltering>
</Sysmon>

Полная таблица Sysmon EID для аналитика:

EID Событие Зачем нужен 1 Process Create PID, PPID, cmdline, hashes, user 3 Network Connect process → dst_ip:port 7 Image Loaded DLL из %TEMP%, unsigned 8 CreateRemoteThread process injection 10 ProcessAccess OpenProcess + GrantedAccess 11 File Create dropper, persistence 12/13/14 Registry Run-ключи, IFEO, COM hijack 15 FileCreateStreamHash ADS (Alternate Data Stream) 17/18 Pipe Create/Connect named pipe C2, lateral movement 22 DNS Query C2 resolution, DGA 25 Process Tampering hollowing, herpaderping 26 File Delete Detected anti-forensics

Linux: auditd vs syslog vs eBPF

# auditd — минимальный набор правил для SOC
# /etc/audit/rules.d/soc.rules

# Исполнение файлов
-a always,exit -F arch=b64 -S execve -k exec
# Изменения в /etc, /tmp
-w /etc/passwd -p wa -k passwd_changes
-w /tmp -p x -k tmp_exec
# Привилегированные команды
-a always,exit -F path=/usr/bin/sudo -F perm=x -k sudo_usage
# Сетевые соединения (syscall level)
-a always,exit -F arch=b64 -S connect -k network_connect
# Загрузка модулей ядра
-a always,exit -F arch=b64 -S init_module,finit_module -k kernel_module
eBPF как альтернатива: Falco, Tetragon — дают syscall-уровень без тяжёлого auditd. Особенно актуально для контейнеров. Но на классическом Linux-хосте для IR auditd + syslog вполне достаточно.

2. Нормализация: что происходит в Logstash/Ingest Pipeline

Сырой лог бесполезен без нормализации. Задача этого слоя — привести всё к единой схеме (ECS — Elastic Common Schema) и обогатить данными.

# Logstash pipeline: windows_security.conf
input {
  beats { port => 5044 }
}

filter {
  # Парсим Windows Security события
  if [winlog][channel] == "Security" {
    mutate {
      rename => {
        "[winlog][event_data][SubjectUserName]" => "[user][name]"
        "[winlog][event_data][IpAddress]"       => "[source][ip]"
        "[winlog][event_data][ProcessName]"     => "[process][executable]"
      }
    }

    # Обогащение: GeoIP для source.ip
    if [source][ip] and [source][ip] != "-" {
      geoip {
        source => "[source][ip]"
        target => "[source][geo]"
      }
    }

    # Threat intel lookup (файл IOC или MISP)
    translate {
      field       => "[source][ip]"
      destination => "[threat][indicator][match]"
      dictionary_path => "/etc/logstash/ioc_ips.yml"
      fallback    => "false"
    }
  }

  # Нормализация пути к процессу (lowercase для KQL)
  if [process][executable] {
    mutate {
      lowercase => ["[process][executable]"]
    }
  }
}

output {
  elasticsearch {
    hosts    => ["https://es01:9200"]
    index    => "logs-windows-%{+YYYY.MM.dd}"
    ssl_certificate_verification => true
  }
}

ECS — ключевые поля, которые нужно знать:

ECS поле Windows источник Что хранит process.name Image (Sysmon EID 1) имя процесса process.command_line CommandLine полная командная строка process.parent.name ParentImage родительский процесс process.hash.sha256 Hashes хэш бинаря user.name SubjectUserName пользователь host.name Computer хост-источник network.destination.ip DestinationIp (Sysmon 3) dst IP dns.question.name QueryName (Sysmon 22) DNS запрос file.path TargetFilename (Sysmon 11) путь к файлу registry.path TargetObject (Sysmon 13) ключ реестра


3. KQL — запросы для Kibana SIEM

Базовая анатомия KQL

field: "value"                         — точное совпадение
field: *value*                         — wildcard
field: (val1 OR val2 OR val3)          — OR в скобках
field >= 100 AND field <= 500          — диапазон
NOT field: "value"                     — исключение
field.keyword: "exact"                 — keyword (без анализа)
field vs field.keyword: text-поля в ES анализируются — "C:\Windows\System32" разбивается на токены. Для точных путей всегда используй .keyword-вариант поля, иначе поиск по подстроке может дать ложные срабатывания.

Обнаружение выполнения команд

🔴 LOLBin / Living Off the Land

event.code: "1"
AND process.name: (
    "certutil.exe" OR "bitsadmin.exe" OR "mshta.exe" OR
    "wscript.exe"  OR "cscript.exe"   OR "regsvr32.exe" OR
    "rundll32.exe" OR "msiexec.exe"   OR "installutil.exe" OR
    "schtasks.exe" OR "at.exe"        OR "wmic.exe"
)
AND NOT process.parent.name: (
    "msiexec.exe" OR "iexplore.exe" OR
    "C:\\Windows\\System32\\services.exe"
)

🔴 PowerShell Encoded Command

event.code: "4104"
AND winlog.event_data.ScriptBlockText: (
    "*-enc *"  OR "*-EncodedCommand*" OR
    "*FromBase64String*" OR "*IEX*"   OR
    "*Invoke-Expression*" OR "*bypass*"
)
Почему EID 4104, а не 4688: Script Block Logging (4104) пишет содержимое скрипта до обфускации — то, что PowerShell реально выполнил. EID 4688 пишет только вызов powershell.exe с аргументами, обфусцированная строка остаётся нечитаемой.

🟠 AMSI Bypass Patterns

event.code: "4104"
AND winlog.event_data.ScriptBlockText: (
    "*amsiInitFailed*"     OR
    "*AmsiScanBuffer*"     OR
    "*[Ref].Assembly*"     OR
    "*System.Runtime.InteropServices.Marshal*"
)

🟠 Подозрительный родитель процесса (Parent-Child)

Аномальные пары родитель → дочерний процесс:

event.code: "1"
AND (
    (process.parent.name: "winword.exe"  AND process.name: ("cmd.exe" OR "powershell.exe" OR "wscript.exe")) OR
    (process.parent.name: "excel.exe"   AND process.name: ("cmd.exe" OR "powershell.exe" OR "mshta.exe"))   OR
    (process.parent.name: "outlook.exe" AND process.name: ("cmd.exe" OR "powershell.exe" OR "wscript.exe")) OR
    (process.parent.name: "acrobat.exe" AND process.name: ("cmd.exe" OR "powershell.exe"))                   OR
    (process.parent.name: "mshta.exe"   AND process.name: ("powershell.exe" OR "cmd.exe" OR "wscript.exe"))
)

Persistence

🔴 Registry Run-ключи

event.code: ("12" OR "13")
AND winlog.event_data.TargetObject: (
    "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run*"     OR
    "*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce*" OR
    "*\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run*" OR
    "*\\SYSTEM\\CurrentControlSet\\Services\\*"
)
AND NOT process.name: (
    "msiexec.exe" OR "setup.exe" OR "install.exe"
)

🔴 Scheduled Task из командной строки

event.code: "1"
AND process.name: "schtasks.exe"
AND process.command_line: (
    "*/create*" AND (
        "*/sc onlogon*" OR "*/sc onstart*" OR
        "*/sc minute*"  OR "*/sc hourly*"
    )
)
AND NOT user.name: ("SYSTEM" OR "LOCAL SERVICE" OR "NETWORK SERVICE")

🟠 IFEO Debugger Injection (Image File Execution Options)

event.code: ("12" OR "13")
AND winlog.event_data.TargetObject: (
    "*\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\*\\Debugger"
)
IFEO Debugger — классический persistence/bypass: малварь прописывает себя как debugger для легитимного процесса. При запуске того процесса вместо него выполняется малварь.

🟠 WMI Event Subscription (филeless persistence)

event.code: "19" OR event.code: "20" OR event.code: "21"

Sysmon EID 19/20/21 — WMI activity. Любой из них без известного software-источника заслуживает расследования. Это один из самых незаметных persistence-механизмов.


Lateral Movement

🔴 Pass-the-Hash / Pass-the-Ticket признаки

event.code: "4624"
AND winlog.event_data.LogonType: "3"
AND winlog.event_data.AuthenticationPackageName: "NTLM"
AND winlog.event_data.WorkstationName: "-"
AND NOT winlog.event_data.SubjectUserName: "*quot;
WorkstationName: "-" при NTLM LogonType 3 — признак PtH: легитимные NTLM-аутентификации обычно имеют имя рабочей станции.

🔴 SMB Lateral Movement (admin shares)

event.code: "4624"
AND winlog.event_data.LogonType: "3"
AND winlog.event_data.ShareName: ("\\\\*\\ADMINquot; OR "\\\\*\\Cquot; OR "\\\\*\\IPCquot;)
AND NOT winlog.event_data.SubjectUserName: ("*quot; OR "backup*" OR "admin*")

🔴 PsExec / Remote Service Creation

event.code: "7045"
AND winlog.event_data.ServiceFileName: (
    "*\\PSEXESVC*" OR "*\\PAExec*" OR
    "*\\RemComSvc*" OR "*cmd.exe*" OR
    "*powershell.exe*" OR "*\\Temp\\*"
)

🟠 WinRM / WSMan Remote Execution

event.code: "1"
AND process.parent.name: "wsmprovhost.exe"

Все процессы, порождённые через WinRM, имеют wsmprovhost.exe в качестве родителя. Легитимные сценарии — администрирование, но в паре с аномальным дочерним процессом это IOC.


Credential Access

🔴 DCSync (репликация AD для дампа хэшей)

event.code: "4662"
AND winlog.event_data.Properties: (
    "*1131f6aa-9c07-11d1-f79f-00c04fc2dcd2*" OR
    "*1131f6ab-9c07-11d1-f79f-00c04fc2dcd2*" OR
    "*89e95b76-444d-4c62-991a-0facbeda640c*"
)
AND NOT winlog.event_data.SubjectUserName: "*quot;

Эти GUIDs — права на репликацию AD: DS-Replication-Get-Changes, DS-Replication-Get-Changes-All, DS-Replication-Get-Changes-In-Filtered-Set. Их запрашивает только контроллер домена — и Mimikatz DCSync.

🟠 Volume Shadow Copy Deletion (pre-ransomware)

event.code: "1"
AND process.command_line: (
    "*vssadmin*delete shadows*" OR
    "*wmic*shadowcopy*delete*"  OR
    "*wbadmin*delete*catalog*"  OR
    "*bcdedit*/set*recoveryenabled*no*"
)

Появление любой из этих команд — высокая вероятность ransomware или деструктивной активности.


4. EQL — детектирование цепочек событий

EQL (Event Query Language) — самый мощный инструмент для детекта многоэтапных атак. Один сигнал легко отфильтровать, последовательность — нет.

-- Детект: macro → child process → network connection
-- (фишинг через Office-документ)
sequence by host.name with maxspan=2m
  [process where event.type == "start"
   and process.parent.name : ("winword.exe", "excel.exe", "outlook.exe")]
  [process where event.type == "start"
   and process.name : ("cmd.exe", "powershell.exe", "wscript.exe", "mshta.exe")]
  [network where event.type == "start"
   and not cidrmatch(destination.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")]
-- Детект: discovery burst (типичный пост-эксплоит enum)
-- 5+ discovery-команд с одного хоста за 60 секунд
sequence by host.name with maxspan=60s
  [process where process.name : ("whoami.exe", "net.exe", "ipconfig.exe",
                                  "systeminfo.exe", "nltest.exe", "arp.exe")]
  [process where process.name : ("whoami.exe", "net.exe", "ipconfig.exe",
                                  "systeminfo.exe", "nltest.exe", "arp.exe")]
  [process where process.name : ("whoami.exe", "net.exe", "ipconfig.exe",
                                  "systeminfo.exe", "nltest.exe", "arp.exe")]
  [process where process.name : ("whoami.exe", "net.exe", "ipconfig.exe",
                                  "systeminfo.exe", "nltest.exe", "arp.exe")]
  [process where process.name : ("whoami.exe", "net.exe", "ipconfig.exe",
                                  "systeminfo.exe", "nltest.exe", "arp.exe")]
-- Детект: credential dump → lateral movement
-- (дамп lsass → использование полученных кредов)
sequence by host.name with maxspan=10m
  [process where event.type == "start"
   and (process.name : ("procdump*.exe", "nanodump*", "mimikatz*")
        or process.command_line : "*lsass*")]
  [authentication where event.action == "logged-in"
   and winlog.logon.type == "Network"
   and source.ip != "127.0.0.1"]

5. Sigma — переносимые правила

Sigma — YAML-формат для правил детектирования, не привязанный к конкретной SIEM. Пишешь один раз — конвертируешь в KQL, SPL (Splunk), ESQL, SQL.

# sigma_rule_lolbin_certutil_download.yml
title: CertUtil Used to Download File
id: 19b08b1c-861d-4e75-a1ef-ea0c1baf202b
status: stable
description: Detects certutil.exe used as a downloader (classic LOLBin pattern)
references:
  - https://attack.mitre.org/techniques/T1105/
tags:
  - attack.command_and_control
  - attack.t1105
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith: '\certutil.exe'
    CommandLine|contains:
      - '-urlcache'
      - '-verifyctl'
      - '-decode'
  filter_legit:
    CommandLine|contains:
      - 'pkiview'
      - 'certificate'
  condition: selection and not filter_legit
falsepositives:
  - Certificate management by admins
level: high

Конвертация в KQL через sigma-cli:

pip install sigma-cli
pip install pysigma-backend-elasticsearch

# Конвертация в KQL (Kibana)
sigma convert -t kibana -p ecs_windows sigma_rule_lolbin_certutil_download.yml

# Конвертация в ES|QL (Elasticsearch Query Language — новый синтаксис)
sigma convert -t esql -p ecs_windows sigma_rule_lolbin_certutil_download.yml

# Конвертация для Splunk
sigma convert -t splunk -p splunk_windows sigma_rule_lolbin_certutil_download.yml

Источники готовых Sigma-правил:

  • SigmaHQ/sigma — официальный репозиторий (~3000+ правил)
  • elastic/detection-rules — Elastic-специфичные, с TOML-форматом
  • splunk/security_content — Splunk Security Essentials

6. Анализ временных меток и построение таймлайна

Временная шкала — основа любого IR. Несколько критических нюансов:

Проблема временных зон

# Elasticsearch хранит время в UTC. 
# Хосты могут быть в разных TZ.
# Ключевое правило: нормализуй ВСЁ в UTC при инgestе.

# Пример Logstash: принудительная конвертация
filter {
  date {
    match => ["[winlog][time_created]", "ISO8601"]
    target => "@timestamp"
    timezone => "UTC"  # всегда явно
  }
}
Forensic trap: на Windows @timestamp в EventLog — время записи в журнал, не время события. Разница может быть значительной при оффлайн-анализе снятых логов.

KQL для временного анализа

-- Активность в нерабочее время (ночью / выходные)
event.code: "4624"
AND NOT (
    @timestamp >= "now/d+8h" AND @timestamp <= "now/d+18h"
)
AND NOT winlog.event_data.SubjectUserName: ("*quot; OR "SYSTEM")
-- Burst: много событий аутентификации за короткий период
-- (brute force или credential stuffing)
-- Реализуется через Kibana Threshold Rule:
-- Group by: winlog.event_data.TargetUserName
-- Threshold: count > 20 over 5 minutes
-- Query:
event.code: "4625"

Построение таймлайна в Kibana

Kibana Timeline (SIEM → Timelines) позволяет:

  1. Создать временную шкалу инцидента
  2. Прикрепить события из разных индексов (Windows, Linux, Network)
  3. Добавить аннотации и notes для каждого события
  4. Экспортировать в CSV/JSON для отчёта
Workflow для IR:
1. Определить T0 (момент первоначального компрометации)
2. Kibana: поиск по host.name + временной диапазон ±24h от T0
3. Добавить в Timeline все подозрительные события
4. Расширить диапазон: искать предшествующую активность (recon)
5. Искать lateral movement по source.ip / destination.ip
6. Построить граф: host → host через сетевые события

7. Анализ сетевых логов

Zeek (Bro) — структурированные сетевые логи

# Zeek пишет отдельные лог-файлы по типам:
# conn.log    — все TCP/UDP соединения
# dns.log     — DNS запросы/ответы
# http.log    — HTTP (URL, user-agent, статус)
# ssl.log     — TLS metadata (JA3, SNI, cert)
# files.log   — переданные файлы с хэшами
# notice.log  — алерты встроенных скриптов

# Импорт в Elasticsearch через Filebeat zeek module:
filebeat modules enable zeek

Полезные KQL-запросы по Zeek:

-- Аномальный user-agent (C2 или staged download)
zeek.http.user_agent: (
    "python-requests*" OR "Go-http-client*" OR
    "curl*"            OR "wget*"           OR
    "nmap*"            OR "masscan*"
)
AND NOT source.ip: ("10.0.0.0/8" OR "172.16.0.0/12")
-- Beaconing: регулярные соединения к одному IP
-- (реализуется через ML job или threshold rule)
-- Признак: одинаковые интервалы, маленький payload, long duration=0

zeek.conn.conn_state: "SF"
AND zeek.conn.duration < 1
AND zeek.conn.orig_bytes < 512
AND destination.port: (80 OR 443 OR 8080 OR 8443)
-- JA3 fingerprint известных инструментов
-- (Metasploit, Cobalt Strike, etc.)
zeek.ssl.ja3: (
    "a0e9f5d64349fb13191bc781f81f42e1" OR  -- Cobalt Strike default
    "72a7c13d8cc8eea6d15d72d7e1d8b02d"     -- Metasploit
)
JA3 — хэш TLS ClientHello параметров. Не зависит от IP/домена — позволяет детектировать инструмент атаки даже при смене C2-инфраструктуры.

8. Практические инструменты для аналитика

Инструмент Назначение Когда использовать Kibana SIEM централизованный детект + timeline основная рабочая среда Kibana Lens ad-hoc визуализация данных быстрый анализ распределений Elastic ML anomaly detection поведенческие аномалии baseline jq CLI-парсинг JSON-логов быстрый анализ без ES Hayabusa offline EVTX → timeline/CSV форензика без SIEM Chainsaw EVTX regex hunt поиск по IoC в .evtx Plaso/log2timeline super-timeline из артефактов полноценный forensic timeline Velociraptor live response + hunt IR на endpoints Sigma2KQL конвертация правил перенос Sigma-правил в Kibana

Hayabusa — быстрый анализ EVTX без SIEM

# Поднять таймлайн из папки с EVTX
.\hayabusa.exe csv-timeline -d C:\Cases\Logs\EVTX\ -o timeline.csv

# Отфильтровать только критические события
.\hayabusa.exe csv-timeline -d .\EVTX\ -m critical -o critical.csv

# Статистика по правилам (что сработало чаще всего)
.\hayabusa.exe logon-summary -d .\EVTX\

# Экспорт в JSONL для импорта в Elastic
.\hayabusa.exe json-timeline -d .\EVTX\ -o timeline.jsonl

jq — быстрый разбор JSON без ES

# Из SilkETW JSON: найти все NtAllocateVirtualMemory события
cat etwti.json | jq '.[] | select(.EventName == "ALLOCVM_REMOTE") | 
  {pid: .ProcessId, target: .TargetProcessId, size: .RegionSize}'

# Из Zeek conn.log: топ-10 destination IP по количеству соединений
cat conn.log | zeek-cut id.resp_h | sort | uniq -c | sort -rn | head -10

# Из Sysmon JSONL: все процессы с сетевыми соединениями
cat sysmon.jsonl | jq 'select(.EventID == 3) | 
  {proc: .Image, dst: .DestinationIp, port: .DestinationPort}'

9. Матрица: MITRE ATT&CK → лог-источник → запрос


10. Заключение

Главный принцип: одиночный сигнал — это шум. Цепочка сигналов с одного хоста за короткий промежуток — это инцидент.

Красные флаги для немедленного расследования:

CRITICAL:
  • Office-процесс породил cmd/powershell/wscript
  • LSASS.exe открыт с GrantedAccess 0x1010 или 0x143a
  • vssadmin.exe с параметром delete shadows
  • schtasks.exe /create от непривилегированного пользователя
  • Новый сервис (EID 7045) с путём в %TEMP%
  • DCSync: Security EID 4662 с replication GUIDs

HIGH:
  • PowerShell ScriptBlock с IEX/FromBase64String/AMSI bypass
  • NTLM LogonType 3 с пустым WorkstationName
  • WMI Event Subscription создана не известным sofware
  • Загрузка unsigned DLL из %APPDATA% / %TEMP%
  • JA3-хэш, совпадающий с известным C2-фреймворком
  • DNS-запросы с DGA-паттерном (высокая энтропия имён)