March 10

Win32 API → NTAPI → Syscall: детектирование через EDR и ELK/Kibana

1. Архитектура вызовов

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

Приложение (user-space)
    │
    │   CreateFile(), VirtualAlloc(), OpenProcess()...
    ▼
kernel32.dll / kernelbase.dll          ← [1] EDR User-space Hook (DLL Injection)
    │
    │   Высокоуровневые обёртки → вызов NTAPI
    ▼
ntdll.dll                              ← [2] ETW / API Monitoring
    │                                      [3] Direct Syscall Detection
    │   NtCreateFile()
    │   NtAllocateVirtualMemory()
    │   NtWriteVirtualMemory()
    │   NtCreateThreadEx()
    │
    │   syscall stub:
    │     mov r10, rcx
    │     mov eax, <SSN>    ← Syscall Service Number
    │     syscall           ← переход в ring 0
    ▼
ntoskrnl.exe (kernel)                  ← [4] SSDT (Service Descriptor Table)
    │                                      [5] Kernel Callbacks
    │   SSDT[SSN] → NtCreateFile
    │             → IopCreateFile
    │             → IoCreateFile...
    ▼
Драйвер / ФС / Устройство              ← [6] Minifilter Driver

Что такое SSN (Syscall Service Number)

SSN — числовой индекс в таблице SSDT, соответствующий конкретной ядерной функции.
Значения зависят от версии и сборки Windows и не являются стабильными между релизами:

Функция Win10 21H2 Win11 22H2 Win11 23H2 NtAllocateVirtualMemory 0x18 0x18 0x18 NtWriteVirtualMemory 0x3A 0x3A 0x3A NtCreateThreadEx 0xC1 0xC2 0xC3 NtOpenProcess 0x26 0x26 0x26

Важно для аналитика: техники Hell's Gate / Halo's Gate / Tartarus' Gate динамически определяют SSN во время выполнения — именно потому что эти числа нестабильны.

2. SSDT

Что такое SSDT

System Service Descriptor Table — структура ядра Windows, содержащая массив указателей на функции-обработчики системных вызовов. Расположена в ntoskrnl.exe.

// Упрощённое определение
typedef struct _SYSTEM_SERVICE_TABLE {
    PULONG_PTR ServiceTableBase;      // массив адресов функций
    PULONG     ServiceCounterTableBase;
    ULONG      NumberOfServices;      // ~450 функций в современных Windows
    PUCHAR     ParamTableBase;
} SYSTEM_SERVICE_TABLE;

SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[2]; // 0=ядро, 1=Win32k (GUI)

Почему SSDT нельзя мониторить напрямую из user-space

  1. SSDT живёт в kernel-памяти — прямой доступ из ring 3 невозможен
  2. KPP (Kernel Patch Protection / PatchGuard) — начиная с x64 Windows, модификация SSDT детектируется и вызывает BSOD с кодом 0x109 CRITICAL_STRUCTURE_CORRUPTION
  3. Антируткит-инструменты (GMER, Kernel Detective) могут читать SSDT через driver — но это не масштабируемое EDR-решение

Что реально делают EDR

Вместо прямого мониторинга SSDT, Enterprise EDR-решения (CrowdStrike Falcon, SentinelOne, Microsoft Defender for Endpoint) используют ETW Threat Intelligence и Kernel Callbacks — легальные Microsoft-approved механизмы, которые дают телеметрию на уровне, максимально близком к SSDT.


3. Точки перехвата

┌─────────────────────────────────────────────────────────────────┐
│  Уровень          │  Механизм              │  EDR/Tool          │
├─────────────────────────────────────────────────────────────────┤
│  User-space       │  IAT/EAT Hooking       │  EDR DLL inject    │
│  (ring 3)         │  (kernel32/ntdll)      │  (legacy подход)   │
├─────────────────────────────────────────────────────────────────┤
│  Syscall boundary │  ETW Threat Intel      │  ETWTI provider    │
│  (ring 3→0)       │  Direct Syscall det.   │  SilkETW           │
├─────────────────────────────────────────────────────────────────┤
│  Kernel           │  Kernel Callbacks      │  EDR driver        │
│  (ring 0)         │  Minifilter Driver     │  CrowdStrike / S1  │
│                   │  ObRegisterCallbacks   │                    │
└─────────────────────────────────────────────────────────────────┘

