> Windows Syscalls
ntoskrnl.exeT1134T1134.002T1106

NtFilterToken

Crea una copia restringida (filtrada) de un token de acceso existente desactivando SIDs, eliminando privilegios o agregando SIDs restringidos.

Prototipo

NTSTATUS NtFilterToken(
  HANDLE          ExistingTokenHandle,
  ULONG           Flags,
  PTOKEN_GROUPS   SidsToDisable,
  PTOKEN_PRIVILEGES PrivilegesToDelete,
  PTOKEN_GROUPS   RestrictedSids,
  PHANDLE         NewTokenHandle
);

Argumentos

NameTypeDirDescription
ExistingTokenHandleHANDLEinHandle al token origen (requiere acceso TOKEN_DUPLICATE).
FlagsULONGinCombinación de DISABLE_MAX_PRIVILEGE, SANDBOX_INERT, LUA_TOKEN, WRITE_RESTRICTED.
SidsToDisablePTOKEN_GROUPSinLista opcional de SIDs a marcar como deny-only en el nuevo token (NULL los deja habilitados).
PrivilegesToDeletePTOKEN_PRIVILEGESinLista opcional de privilegios a quitar del nuevo token (p. ej. SeDebugPrivilege, SeImpersonatePrivilege).
RestrictedSidsPTOKEN_GROUPSinLista opcional de SIDs restringidos añadidos al nuevo token; el kernel los comprueba en AND con cada DACL.
NewTokenHandlePHANDLEoutRecibe el handle del token filtrado recién creado si tiene éxito.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070xD5win10-1507
Win10 16070xD8win10-1607
Win10 17030xDBwin10-1703
Win10 17090xDCwin10-1709
Win10 18030xDDwin10-1803
Win10 18090xDEwin10-1809
Win10 19030xDFwin10-1903
Win10 19090xDFwin10-1909
Win10 20040xE4win10-2004
Win10 20H20xE4win10-20h2
Win10 21H10xE4win10-21h1
Win10 21H20xE5win10-21h2
Win10 22H20xE5win10-22h2
Win11 21H20xEAwin11-21h2
Win11 22H20xEBwin11-22h2
Win11 23H20xEBwin11-23h2
Win11 24H20xEDwin11-24h2
Server 20160xD8winserver-2016
Server 20190xDEwinserver-2019
Server 20220xE9winserver-2022
Server 20250xEDwinserver-2025

Módulo del kernel

ntoskrnl.exeNtFilterToken

APIs relacionadas

CreateRestrictedTokenDuplicateTokenExAdjustTokenPrivilegesNtDuplicateTokenNtAdjustPrivilegesTokenNtSetInformationToken

Stub del syscall

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

Notas no documentadas

NtFilterToken es la implementación de kernel detrás de advapi32!CreateRestrictedToken. A partir de un token origen devuelve un nuevo token primario o de impersonación con ciertos SIDs marcados como deny-only, ciertos privilegios eliminados y opcionales *restricted SIDs* adjuntos. Los restricted SIDs son potentes: en cada chequeo de acceso el kernel hace AND entre el acceso concedido y lo que la lista de restricted SIDs por sí sola habría concedido, así que el token resultante puede quedar muy por debajo de los derechos normales del usuario. La SSN cambia casi en cada actualización mayor (`0xD5` en Win10 1507, `0xED` en Win11 24H2), por lo que la resolución dinámica es obligatoria.

Uso común por malware

Usada legítimamente por los sandboxes de Chromium / Edge / Acrobat y por los brokers de AppContainer. El uso ofensivo existe pero es más raro: un atacante con un token de alto privilegio (SYSTEM, o un usuario impersonado con SeDebugPrivilege) puede *degradar* deliberadamente un proceso hijo o un contexto de impersonación para parecerse a un usuario poco privilegiado — una forma de token demotion que evade detecciones basadas en "SYSTEM hizo X". Algunos frameworks de red team y un puñado de muestras de investigación envuelven NtFilterToken precisamente por eso. *No* es una señal ofensiva fuerte por sí sola.

Oportunidades de detección

La cobertura de eventos de token es el punto de partida correcto: los eventos 4696/4624 de Microsoft-Windows-Security-Auditing exponen cambios de token de logon, y ETW Microsoft-Windows-Kernel-Audit-API-Calls cubre la creación de tokens. Los EDR suelen hookear NtFilterToken para alimentar sus grafos de derivación de tokens. Señal blue-team útil: NtFilterToken invocada *con* un token origen de alto privilegio *desde* un proceso inusual (ni navegador, ni broker). Combinar con NtCreateUserProcess + AssignPrimaryToken posteriores para detectar una token demotion deliberada antes de la ejecución del proceso hijo.

Ejemplos de syscalls directos

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 ENDP

cToken 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),
    );
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20