> Windows Syscalls
ntoskrnl.exeT1134T1548.002T1106

NtSetInformationToken

Writes a property on an access token — integrity level, session id, owner, default DACL, audit policy, linked token.

Prototype

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

Arguments

NameTypeDirDescription
TokenHandleHANDLEinHandle to the token. Required access depends on the class — typically TOKEN_ADJUST_DEFAULT, TOKEN_ADJUST_PRIVILEGES or TOKEN_ADJUST_SESSIONID.
TokenInformationClassTOKEN_INFORMATION_CLASSinEnum: TokenPrivileges (3), TokenOwner (4), TokenDefaultDacl (6), TokenSessionId (12), TokenAuditPolicy (16), TokenOrigin (17), TokenLinkedToken (19), TokenIntegrityLevel (25), TokenUIAccess (26).
TokenInformationPVOIDinBuffer with the new value. Structure depends on the class (TOKEN_PRIVILEGES, TOKEN_MANDATORY_LABEL, etc.).
TokenInformationLengthULONGinSize in bytes of TokenInformation. STATUS_INFO_LENGTH_MISMATCH if it disagrees with the class's expected size.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
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

Kernel module

ntoskrnl.exeNtSetInformationToken

Related APIs

SetTokenInformationNtAdjustPrivilegesTokenNtQueryInformationTokenNtDuplicateTokenCreateRestrictedTokenImpersonateLoggedOnUser

Syscall stub

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

Undocumented notes

The kernel-side router for `SetTokenInformation`. The interesting classes are: `TokenIntegrityLevel` (25) — overwrite the mandatory label SID on the token, used to raise or (more often) lower a token's integrity; `TokenSessionId` (12) — change the session in which the token will run, requires SeTcbPrivilege, used by services to pivot into a logged-on user's session for interactive payload delivery; `TokenPrivileges` (3) — paired with `NtAdjustPrivilegesToken`, allows wholesale replacement of the privilege set on the token; `TokenLinkedToken` (19) — pair a filtered token with its full-admin twin for split-token UAC contexts; `TokenUIAccess` (26) — flip the bit that allows a token to drive the UI of higher-IL processes (UIPI bypass). Setting most classes requires the token to be open for the matching TOKEN_ADJUST_* access; some (TokenSessionId, TokenAuditPolicy) require system-wide privileges.

Common malware usage

Three high-signal recipes. (1) Integrity-level lowering: open the process token of a target child with TOKEN_ADJUST_DEFAULT, set TokenIntegrityLevel to Low or Untrusted SID — produces an AppContainer-adjacent sandbox without going through the full LowBox machinery, sometimes used to spawn a stealth-helper that cannot be enumerated by curious admins. (2) Token session pivot: services running as SYSTEM in session 0 use TokenSessionId to push a duplicated SYSTEM token into session 1, enabling `CreateProcessAsUser` to deliver interactive payloads (used by some commodity remote-access trojans and various 'service-to-desktop' utilities). (3) UAC bypass component: in split-token contexts, swap TokenLinkedToken to attach the elevated twin, then re-impersonate — variant on T1548.002. UIAccess flipping is used by sneaky GUI-injectors (FinFisher-class) to bypass UIPI when targeting MSAA controls of higher-IL apps.

Detection opportunities

Microsoft-Windows-Threat-Intelligence ETW emits an event for `TokenIntegrityLevel` and `TokenSessionId` changes (`EtwTiLogSetTokenAttributes`). Defender for Endpoint surfaces this as `TokenManipulation`. Sysmon does not log it directly, but a process that issued `NtOpenProcessToken` then `NtSetInformationToken(class=25)` against a *non-owned* PID is suspicious. For SessionId changes, correlate with subsequent `NtCreateUserProcess` showing `TokenSessionId` != `ParentSessionId`. UIAccess flips raise a Security event ID 4703 (token privilege adjustment) only indirectly via the side-effect privileges; reliable detection requires the kernel ETW signal.

Direct syscall examples

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

MITRE ATT&CK mappings

Last verified: 2026-05-20