4. ETW — основной механизм телеметрии

Event Tracing for Windows (ETW) — ключевой легальный механизм получения syscall-телеметрии без патчинга SSDT.

Ключевые провайдеры

Provider GUID Покрытие Microsoft-Windows-Kernel-Process 22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716 CreateProcess, CreateThread, LoadImage Microsoft-Windows-Kernel-File EDD08927-9CC4-4E65-B970-C2560FB5C289 NtCreateFile, NtWriteFile, NtReadFile Microsoft-Windows-Kernel-Registry 70EB4F03-C1DE-4F73-A051-33D13D5413BD Все Registry-операции Microsoft-Windows-Kernel-Network 7DD42A49-5329-4832-8DFD-43D979153A88 TCP/UDP события Microsoft-Windows-Threat-Intelligence F4E1897C-BB5D-5668-F1D8-040F4D8DD344 ETWTI — критически важен

ETWTI (ETW Threat Intelligence) — приоритет №1

ETWTI работает на уровне ядра и значительно сложнее обойти, чем user-space хуки:

Покрываемые API:
  NtAllocateVirtualMemory   → детект shellcode allocation
  NtProtectVirtualMemory    → детект RW→RX смены прав
  NtWriteVirtualMemory      → детект process injection
  NtCreateThreadEx          → детект remote thread
  NtMapViewOfSection        → детект mapping injection
  NtQueueApcThread          → детект APC injection
  LdrLoadDll                → детект рефлективной загрузки DLL

Как малварь пытается обойти ETW

// Патч EtwEventWrite в ntdll.dll (user-space ETW патч)
// Малварь ищет функцию и пишет ret в начало:

FARPROC pEtwEventWrite = GetProcAddress(GetModuleHandle("ntdll.dll"), "EtwEventWrite");
BYTE patch[] = { 0xC3 };  // ret
WriteProcessMemory(GetCurrentProcess(), pEtwEventWrite, patch, 1, NULL);

Детект: само по себе изменение байт EtwEventWrite в ntdll — детект-сигнал.
ETWTI работает из ядра → патч user-space ntdll его не отключает.


5. Kernel Callbacks

EDR-драйвер регистрирует callbacks через официальный kernel API:

// ── Process Monitoring ────────────────────────────────────────
PsSetCreateProcessNotifyRoutineEx(
    CallbackRoutine,
    FALSE   // регистрация
);
// → срабатывает при каждом CreateProcess / ExitProcess
// → даёт: PEPROCESS, parent PID, image path, commandline

// ── Thread Monitoring ─────────────────────────────────────────
PsSetCreateThreadNotifyRoutine(CallbackRoutine);
// → каждый CreateThread / CreateRemoteThread
// → КРИТИЧНО: remote thread в чужой процесс → IOC

// ── Image Load Monitoring ─────────────────────────────────────
PsSetLoadImageNotifyRoutine(CallbackRoutine);
// → каждая загрузка DLL/драйвера
// → детект: reflective injection, unsigned DLL, загрузка из temp

// ── Registry Monitoring ───────────────────────────────────────
CmRegisterCallback(CallbackRoutine, NULL, &Cookie);
// → все операции с реестром: Run ключи, Services, IFEO...

// ── Handle Operations ─────────────────────────────────────────
ObRegisterCallbacks(&CallbackRegistration, &RegistrationHandle);
// → OpenProcess / OpenThread с конкретными правами доступа
// → КЛЮЧЕВОЙ детект: OpenProcess(LSASS, PROCESS_VM_READ) → Mimikatz

GrantedAccess маски для OpenProcess — что искать

0x1010  →  PROCESS_VM_READ | PROCESS_QUERY_LIMITED_INFORMATION   (чтение памяти)
0x1410  →  + PROCESS_VM_OPERATION                                (запись)
0x143A  →  почти все права                                       (дамп)
0x1FFFFF → PROCESS_ALL_ACCESS                                    (полный доступ)
0x0410  →  стандартный Mimikatz-набор прав

6. Direct Syscall и Syscall Spoofing

Это наиболее актуальная техника обхода в 2024–2025. Понимание этого механизма критично для SOC-аналитика.

