> Windows Syscalls
ntoskrnl.exeT1559T1106

NtAlpcAcceptConnectPort

Aceptación ALPC del lado servidor — completa una solicitud de conexión cliente pendiente y devuelve un puerto de comunicación por cliente.

Prototipo

NTSTATUS NtAlpcAcceptConnectPort(
  PHANDLE                  PortHandle,
  HANDLE                   ConnectionPortHandle,
  ULONG                    Flags,
  POBJECT_ATTRIBUTES       ObjectAttributes,
  PALPC_PORT_ATTRIBUTES    PortAttributes,
  PVOID                    PortContext,
  PPORT_MESSAGE            ConnectionRequest,
  PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
  BOOLEAN                  AcceptConnection
);

Argumentos

NameTypeDirDescription
PortHandlePHANDLEoutRecibe un handle al nuevo puerto de comunicación por cliente (o NULL si AcceptConnection es FALSE).
ConnectionPortHandleHANDLEinHandle al puerto de conexión del servidor en escucha, creado previamente con NtAlpcCreatePort.
FlagsULONGinBanderas de conexión ALPC (ALPC_MSGFLG_SYNC_REQUEST, ALPC_PORFLG_*); normalmente 0.
ObjectAttributesPOBJECT_ATTRIBUTESinAtributos de objeto opcionales para el nuevo puerto de comunicación; normalmente NULL.
PortAttributesPALPC_PORT_ATTRIBUTESinAtributos de puerto del lado servidor (tamaño máx de mensaje, tamaño de vista, QoS de seguridad) que rigen este puerto cliente.
PortContextPVOIDinValor de contexto opaco que el servidor recupera luego en cada recepción en este puerto — típicamente un puntero a una estructura por cliente.
ConnectionRequestPPORT_MESSAGEinEl PORT_MESSAGE LPC_CONNECTION_REQUEST original recibido vía NtAlpcSendWaitReceivePort que disparó esta aceptación.
ConnectionMessageAttributesPALPC_MESSAGE_ATTRIBUTESinAtributos de mensaje (handle, contexto de seguridad, vista) devueltos al cliente como payload de la respuesta de aceptación.
AcceptConnectionBOOLEANinTRUE para aceptar la conexión (devuelve un handle de puerto); FALSE para rechazarla (el cliente recibe STATUS_PORT_CONNECTION_REFUSED).

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x73win10-1507
Win10 16070x73win10-1607
Win10 17030x74win10-1703
Win10 17090x74win10-1709
Win10 18030x75win10-1803
Win10 18090x75win10-1809
Win10 19030x75win10-1903
Win10 19090x75win10-1909
Win10 20040x77win10-2004
Win10 20H20x77win10-20h2
Win10 21H10x77win10-21h1
Win10 21H20x77win10-21h2
Win10 22H20x77win10-22h2
Win11 21H20x77win11-21h2
Win11 22H20x77win11-22h2
Win11 23H20x77win11-23h2
Win11 24H20x79win11-24h2
Server 20160x73winserver-2016
Server 20190x75winserver-2019
Server 20220x77winserver-2022
Server 20250x79winserver-2025

Módulo del kernel

ntoskrnl.exeNtAlpcAcceptConnectPort

APIs relacionadas

NtAlpcCreatePortNtAlpcConnectPortNtAlpcSendWaitReceivePortNtAlpcDisconnectPortRpcServerListenRpcServerUseProtseqEpW

Stub del syscall

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

`NtAlpcAcceptConnectPort` es la contraparte exacta de `NtAlpcConnectPort`: el lado servidor del handshake de tres pasos de ALPC. El patrón canónico es `NtAlpcCreatePort` (bind/listen) → `NtAlpcSendWaitReceivePort` (recv `LPC_CONNECTION_REQUEST`) → `NtAlpcAcceptConnectPort` (accept o reject). Un accept exitoso devuelve un puerto de comunicación por cliente; el tráfico posterior pasa por ese handle, no por el puerto de conexión. Todo servicio RPC de Windows que expone un endpoint `ncalrpc` ejecuta este bucle, casi siempre vía el wrapper `RPCRT4!RpcServerListen` en lugar de invocar la rutina Nt directamente. No hay superficie Win32 pública.

Uso común por malware

Por sí solo, llamar a `NtAlpcAcceptConnectPort` desde malware es inusual — implica que el malware *hospeda* él mismo un endpoint servidor ALPC para coordinar otros componentes (loader ↔ DLL inyectada ↔ servicio de persistencia). Algunos implantes modulares de larga duración hacen exactamente esto porque ALPC es invisible a la telemetría de red de Sysmon y sobrevive incluso sin red de salida. Más comúnmente, el syscall es interesante en sentido *inverso*: las cadenas de exploit ALPC LPE (CVE-2018-8440 Task Scheduler, varios bugs de Print Spooler) terminan engañando al bucle de accept de un servidor *privilegiado* con un `PORT_MESSAGE` LPC_CONNECTION_REQUEST forjado — el bug está en quien llama a `NtAlpcAcceptConnectPort`, no en el syscall.

Oportunidades de detección

Detección asimétrica: dominado por todos los servicios legítimos del equipo. La señal reside en *qué* proceso lo invoca. Ejecutar `handle.exe -a -p <pid>` (o equivalente) sobre un binario no-servicio / no-Microsoft y encontrar un endpoint servidor `ALPC Port \RPC Control\…` es anómalo. El ETW `Microsoft-Windows-Kernel-ALPC` expone eventos accept por puerto pero rara vez está activo a escala. La pestaña ALPC de SystemInformer enumera puertos servidor por proceso — herramienta más útil en post-incidente.

Ejemplos de syscalls directos

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtAlpcAcceptConnectPort (SSN 0x79 on Win11 24H2)
NtAlpcAcceptConnectPort PROC
    mov  r10, rcx          ; PortHandle
    mov  eax, 79h          ; SSN — drifts per build
    syscall
    ret
NtAlpcAcceptConnectPort ENDP

cMinimal ALPC server accept loop

// Skeleton of the canonical create → recv-connreq → accept loop.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtAlpcAcceptConnectPort)(
    PHANDLE, HANDLE, ULONG, POBJECT_ATTRIBUTES, PVOID,
    PVOID, PPORT_MESSAGE, PVOID, BOOLEAN);

static pNtAlpcAcceptConnectPort g_accept;

NTSTATUS HandleConnReq(HANDLE hConnectionPort,
                       PPORT_MESSAGE pConnReq) {
    HANDLE hClient = NULL;
    // Per-client context — survives across receives.
    PVOID ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 64);
    NTSTATUS st = g_accept(&hClient, hConnectionPort, 0,
                           NULL, NULL, ctx, pConnReq, NULL,
                           TRUE /* accept */);
    // hClient is now the per-client comm port — pump it with
    // NtAlpcSendWaitReceivePort in a worker thread.
    return st;
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20