NtTraceControl
Gemultiplextes Kontroll-IOCTL für das ETW-Subsystem — Sitzungen starten, stoppen, abfragen, flushen und Provider aktivieren/deaktivieren.
Prototyp
NTSTATUS NtTraceControl( ULONG FunctionCode, PVOID InBuffer, ULONG InBufferLen, PVOID OutBuffer, ULONG OutBufferLen, PULONG ReturnLength );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| FunctionCode | ULONG | in | EtwpControlCode-Selektor: 1=Start, 2=Stop, 3=Query, 4=Update, 5=Flush, 7=EnableTraceProvider, 13=QueryAllTraces, usw. |
| InBuffer | PVOID | in | Funktionsspezifische Eingabe — typischerweise ein EVENT_TRACE_PROPERTIES oder ETW_ENABLE_NOTIFICATION_PACKET. |
| InBufferLen | ULONG | in | Größe von InBuffer in Bytes. |
| OutBuffer | PVOID | out | Funktionsspezifischer Ausgabepuffer; bei Query gibt er aktualisierte EVENT_TRACE_PROPERTIES mit Statistiken zurück. |
| OutBufferLen | ULONG | in | Kapazität von OutBuffer in Bytes. |
| ReturnLength | PULONG | out | Empfängt die Anzahl tatsächlich in OutBuffer geschriebener Bytes. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x1A6 | win10-1507 |
| Win10 1607 | 0x1AF | win10-1607 |
| Win10 1703 | 0x1B5 | win10-1703 |
| Win10 1709 | 0x1B9 | win10-1709 |
| Win10 1803 | 0x1BB | win10-1803 |
| Win10 1809 | 0x1BC | win10-1809 |
| Win10 1903 | 0x1BD | win10-1903 |
| Win10 1909 | 0x1BD | win10-1909 |
| Win10 2004 | 0x1C3 | win10-2004 |
| Win10 20H2 | 0x1C3 | win10-20h2 |
| Win10 21H1 | 0x1C3 | win10-21h1 |
| Win10 21H2 | 0x1C5 | win10-21h2 |
| Win10 22H2 | 0x1C5 | win10-22h2 |
| Win11 21H2 | 0x1CF | win11-21h2 |
| Win11 22H2 | 0x1D3 | win11-22h2 |
| Win11 23H2 | 0x1D3 | win11-23h2 |
| Win11 24H2 | 0x1D6 | win11-24h2 |
| Server 2016 | 0x1AF | winserver-2016 |
| Server 2019 | 0x1BC | winserver-2019 |
| Server 2022 | 0x1CB | winserver-2022 |
| Server 2025 | 0x1D6 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 D6 01 00 00 mov eax, 0x1D6 F6 04 25 08 03 FE 7F 01 test byte ptr [0x7FFE0308], 1 75 03 jne short +3 0F 05 syscall C3 ret CD 2E int 2Eh C3 ret
Undokumentierte Hinweise
Die gesamte User-Mode-*Kontrolloberfläche* von ETW liegt auf `NtTraceControl`. `StartTrace`, `StopTrace`, `ControlTraceW`, `QueryTrace`, `FlushTrace`, `EnableTraceEx2`, `EnumerateTraceGuidsEx` — alle marshallen ein `EVENT_TRACE_PROPERTIES` (oder eines von rund 30 internen Kontroll-Packets) und dispatchen zu diesem einen Syscall, wobei `FunctionCode` die Operation wählt. Der Kernel-Handler `EtwpControlTrace` prüft `SeSystemProfilePrivilege` / `SeDebugPrivilege` für sensible Operationen und den `EtwGuid`-Security-Descriptor für Provider-Level-Kontrollen. Funktion 7 (`EnableTraceProvider`) schaltet Provider innerhalb bestehender Sitzungen ein und aus — und ist die für Angreifer interessante. Die SSN driftet ungefähr mit jedem Windows-Release, jede hartkodierte Nummer bricht also zwischen Builds; `0x1D6` auf Win11 24H2 / Server 2025.
Häufige Malware-Nutzung
**Die wichtigste ETW-Bypass-Oberfläche.** Der lehrbuchmäßige User-Mode-ETW-Patch (das erste Byte von `ntdll!EtwEventWrite` mit `0xC3` überschreiben) blendet nur den *aktuellen Prozess* aus. Verteidiger, die systemweite Telemetrie wollen — vor allem den von EDR genutzten Provider `Microsoft-Windows-Threat-Intelligence` — sammeln aus einer systemweiten Sitzung. Um die stillzulegen, greifen Angreifer zu `NtTraceControl` mit `FunctionCode=7` (`EtwpEnableTraceProvider`) und `EnableState=0`, um den Provider in der EDR-eigenen Sitzung zu *deaktivieren*, oder `FunctionCode=2` (`EtwpStopTrace`), um die Sitzung gleich ganz abzureißen. **Cobalt Strike**, **Brute Ratel C4**, **Havoc**, **Nighthawk** sowie die Open-Source-Tools **SharpEtwBypass** / **TamperETW** liefern Varianten davon. Kernel-Mode-Pendants (Lazarus-Rootkit **FudModule**) erreichen dasselbe, indem sie `EtwThreatIntProvRegHandle` direkt nullen — eine andere Primitive, die `NtTraceControl` komplett umgeht, aber denselben Blackout erzeugt. Eine Sitzung zu deaktivieren erfordert zudem, dass der aufrufende Prozess die Sitzung besitzt oder `SeSystemProfilePrivilege` / TrustedInstaller-Vertrauen hält — weshalb die meisten Ketten zuerst über einen SYSTEM-Kontext-Payload pivotieren.
Erkennungsmöglichkeiten
Hook-basierte AVs sehen dies nicht — per Definition deaktiviert der Angreifer ja die Telemetrie. Die kernelseitige Erkennung lautet, *nicht auf die Sitzung als lebend zu vertrauen*: einen zweiten, redundanten ETW-Threat-Intelligence-Consumer aus einem Kernel-Treiber registrieren (PPL-EDR-Treiber tun das), oder den Provider `Microsoft-Windows-Kernel-EventTracing` nutzen, der administrative Events (4 = SessionStop, 12 = TraceConfigChange) an sich selbst loggt. Achten Sie auf jeden nicht-Microsoft-signierten Prozess, der `ControlTraceW` gegen bekannte EDR-Sitzungsnamen aufruft (`DefenderApiLogger`, `EventLog-Security`, `MS_Mon_*`, herstellerspezifisch). Auf Server 2022+ loggt der Windows-Defender-for-Endpoint-Sensor ETW-Sitzungsmanipulation direkt als Alert. Auf Kernel-Ebene ist `EtwThreatIntProvRegHandle == NULL`, während das System angeblich mit aktiviertem TI-Logging läuft, das Smoking Gun für die BYOVD-Variante.
Direkte Syscall-Beispiele
cDisable Threat-Intelligence provider in a target session
// Disable Microsoft-Windows-Threat-Intelligence (GUID {f4e1897c-bb5d-5668-f1d8-040f4d8dd344})
// inside an existing logger session. Requires SeSystemProfilePrivilege or session ownership.
#include <windows.h>
#include <evntrace.h>
static const GUID kThreatIntel =
{ 0xf4e1897c, 0xbb5d, 0x5668, { 0xf1,0xd8,0x04,0x0f,0x4d,0x8d,0xd3,0x44 } };
void disable_ti_in_session(TRACEHANDLE hSession) {
ENABLE_TRACE_PARAMETERS p = { 0 };
p.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
EnableTraceEx2(
hSession,
&kThreatIntel,
EVENT_CONTROL_CODE_DISABLE_PROVIDER, // -> NtTraceControl FunctionCode=7, EnableState=0
TRACE_LEVEL_NONE,
0, 0, 0, &p);
}cStop a named EDR session outright
// Tears the whole session down — EtwpStopTrace via NtTraceControl FunctionCode=2.
BYTE buf[sizeof(EVENT_TRACE_PROPERTIES) + 1024] = { 0 };
EVENT_TRACE_PROPERTIES* props = (EVENT_TRACE_PROPERTIES*)buf;
props->Wnode.BufferSize = sizeof(buf);
props->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
ULONG st = ControlTraceW(
0,
L"DefenderApiLogger", // typical Microsoft Defender ETW session
props,
EVENT_TRACE_CONTROL_STOP);asmx64 direct stub (Win11 24H2 / Server 2025, SSN 0x1D6)
; The SSN drifts per build — resolve dynamically with Halo's Gate for portability.
NtTraceControl PROC
mov r10, rcx
mov eax, 1D6h
syscall
ret
NtTraceControl ENDPMITRE ATT&CK-Mappings
Last verified: 2026-05-20