Почему малварь переходит на Direct Syscall

EDR-хуки в ntdll работают по принципу: EDR инжектирует свою DLL в каждый процесс и перехватывает вызовы в ntdll. Если малварь вызывает syscall, минуя ntdll — хук не срабатывает.

; ── Нормальный путь через ntdll ──────────────────────────────────
; ntdll!NtAllocateVirtualMemory:
    mov r10, rcx          ; сохранение rcx для syscall
    mov eax, 0x18         ; SSN
    syscall               ; переход в ring 0
    ret

; ── Direct Syscall (малварь в своём .text) ───────────────────────
; malware.exe+0x5678:
    mov r10, rcx          ; те же инструкции
    mov eax, 0x18         ; тот же SSN
    syscall               ; НО: выполняется из адреса малвари!
    ret

Syscall Spoofing / Stomping

Более продвинутая техника: SSN берётся из ntdll, но ret address подменяется:

Техника "Egg Hunting" / "Synthetic Frames":
1. Малварь находит syscall stub в ntdll (легитимный адрес)
2. Подменяет return address на стеке → stack walk показывает ntdll
3. Фактически: syscall выполняется из кода малвари, но стек "чистый"

Как детектировать Direct Syscall

Метод 1 — Аномальный call stack

── НОРМАЛЬНЫЙ СТЕК ─────────────────────────────────────────────
ntdll!NtAllocateVirtualMemory + 0x14
kernelbase!VirtualAllocEx + 0x5F
malware.exe + 0x1A3C

── ПОДОЗРИТЕЛЬНЫЙ (Direct Syscall) ────────────────────────────
ntdll!NtAllocateVirtualMemory + 0x14
malware.exe + 0x5678          ← нет kernelbase! в стеке
                               ← или: syscall из non-ntdll региона

Метод 2 — Адрес инструкции syscall вне диапазона ntdll

# Псевдологика детекта (реализуется в EDR-драйвере):
ntdll_base = get_module_base("ntdll.dll")
ntdll_end  = ntdll_base + get_module_size("ntdll.dll")

if syscall_instruction_address < ntdll_base or \
   syscall_instruction_address > ntdll_end:
    ALERT("Direct Syscall detected outside ntdll!")
    log(process_name, pid, syscall_address, ssn)

Метод 3 — Memory region без backing file

Если syscall выполняется из региона памяти, у которого:
  - Type: MEM_PRIVATE (не MEM_IMAGE)
  - State: MEM_COMMIT
  - Protect: PAGE_EXECUTE_READ или PAGE_EXECUTE_READWRITE
  - MappedFile: None (нет backing PE-файла)

→ Это shellcode или reflective DLL → HIGH CONFIDENCE IOB

7. ELK / Kibana — конкретные запросы и правила

Источники данных

Sysmon v14+       → Winlogbeat  → Elasticsearch → Kibana SIEM
ETW (SilkETW)     → Filebeat    → Logstash      → Kibana
EDR Telemetry     → Logstash    → ES            → Kibana
Windows EventLog  → Winlogbeat  → ES            → Kibana

Sysmon — критические Event ID

EID Событие Применение 1 Process Create commandline, hashes, parent 7 Image Loaded DLL из temp/appdata, unsigned 8 CreateRemoteThread remote thread injection 10 ProcessAccess OpenProcess + GrantedAccess 17/18 Pipe Created/Connected lateral movement, C2 25 Process Tampering hollowing, herpaderping


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

🔴 LSASS Access (Credential Dumping)

event.code: "10"
AND winlog.event_data.TargetImage: "*\\lsass.exe"
AND winlog.event_data.GrantedAccess: (
    "0x1010" OR "0x1410" OR "0x143a" OR
    "0x1fffff" OR "0x0410" OR "0x1438"
)
AND NOT winlog.event_data.SourceImage: (
    "C:\\Windows\\System32\\svchost.exe" OR
    "C:\\Windows\\System32\\werfault.exe" OR
    "C:\\Windows\\System32\\taskmgr.exe" OR
    "C:\\Program Files\\*\\MsMpEng.exe"
)

Детектирует: Mimikatz, ProcDump, Nanodump, lsassy


🔴 Process Injection — Remote Thread

