> Windows Syscalls
ntoskrnl.exeT1134T1134.001T1106

NtOpenProcessToken

Abre el token de acceso asociado a un proceso y devuelve un handle hacia él.

Prototipo

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

Argumentos

NameTypeDirDescription
ProcessHandleHANDLEinHandle al proceso cuyo token se abre. Debe tener PROCESS_QUERY_INFORMATION (o PROCESS_QUERY_LIMITED_INFORMATION).
DesiredAccessACCESS_MASKinDerechos solicitados sobre el token, p. ej. TOKEN_QUERY (0x8), TOKEN_DUPLICATE (0x2), TOKEN_ADJUST_PRIVILEGES (0x20), TOKEN_ALL_ACCESS.
TokenHandlePHANDLEoutRecibe el handle al token abierto en caso de éxito. Debe cerrarse con NtClose.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
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

Módulo del kernel

ntoskrnl.exeNtOpenProcessToken

APIs relacionadas

OpenProcessTokenNtOpenProcessTokenExNtOpenThreadTokenNtDuplicateTokenNtQueryInformationTokenNtAdjustPrivilegesToken

Stub del syscall

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

Notas no documentadas

NtOpenProcessToken es la forma heredada de la primitiva de apertura de token, conservada por compatibilidad con la API NT original. Las rutas modernas en `kernel32!OpenProcessToken` realmente invocan `NtOpenProcessTokenEx` con `HandleAttributes = 0`. El SSN deriva considerablemente entre builds — de `0x114` en Windows 10 1507 a `0x133` en Windows 11 24H2 — lo que lo convierte en mal candidato para SSN codificados y un caso de manual para resolución dinámica vía Hell's Gate / Halo's Gate. Internamente, despacha a través de `SeQueryAuthenticationIdToken` y `ObOpenObjectByPointer` contra el puntero EPROCESS->Token.

Uso común por malware

Siempre el primer paso de una cadena de robo de token: abrir un proceso de alta integridad (winlogon, services.exe, lsass.exe) con `TOKEN_DUPLICATE | TOKEN_QUERY`, luego llamar a NtDuplicateToken para forjar un token de impersonación SecurityImpersonation, y por último NtSetInformationThread (ThreadImpersonationToken) o CreateProcessWithTokenW para arrancar bajo la identidad robada. Es el patrón clásico Incognito / Mimikatz `token::elevate` y la base de la mayor parte del movimiento lateral post-explotación observado en Conti, BlackCat y APT29.

Oportunidades de detección

Abrir un token sobre un proceso que no es tuyo requiere normalmente SeDebugPrivilege — el evento Windows Security 4672 (Special Privileges Assigned) sobre la sesión de logon llamante es un precursor sólido. El evento 4663 (object access) con tipo de objeto `Token` y 4673 (Sensitive Privilege Use) se disparan cuando la operación tiene éxito sobre un proceso privilegiado. El provider ETW `Microsoft-Windows-Kernel-Audit-API-Calls` emite eventos `PsOpenProcessToken`. Los EDR hookean `ntdll!NtOpenProcessToken`; los syscalls directos evaden los hooks de user-mode pero el kernel sigue emitiendo auditoría SE_TOKEN_USER del object-manager en procesos protegidos.

Ejemplos de syscalls directos

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

Mapeos MITRE ATT&CK

Last verified: 2026-05-20