NtOpenProcessTokenEx
Öffnet das Zugriffstoken eines Prozesses und erlaubt dem Aufrufer, Handle-Attribute wie OBJ_INHERIT anzugeben.
Prototyp
NTSTATUS NtOpenProcessTokenEx( HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, PHANDLE TokenHandle );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| ProcessHandle | HANDLE | in | Handle auf den Prozess, dessen Token geöffnet wird. Benötigt PROCESS_QUERY_(LIMITED_)INFORMATION. |
| DesiredAccess | ACCESS_MASK | in | Token-Zugriffsrechte — Kombinationen aus TOKEN_QUERY, TOKEN_DUPLICATE, TOKEN_ADJUST_PRIVILEGES, TOKEN_IMPERSONATE usw. |
| HandleAttributes | ULONG | in | OBJECT_ATTRIBUTES-Flags wie OBJ_INHERIT (0x2) oder OBJ_KERNEL_HANDLE (0x200). Häufig 0. |
| TokenHandle | PHANDLE | out | Erhält bei Erfolg das Handle auf das geöffnete Token. Muss mit NtClose geschlossen werden. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x30 | win10-1507 |
| Win10 1607 | 0x30 | win10-1607 |
| Win10 1703 | 0x30 | win10-1703 |
| Win10 1709 | 0x30 | win10-1709 |
| Win10 1803 | 0x30 | win10-1803 |
| Win10 1809 | 0x30 | win10-1809 |
| Win10 1903 | 0x30 | win10-1903 |
| Win10 1909 | 0x30 | win10-1909 |
| Win10 2004 | 0x30 | win10-2004 |
| Win10 20H2 | 0x30 | win10-20h2 |
| Win10 21H1 | 0x30 | win10-21h1 |
| Win10 21H2 | 0x30 | win10-21h2 |
| Win10 22H2 | 0x30 | win10-22h2 |
| Win11 21H2 | 0x30 | win11-21h2 |
| Win11 22H2 | 0x30 | win11-22h2 |
| Win11 23H2 | 0x30 | win11-23h2 |
| Win11 24H2 | 0x30 | win11-24h2 |
| Server 2016 | 0x30 | winserver-2016 |
| Server 2019 | 0x30 | winserver-2019 |
| Server 2022 | 0x30 | winserver-2022 |
| Server 2025 | 0x30 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 30 00 00 00 mov eax, 0x30 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
NtOpenProcessTokenEx ist die kanonische Primitive, die `kernel32!OpenProcessToken` tatsächlich aufruft — `NtOpenProcessToken` ist im Wesentlichen ein Wrapper, der aus Quellkompatibilität mit NT 3.x erhalten blieb. Anders als die Legacy-Variante ist ihr SSN von Windows 10 1507 bis Windows 11 24H2 **stabil bei `0x30`**, was sie zum bevorzugten Ziel für Loader mit hartkodiertem SSN und SysWhispers-Stubs macht. Der zusätzliche `HandleAttributes`-Parameter erlaubt das Anfordern vererbbarer Handles (`OBJ_INHERIT`) — nützlich für Child-Prozesse mit gespooftem Parent-PID, die das Token erben sollen.
Häufige Malware-Nutzung
Gleiche Rolle wie NtOpenProcessToken in Token-Diebstahlsketten, von modernen Loadern aber wegen des stabilen SSN bevorzugt. Cobalt Strikes `steal_token`-BOF und Slivers `getsystem`-Modul laufen darüber. JuicyPotato / RoguePotato / PrintSpoofer verhandeln zuerst ein SYSTEM-Token per RPC-Coercion, rufen dann NtOpenProcessTokenEx auf dem gespawnten Prozess auf, um ein duplizierbares Handle zu erhalten, und schließlich NtDuplicateToken + CreateProcessWithTokenW, um eine cmd.exe im SYSTEM-Kontext zu starten. Die Make-Me-Admin-UAC-Bypass-Familie nutzt es, um den elevierten Zwilling des Medium-IL-Tokens zu klonen.
Erkennungsmöglichkeiten
Identische Detection-Surface wie NtOpenProcessToken: 4672 (Special Privileges Assigned, SeDebugPrivilege), 4663 (Object Access auf Token), 4673 (Sensitive Privilege Use). Speziell für LSASS erzwingt RunAsPPL ein STATUS_ACCESS_DENIED, sofern der Aufrufer nicht selbst PPL ist — ein Fehlerevent mit hohem Signalwert. ETW `Microsoft-Windows-Kernel-Audit-API-Calls` emittiert `PsOpenProcessToken` unabhängig davon, welche Nt-Variante aufgerufen wurde. EDRs hooken diese Funktion häufig in ntdll; direkte Syscalls umgehen das, aber das kernelseitige Object-Access-Audit bleibt.
Direkte Syscall-Beispiele
asmx64 direct stub (stable SSN 0x30)
; SSN 0x30 stable across Win10 1507 -> Win11 24H2.
NtOpenProcessTokenEx PROC
mov r10, rcx ; ProcessHandle
mov eax, 30h ; SSN
syscall
ret
NtOpenProcessTokenEx ENDPcOpen elevated token for cross-session UAC clone (Make-Me-Admin)
// Locate the elevated split-token sibling of the current medium-IL process
// and ask for TOKEN_DUPLICATE so we can spawn a high-IL process with it.
HANDLE hElev = NULL, hTok = NULL;
// hElev = handle to a high-IL svchost / consent.exe we previously opened
NTSTATUS s = NtOpenProcessTokenEx(
hElev,
TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY,
0, // HandleAttributes
&hTok);
if (NT_SUCCESS(s)) {
// Next: NtDuplicateToken(... TokenPrimary ...) -> CreateProcessWithTokenW
}rustwindows-sys wrapper with naked-asm direct syscall
use std::arch::asm;
use windows_sys::Win32::Foundation::HANDLE;
#[unsafe(naked)]
pub unsafe extern "system" fn nt_open_process_token_ex(
_process: HANDLE,
_desired: u32,
_handle_attrs: u32,
_token_out: *mut HANDLE,
) -> i32 {
asm!(
"mov r10, rcx",
"mov eax, 0x30",
"syscall",
"ret",
options(noreturn),
);
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20