event.code: "8"
AND winlog.event_data.TargetImage: (
    "*\\explorer.exe" OR "*\\svchost.exe" OR
    "*\\lsass.exe"   OR "*\\winlogon.exe" OR
    "*\\spoolsv.exe"
)
AND NOT winlog.event_data.SourceImage: (
    "C:\\Windows\\System32\\*" OR
    "C:\\Windows\\SysWOW64\\*" OR
    "C:\\Program Files\\*"
)

🔴 Подозрительная загрузка DLL (Unsigned / Temp)

event.code: "7"
AND winlog.event_data.Signed: "false"
AND winlog.event_data.ImageLoaded: (
    "*\\AppData\\*"   OR
    "*\\Temp\\*"      OR
    "*\\ProgramData\\*" OR
    "*\\Users\\Public\\*"
)
AND NOT winlog.event_data.Image: (
    "C:\\Windows\\System32\\*" OR
    "C:\\Windows\\SysWOW64\\*"
)

🔴 RW→RX смена прав памяти (Shellcode Pattern)

event.provider: "Microsoft-Windows-Threat-Intelligence"
AND winlog.event_data.NewAccessProtection: (
    "PAGE_EXECUTE_READWRITE" OR
    "PAGE_EXECUTE_WRITECOPY" OR
    "0x40" OR "0x80"
)
AND winlog.event_data.OldAccessProtection: (
    "PAGE_READWRITE" OR "0x04"
)

Детектирует: классический shellcode loader (malloc RW → copy → VirtualProtect RX → exec)


🟠 Direct Syscall — отсутствие ntdll в стеке

event.provider: "Microsoft-Windows-Threat-Intelligence"
AND winlog.event_data.CallingProcessId: *
AND NOT winlog.event_data.CallStack: "*ntdll*"
AND winlog.event_data.Type: (
    "ALLOCVM_REMOTE" OR "PROTECTVM_REMOTE" OR
    "WRITEVM_REMOTE" OR "CREATETHREAD_REMOTE"
)

🟠 ETW Patch Detection (EtwEventWrite stomping)

event.code: "7"
AND winlog.event_data.ImageLoaded: "*\\ntdll.dll"
AND winlog.event_data.ProcessId: *

В связке с:

event.provider: "Microsoft-Windows-Threat-Intelligence"
AND winlog.event_data.ThreatName: "EtwEventWritePatch"

🟠 Heaven's Gate (WoW64 32→64 переход)

event.provider: "Microsoft-Windows-Threat-Intelligence"
AND winlog.event_data.CallerProcessIsWow64: "true"
AND winlog.event_data.TargetProcessIsWow64: "false"
AND winlog.event_data.Type: "CREATETHREAD_REMOTE"

🟡 Scheduled Task Persistence (SSDT-смежный)

event.code: "1"
AND winlog.event_data.Image: "*\\schtasks.exe"
AND winlog.event_data.CommandLine: (
    "*/create*" AND
    ("*/sc onlogon*" OR "*/sc onstart*" OR "*/sc minute*")
)
AND NOT winlog.event_data.User: "NT AUTHORITY\\SYSTEM"

Elastic Detection Rules (готовые к импорту)

В официальном репозитории elastic/detection-rules доступны правила, напрямую покрывающие SSDT-смежные техники:

windows/defense_evasion_direct_syscall_ntdll.toml
windows/credential_access_lsass_memory_access.toml
windows/defense_evasion_process_injection_via_createremotethread.toml
windows/defense_evasion_suspicious_process_creation_calltrace.toml
windows/defense_evasion_etw_provider_patched.toml

Импорт в Kibana SIEM:
Stack Management → Rules → Import rule


8. Практический стек детектирования

