> Windows Syscalls
ntoskrnl.exeT1134T1548.002T1106

NtSetInformationToken

Écrit une propriété d'un token d'accès — niveau d'intégrité, session id, owner, DACL par défaut, politique d'audit, token lié.

Prototype

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

Arguments

NameTypeDirDescription
TokenHandleHANDLEinHandle vers le token. Accès requis selon la classe — typiquement TOKEN_ADJUST_DEFAULT, TOKEN_ADJUST_PRIVILEGES ou TOKEN_ADJUST_SESSIONID.
TokenInformationClassTOKEN_INFORMATION_CLASSinÉnum : TokenPrivileges (3), TokenOwner (4), TokenDefaultDacl (6), TokenSessionId (12), TokenAuditPolicy (16), TokenOrigin (17), TokenLinkedToken (19), TokenIntegrityLevel (25), TokenUIAccess (26).
TokenInformationPVOIDinTampon contenant la nouvelle valeur. Structure dépend de la classe (TOKEN_PRIVILEGES, TOKEN_MANDATORY_LABEL, etc.).
TokenInformationLengthULONGinTaille en octets de TokenInformation. STATUS_INFO_LENGTH_MISMATCH si elle ne correspond pas à la taille attendue pour la classe.

IDs de syscalls par version de Windows

Version 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

Module noyau

ntoskrnl.exeNtSetInformationToken

APIs liées

SetTokenInformationNtAdjustPrivilegesTokenNtQueryInformationTokenNtDuplicateTokenCreateRestrictedTokenImpersonateLoggedOnUser

Stub du 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

Notes non documentées

Le routeur noyau de `SetTokenInformation`. Classes intéressantes : `TokenIntegrityLevel` (25) — écraser le SID de label obligatoire, sert à élever ou (plus souvent) abaisser l'intégrité du token ; `TokenSessionId` (12) — change la session d'exécution du token, exige SeTcbPrivilege, sert aux services pour pivoter vers la session d'un utilisateur connecté ; `TokenPrivileges` (3) — couplé à `NtAdjustPrivilegesToken`, permet le remplacement en gros du jeu de privilèges ; `TokenLinkedToken` (19) — apparier un token filtré avec son jumeau full-admin dans le contexte UAC split-token ; `TokenUIAccess` (26) — bascule le bit qui permet au token de piloter l'UI de processus à IL plus élevé (contournement d'UIPI). Régler la plupart des classes exige que le token soit ouvert avec le TOKEN_ADJUST_* correspondant ; certaines (TokenSessionId, TokenAuditPolicy) demandent des privilèges système.

Usage courant par les malwares

Trois recettes à fort signal. (1) Abaissement d'intégrité : ouvrir le token d'un enfant cible en TOKEN_ADJUST_DEFAULT, fixer TokenIntegrityLevel au SID Low ou Untrusted — produit une sandbox proche d'AppContainer sans passer par toute la machinerie LowBox, parfois utilisé pour lancer un helper furtif inviable à énumérer pour un admin curieux. (2) Pivot de session : un service SYSTEM en session 0 utilise TokenSessionId pour pousser un token SYSTEM dupliqué en session 1, permettant à `CreateProcessAsUser` de livrer du payload interactif (vu chez certains RAT et utilitaires service-vers-bureau). (3) Composant de bypass UAC : en split-token, intervertir TokenLinkedToken pour attacher le jumeau élevé, puis ré-impersonner — variante de T1548.002. Le flip UIAccess est utilisé par des injecteurs GUI furtifs (classe FinFisher) pour contourner UIPI sur les contrôles MSAA d'apps à IL plus élevé.

Opportunités de détection

L'ETW Microsoft-Windows-Threat-Intelligence émet un événement pour les changements `TokenIntegrityLevel` et `TokenSessionId` (`EtwTiLogSetTokenAttributes`). Defender for Endpoint le présente comme `TokenManipulation`. Sysmon ne le journalise pas directement, mais un processus qui a fait `NtOpenProcessToken` puis `NtSetInformationToken(class=25)` contre un PID *qu'il ne possède pas* est suspect. Pour les changements de SessionId, corréler avec un `NtCreateUserProcess` montrant `TokenSessionId` != `ParentSessionId`. Les flips UIAccess remontent un Security 4703 (ajustement de privilèges du token) seulement indirectement via les privilèges effets secondaires ; la détection fiable passe par le signal ETW noyau.

Exemples de syscalls directs

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)
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20