> Windows Syscalls
ntoskrnl.exeT1134T1548.002T1106

NtSetInformationToken

Escribe una propiedad de un token de acceso — nivel de integridad, session id, owner, DACL por defecto, política de auditoría, token enlazado.

Prototipo

NTSTATUS NtSetInformationToken(
  HANDLE                  TokenHandle,
  TOKEN_INFORMATION_CLASS TokenInformationClass,
  PVOID                   TokenInformation,
  ULONG                   TokenInformationLength
);

Argumentos

NameTypeDirDescription
TokenHandleHANDLEinHandle al token. Acceso requerido según la clase — típicamente TOKEN_ADJUST_DEFAULT, TOKEN_ADJUST_PRIVILEGES o TOKEN_ADJUST_SESSIONID.
TokenInformationClassTOKEN_INFORMATION_CLASSinEnum: TokenPrivileges (3), TokenOwner (4), TokenDefaultDacl (6), TokenSessionId (12), TokenAuditPolicy (16), TokenOrigin (17), TokenLinkedToken (19), TokenIntegrityLevel (25), TokenUIAccess (26).
TokenInformationPVOIDinBúfer con el nuevo valor. La estructura depende de la clase (TOKEN_PRIVILEGES, TOKEN_MANDATORY_LABEL, etc.).
TokenInformationLengthULONGinTamaño en bytes de TokenInformation. STATUS_INFO_LENGTH_MISMATCH si no coincide con el tamaño esperado por la clase.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x17Fwin10-1507
Win10 16070x188win10-1607
Win10 17030x18Ewin10-1703
Win10 17090x191win10-1709
Win10 18030x193win10-1803
Win10 18090x194win10-1809
Win10 19030x195win10-1903
Win10 19090x195win10-1909
Win10 20040x19Bwin10-2004
Win10 20H20x19Bwin10-20h2
Win10 21H10x19Bwin10-21h1
Win10 21H20x19Dwin10-21h2
Win10 22H20x19Dwin10-22h2
Win11 21H20x1A6win11-21h2
Win11 22H20x1AAwin11-22h2
Win11 23H20x1AAwin11-23h2
Win11 24H20x1ADwin11-24h2
Server 20160x188winserver-2016
Server 20190x194winserver-2019
Server 20220x1A3winserver-2022
Server 20250x1ADwinserver-2025

Módulo del kernel

ntoskrnl.exeNtSetInformationToken

APIs relacionadas

SetTokenInformationNtAdjustPrivilegesTokenNtQueryInformationTokenNtDuplicateTokenCreateRestrictedTokenImpersonateLoggedOnUser

Stub del syscall

4C 8B D1            mov r10, rcx
B8 AD 01 00 00      mov eax, 0x1AD
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

El enrutador kernel de `SetTokenInformation`. Clases interesantes: `TokenIntegrityLevel` (25) — sobrescribir el SID de etiqueta obligatoria, se usa para elevar o (más a menudo) bajar la integridad del token; `TokenSessionId` (12) — cambia la sesión donde correrá el token, requiere SeTcbPrivilege, usado por servicios para pivotar a la sesión de un usuario conectado; `TokenPrivileges` (3) — emparejado con `NtAdjustPrivilegesToken`, permite reemplazar al por mayor el conjunto de privilegios; `TokenLinkedToken` (19) — emparejar un token filtrado con su gemelo full-admin en contextos UAC split-token; `TokenUIAccess` (26) — voltea el bit que permite al token manejar la UI de procesos con IL más alto (bypass de UIPI). Establecer la mayoría de las clases requiere que el token esté abierto con el TOKEN_ADJUST_* correspondiente; algunas (TokenSessionId, TokenAuditPolicy) exigen privilegios del sistema.

Uso común por malware