┌─────────────────────────────────────────────────────────────────────┐
│                    PRODUCTION DETECTION STACK                       │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  [Kernel Layer]                                                     │
│   ETW Threat Intelligence Provider (F4E1897C...)                   │
│   + PsSetCreateProcessNotifyRoutineEx                              │
│   + ObRegisterCallbacks (OpenProcess/OpenThread)                   │
│   + Minifilter (filesystem events)                                 │
│                        │                                           │
│  [Collection Layer]    ▼                                           │
│   SilkETW / SealighterTI → JSON (ETW → структурированные события) │
│   Sysmon v14+            → XML (process/file/network/registry)    │
│                        │                                           │
│  [Transport Layer]     ▼                                           │
│   Winlogbeat / Filebeat → Logstash (enrich, normalize, GeoIP)     │
│                        │                                           │
│  [Storage Layer]       ▼                                           │
│   Elasticsearch (горячий: 30 дней, тёплый: 90 дней)               │
│                        │                                           │
│  [Detection Layer]     ▼                                           │
│   Kibana SIEM Rules    → статические правила (KQL/EQL)            │
│   ML Anomaly Jobs      → поведенческие аномалии (CPU, inject rate)│
│                        │                                           │
│  [Response Layer]      ▼                                           │
│   Alert → SOAR (TheHive / Cortex) → автоматическая изоляция       │
└─────────────────────────────────────────────────────────────────────┘

SilkETW — быстрый старт

# Мониторинг ETW Threat Intelligence провайдера
SilkETW.exe -t user `
    -pn Microsoft-Windows-Threat-Intelligence `
    -ot file `
    -p C:\Logs\etwti.json

# Затем Filebeat читает C:\Logs\etwti.json → Elasticsearch

EQL (Event Query Language) — Kibana sequence detection

EQL позволяет детектировать цепочки событий, что критично для обнаружения многоэтапных техник:

-- Детект: alloc → write → protect → exec (классический shellcode loader)
sequence by process.entity_id with maxspan=30s
  [process where event.type == "start"]
  [api where process.Etwti.type == "ALLOCVM_REMOTE"]
  [api where process.Etwti.type == "WRITEVM_REMOTE"]
  [api where process.Etwti.type == "PROTECTVM_REMOTE"
        and process.Etwti.NewProtection == "PAGE_EXECUTE_READ"]
  [api where process.Etwti.type == "CREATETHREAD_REMOTE"]

9. Матрица угроз и обходов

Техника атаки Что обходит Детект-механизм Сигнал Direct Syscall ntdll user-space хуки ETWTI call stack analysis syscall не из ntdll диапазона Hell's Gate hardcoded SSN Sysmon EID 11 (чтение ntdll с диска) чтение PE-заголовка ntdll Halo's Gate патченные стабы memory scan ntdll integrity изменённые байты в ntdll Tartarus' Gate оба выше ETWTI комбо сигналов Syscall Spoofing call stack analysis ETWTI synthetic frame det. несоответствие ret address Heaven's Gate WoW64 хуки ETWTI WoW64 monitoring 32→64 thread creation ETW Patch ETW телеметрию kernel ETW integrity check патч EtwEventWrite SSDT Hook (руткит) всё PatchGuard / расхождение адресов BSOD или driver alert Process Hollowing process name whitelist Sysmon EID 25 section replace Process Doppelgänging file-based детект ETWTI + section mapping транзакционный файл


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

Главный вывод

SSDT нельзя мониторить напрямую из user-space. Но это и не нужно — правильный стек детектирования строится на:

  1. ETWTI — ближайший к SSDT легальный источник телеметрии, работает из ядра
  2. Kernel Callbacks — покрывают process/thread/image/registry/handle события
  3. Sysmon — структурированная телеметрия для ELK без написания драйвера
  4. Поведенческие цепочки (EQL) — важнее отдельных сигнатур

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

CRITICAL:
  • syscall-инструкция выполняется вне диапазона ntdll.dll
  • OpenProcess(lsass.exe) с GrantedAccess 0x1010/0x143a
  • CreateRemoteThread в системный процесс из non-system source
  • EtwEventWrite patch в ntdll любого процесса

HIGH:
  • RW→RX смена прав в приватном (не MEM_IMAGE) регионе
  • Unsigned DLL загружена из %TEMP% / %APPDATA%
  • Отсутствие ntdll в call stack при системном вызове
  • Heaven's Gate: CreateThread WoW64→x64 cross-arch

Инструменты для лаборатории

Инструмент Назначение SilkETW ETW collection → JSON SealighterTI ETWTI специфично, usermode WinApiOverride user-space API мониторинг API Monitor перехват вызовов с параметрами WinDbg + tt time-travel debugging syscall chain Process Monitor быстрый file/registry/network мониторинг pe-sieve + hollows_hunter детект hollowing/doppelgänging в памяти