NtSetInformationToken
Schreibt eine Token-Eigenschaft — Integritätslevel, Session-ID, Owner, Standard-DACL, Audit-Policy, Linked-Token.
Prototyp
NTSTATUS NtSetInformationToken( HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, PVOID TokenInformation, ULONG TokenInformationLength );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| TokenHandle | HANDLE | in | Handle auf das Token. Erforderlicher Zugriff hängt von der Klasse ab — meist TOKEN_ADJUST_DEFAULT, TOKEN_ADJUST_PRIVILEGES oder TOKEN_ADJUST_SESSIONID. |
| TokenInformationClass | TOKEN_INFORMATION_CLASS | in | Enum: TokenPrivileges (3), TokenOwner (4), TokenDefaultDacl (6), TokenSessionId (12), TokenAuditPolicy (16), TokenOrigin (17), TokenLinkedToken (19), TokenIntegrityLevel (25), TokenUIAccess (26). |
| TokenInformation | PVOID | in | Puffer mit dem neuen Wert. Struktur richtet sich nach der Klasse (TOKEN_PRIVILEGES, TOKEN_MANDATORY_LABEL usw.). |
| TokenInformationLength | ULONG | in | Größe von TokenInformation in Bytes. STATUS_INFO_LENGTH_MISMATCH bei Abweichung von der klassen-erwarteten Größe. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x17F | win10-1507 |
| Win10 1607 | 0x188 | win10-1607 |
| Win10 1703 | 0x18E | win10-1703 |
| Win10 1709 | 0x191 | win10-1709 |
| Win10 1803 | 0x193 | win10-1803 |
| Win10 1809 | 0x194 | win10-1809 |
| Win10 1903 | 0x195 | win10-1903 |
| Win10 1909 | 0x195 | win10-1909 |
| Win10 2004 | 0x19B | win10-2004 |
| Win10 20H2 | 0x19B | win10-20h2 |
| Win10 21H1 | 0x19B | win10-21h1 |
| Win10 21H2 | 0x19D | win10-21h2 |
| Win10 22H2 | 0x19D | win10-22h2 |
| Win11 21H2 | 0x1A6 | win11-21h2 |
| Win11 22H2 | 0x1AA | win11-22h2 |
| Win11 23H2 | 0x1AA | win11-23h2 |
| Win11 24H2 | 0x1AD | win11-24h2 |
| Server 2016 | 0x188 | winserver-2016 |
| Server 2019 | 0x194 | winserver-2019 |
| Server 2022 | 0x1A3 | winserver-2022 |
| Server 2025 | 0x1AD | winserver-2025 |
Kernel-Modul
Verwandte APIs
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
Undokumentierte Hinweise
Der Kernel-Router von `SetTokenInformation`. Interessante Klassen: `TokenIntegrityLevel` (25) — Mandatory-Label-SID überschreiben, hebt oder (häufiger) senkt die Integrität des Tokens; `TokenSessionId` (12) — ändert die Session, in der das Token läuft, erfordert SeTcbPrivilege, von Services genutzt, um in die Session eines angemeldeten Benutzers zu pivotieren; `TokenPrivileges` (3) — gepaart mit `NtAdjustPrivilegesToken`, erlaubt großflächigen Ersatz des Privilegien-Sets; `TokenLinkedToken` (19) — gefiltertes Token mit seinem Full-Admin-Zwilling im Split-Token-UAC-Kontext koppeln; `TokenUIAccess` (26) — kippt das Bit, das dem Token erlaubt, die UI von Prozessen höherer IL zu bedienen (UIPI-Bypass). Das Setzen der meisten Klassen verlangt, dass das Token mit passendem TOKEN_ADJUST_* geöffnet ist; einige (TokenSessionId, TokenAuditPolicy) fordern systemweite Privilegien.
Häufige Malware-Nutzung
Drei hochwertige Rezepte. (1) Integritäts-Absenkung: Token eines Ziel-Kindes mit TOKEN_ADJUST_DEFAULT öffnen, TokenIntegrityLevel auf Low- oder Untrusted-SID setzen — ergibt eine AppContainer-nahe Sandbox ohne die volle LowBox-Maschinerie, manchmal, um einen Stealth-Helfer zu starten, den ein neugieriger Admin kaum enumerieren kann. (2) Session-Pivot: Ein SYSTEM-Service in Session 0 nutzt TokenSessionId, um ein dupliziertes SYSTEM-Token in Session 1 zu schieben — so kann `CreateProcessAsUser` interaktive Payloads ausliefern (in einigen Commodity-RATs und Service-to-Desktop-Tools beobachtet). (3) UAC-Bypass-Baustein: im Split-Token TokenLinkedToken austauschen, um den elevierten Zwilling anzuhängen, dann erneut impersonieren — Variante von T1548.002. UIAccess-Flips nutzen sneaky GUI-Injectors (FinFisher-Klasse), um UIPI bei MSAA-Controls höherer IL-Apps zu umgehen.
Erkennungsmöglichkeiten
Microsoft-Windows-Threat-Intelligence-ETW emittiert Events für `TokenIntegrityLevel`- und `TokenSessionId`-Änderungen (`EtwTiLogSetTokenAttributes`). Defender for Endpoint zeigt das als `TokenManipulation`. Sysmon loggt es nicht direkt, aber ein Prozess, der `NtOpenProcessToken` und dann `NtSetInformationToken(class=25)` gegen eine *fremde* PID absetzt, ist verdächtig. Für SessionId-Wechsel mit nachfolgendem `NtCreateUserProcess` mit `TokenSessionId` != `ParentSessionId` korrelieren. UIAccess-Flips erzeugen Security-Event 4703 (Privilegien-Anpassung) nur indirekt über Nebeneffekt-Privilegien; verlässliche Detection braucht das Kernel-ETW-Signal.
Direkte Syscall-Beispiele
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