Tres recetas con señal alta. (1) Bajada de integridad: abrir el token de un hijo objetivo con TOKEN_ADJUST_DEFAULT, fijar TokenIntegrityLevel a SID Low o Untrusted — produce una sandbox cercana a AppContainer sin la maquinaria LowBox completa, a veces para lanzar un helper sigiloso difícil de enumerar para un admin curioso. (2) Pivote de sesión: un servicio SYSTEM en sesión 0 usa TokenSessionId para empujar un token SYSTEM duplicado a sesión 1, permitiendo a `CreateProcessAsUser` entregar payload interactivo (visto en RAT comerciales y utilidades servicio-a-escritorio). (3) Componente de bypass UAC: en split-token, intercambiar TokenLinkedToken para enganchar el gemelo elevado y re-impersonar — variante de T1548.002. El flip UIAccess lo usan inyectores GUI sigilosos (clase FinFisher) para evitar UIPI al apuntar a controles MSAA de apps con IL más alto.

Oportunidades de detección

El ETW Microsoft-Windows-Threat-Intelligence emite evento para cambios de `TokenIntegrityLevel` y `TokenSessionId` (`EtwTiLogSetTokenAttributes`). Defender for Endpoint lo presenta como `TokenManipulation`. Sysmon no lo registra directamente, pero un proceso que hizo `NtOpenProcessToken` y luego `NtSetInformationToken(class=25)` contra un PID *no propio* es sospechoso. Para cambios de SessionId correlacione con un `NtCreateUserProcess` posterior que muestre `TokenSessionId` != `ParentSessionId`. Los flips UIAccess generan Security 4703 (ajuste de privilegios) solo indirectamente vía privilegios derivados; la detección fiable requiere la señal ETW del kernel.

Ejemplos de syscalls directos

cLower integrity level on a child process token

// Build a TOKEN_MANDATORY_LABEL pointing at the Low integrity SID, then apply.
#include <sddl.h>
typedef NTSTATUS(NTAPI* fnSet)(HANDLE, ULONG, PVOID, ULONG);

BOOL DropToLow(HANDLE hToken) {
    PSID pSid = NULL;
    if (!ConvertStringSidToSidA("S-1-16-4096" /* Low */, &pSid)) return FALSE;
    TOKEN_MANDATORY_LABEL tml = { { pSid, SE_GROUP_INTEGRITY } };
    HMODULE n = GetModuleHandleA("ntdll.dll");
    fnSet pSet = (fnSet)GetProcAddress(n, "NtSetInformationToken");
    DWORD len = (DWORD)(sizeof(tml) + GetLengthSid(pSid));
    NTSTATUS s = pSet(hToken, 25 /* TokenIntegrityLevel */, &tml, len);
    LocalFree(pSid);
    return s == 0;
}

cService pivot to interactive session via TokenSessionId

// SYSTEM in session 0 pushes a duplicated token into the active console session
// so CreateProcessAsUser can drop an interactive payload on the user's desktop.
// Requires SeTcbPrivilege already enabled on the source token.
typedef NTSTATUS(NTAPI* fnSet)(HANDLE, ULONG, PVOID, ULONG);

BOOL RetargetSession(HANDLE hDupToken, DWORD targetSessionId) {
    HMODULE n = GetModuleHandleA("ntdll.dll");
    fnSet pSet = (fnSet)GetProcAddress(n, "NtSetInformationToken");
    NTSTATUS s = pSet(hDupToken, 12 /* TokenSessionId */, &targetSessionId, sizeof(DWORD));
    return s == 0;
}

rustToggle UIAccess for UIPI bypass

// Flipping TokenUIAccess on a token whose process is signed with uiAccess=true in its manifest
// lets that process drive MSAA controls of higher-IL windows. Abused by GUI injectors.
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};

type NtSetInformationToken = unsafe extern "system" fn(
    token: isize, class: u32, info: *mut u8, len: u32,
) -> i32;

pub unsafe fn set_ui_access(token: isize, enable: bool) -> i32 {
    let n = GetModuleHandleA(b"ntdll.dll\0".as_ptr());
    let addr = GetProcAddress(n, b"NtSetInformationToken\0".as_ptr()).unwrap();
    let f: NtSetInformationToken = std::mem::transmute(addr);
    let mut v: u32 = if enable { 1 } else { 0 };
    f(token, 26 /* TokenUIAccess */, &mut v as *mut _ as *mut u8, 4)
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20