NtFilterToken
Erzeugt eine eingeschränkte (gefilterte) Kopie eines bestehenden Access-Tokens durch Deaktivieren von SIDs, Entfernen von Privilegien oder Hinzufügen restricted SIDs.
Prototyp
NTSTATUS NtFilterToken( HANDLE ExistingTokenHandle, ULONG Flags, PTOKEN_GROUPS SidsToDisable, PTOKEN_PRIVILEGES PrivilegesToDelete, PTOKEN_GROUPS RestrictedSids, PHANDLE NewTokenHandle );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| ExistingTokenHandle | HANDLE | in | Handle auf das Quell-Token (benötigt TOKEN_DUPLICATE-Zugriff). |
| Flags | ULONG | in | Kombination aus DISABLE_MAX_PRIVILEGE, SANDBOX_INERT, LUA_TOKEN, WRITE_RESTRICTED. |
| SidsToDisable | PTOKEN_GROUPS | in | Optionale Liste von SIDs, die im neuen Token als deny-only markiert werden (NULL belässt sie aktiv). |
| PrivilegesToDelete | PTOKEN_PRIVILEGES | in | Optionale Liste von Privilegien, die aus dem neuen Token entfernt werden (z. B. SeDebugPrivilege, SeImpersonatePrivilege). |
| RestrictedSids | PTOKEN_GROUPS | in | Optionale Liste restricted SIDs, die dem neuen Token hinzugefügt werden; der Kernel prüft sie UND-verknüpft mit jeder DACL. |
| NewTokenHandle | PHANDLE | out | Erhält das Handle des neu gefilterten Tokens bei Erfolg. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0xD5 | win10-1507 |
| Win10 1607 | 0xD8 | win10-1607 |
| Win10 1703 | 0xDB | win10-1703 |
| Win10 1709 | 0xDC | win10-1709 |
| Win10 1803 | 0xDD | win10-1803 |
| Win10 1809 | 0xDE | win10-1809 |
| Win10 1903 | 0xDF | win10-1903 |
| Win10 1909 | 0xDF | win10-1909 |
| Win10 2004 | 0xE4 | win10-2004 |
| Win10 20H2 | 0xE4 | win10-20h2 |
| Win10 21H1 | 0xE4 | win10-21h1 |
| Win10 21H2 | 0xE5 | win10-21h2 |
| Win10 22H2 | 0xE5 | win10-22h2 |
| Win11 21H2 | 0xEA | win11-21h2 |
| Win11 22H2 | 0xEB | win11-22h2 |
| Win11 23H2 | 0xEB | win11-23h2 |
| Win11 24H2 | 0xED | win11-24h2 |
| Server 2016 | 0xD8 | winserver-2016 |
| Server 2019 | 0xDE | winserver-2019 |
| Server 2022 | 0xE9 | winserver-2022 |
| Server 2025 | 0xED | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 ED 00 00 00 mov eax, 0xED 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
NtFilterToken ist die Kernel-Implementierung hinter advapi32!CreateRestrictedToken. Aus einem Quell-Token wird ein neues Primary- oder Impersonation-Token erzeugt, in dem ausgewählte SIDs auf deny-only gesetzt, ausgewählte Privilegien entfernt und optional *Restricted SIDs* angehängt sind. Restricted SIDs sind mächtig: bei jeder Access Check UND-verknüpft der Kernel den gewährten Zugriff mit dem, was die Restricted-SID-Liste allein erlaubt hätte; das resultierende Token kann so weit unter die normalen Benutzerrechte gedrückt werden. Die SSN driftet bei nahezu jedem Feature-Update (`0xD5` auf Win10 1507, `0xED` auf Win11 24H2), dynamische Auflösung ist daher Pflicht.
Häufige Malware-Nutzung
Wird legitim von den Chromium-/Edge-/Acrobat-Sandboxes und von AppContainer-Brokern genutzt. Offensiver Einsatz existiert, ist aber seltener: ein Angreifer mit hochprivilegiertem Token (SYSTEM oder ein imitierter Benutzer mit SeDebugPrivilege) kann einen Kindprozess oder Impersonation-Kontext bewusst *herabstufen*, damit er wie ein gering privilegierter Benutzer aussieht — eine Form von Token Demotion, die Detektionen umgeht, die auf „SYSTEM hat X getan" basieren. Einige Red-Team-Frameworks und wenige Forschungs-Samples wrappen NtFilterToken genau aus diesem Grund. Allein ist es *kein* starkes Offensiv-Signal.
Erkennungsmöglichkeiten
Token-Event-Abdeckung ist der richtige Einstieg: die Events 4696/4624 in Microsoft-Windows-Security-Auditing zeigen Logon-Token-Wechsel, und ETW Microsoft-Windows-Kernel-Audit-API-Calls deckt Token-Erzeugung ab. EDRs hooken NtFilterToken üblicherweise, um Token-Ableitungsgraphen zu füttern. Nützliches Blue-Team-Signal: NtFilterToken aufgerufen *mit* einem hochprivilegierten Quell-Token *aus* einem unüblichen Prozess (kein Browser, kein Broker). Kombinieren mit nachfolgendem NtCreateUserProcess + AssignPrimaryToken, um gezielte Token Demotion vor Kindprozessstart zu erkennen.
Direkte Syscall-Beispiele
asmx64 direct stub (Win11 24H2 SSN)
; Direct syscall stub for NtFilterToken (SSN 0xED on Win11 24H2 / Server 2025)
NtFilterToken PROC
mov r10, rcx ; syscall convention
mov eax, 0EDh ; SSN for win11-24h2
syscall
ret
NtFilterToken ENDPcToken demotion: strip privileges from current token
// Take the current process token and produce a filtered copy with SeDebugPrivilege
// and SeImpersonatePrivilege removed — useful for spawning a less-suspicious child.
HANDLE hCurrent = NULL;
NtOpenProcessToken(NtCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hCurrent);
LUID seDebug, seImpersonate;
LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &seDebug);
LookupPrivilegeValueW(NULL, L"SeImpersonatePrivilege", &seImpersonate);
struct {
DWORD Count;
LUID_AND_ATTRIBUTES Priv[2];
} toDelete = { 2, {{seDebug, 0}, {seImpersonate, 0}} };
HANDLE hFiltered = NULL;
NtFilterToken(hCurrent,
DISABLE_MAX_PRIVILEGE, // also strip every non-mandatory privilege
NULL, // SidsToDisable
(PTOKEN_PRIVILEGES)&toDelete,
NULL, // RestrictedSids
&hFiltered);rustwindows-sys + naked syscall stub
// Cargo: windows-sys = "0.59" (Win32_Security)
use std::arch::asm;
#[unsafe(naked)]
unsafe extern "system" fn nt_filter_token_stub() {
asm!(
"mov r10, rcx",
"mov eax, 0xED", // Win11 24H2; resolve dynamically for other builds
"syscall",
"ret",
options(noreturn),
);
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20