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
| Name | Type | Dir | Description |
|---|---|---|---|
| PortHandle | PHANDLE | out | Recibe un handle al nuevo puerto de comunicación por cliente (o NULL si AcceptConnection es FALSE). |
| ConnectionPortHandle | HANDLE | in | Handle al puerto de conexión del servidor en escucha, creado previamente con NtAlpcCreatePort. |
| Flags | ULONG | in | Banderas de conexión ALPC (ALPC_MSGFLG_SYNC_REQUEST, ALPC_PORFLG_*); normalmente 0. |
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Atributos de objeto opcionales para el nuevo puerto de comunicación; normalmente NULL. |
| PortAttributes | PALPC_PORT_ATTRIBUTES | in | Atributos de puerto del lado servidor (tamaño máx de mensaje, tamaño de vista, QoS de seguridad) que rigen este puerto cliente. |
| PortContext | PVOID | in | Valor de contexto opaco que el servidor recupera luego en cada recepción en este puerto — típicamente un puntero a una estructura por cliente. |
| ConnectionRequest | PPORT_MESSAGE | in | El PORT_MESSAGE LPC_CONNECTION_REQUEST original recibido vía NtAlpcSendWaitReceivePort que disparó esta aceptación. |
| ConnectionMessageAttributes | PALPC_MESSAGE_ATTRIBUTES | in | Atributos de mensaje (handle, contexto de seguridad, vista) devueltos al cliente como payload de la respuesta de aceptación. |
| AcceptConnection | BOOLEAN | in | TRUE 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 Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x73 | win10-1507 |
| Win10 1607 | 0x73 | win10-1607 |
| Win10 1703 | 0x74 | win10-1703 |
| Win10 1709 | 0x74 | win10-1709 |
| Win10 1803 | 0x75 | win10-1803 |
| Win10 1809 | 0x75 | win10-1809 |
| Win10 1903 | 0x75 | win10-1903 |
| Win10 1909 | 0x75 | win10-1909 |
| Win10 2004 | 0x77 | win10-2004 |
| Win10 20H2 | 0x77 | win10-20h2 |
| Win10 21H1 | 0x77 | win10-21h1 |
| Win10 21H2 | 0x77 | win10-21h2 |
| Win10 22H2 | 0x77 | win10-22h2 |
| Win11 21H2 | 0x77 | win11-21h2 |
| Win11 22H2 | 0x77 | win11-22h2 |
| Win11 23H2 | 0x77 | win11-23h2 |
| Win11 24H2 | 0x79 | win11-24h2 |
| Server 2016 | 0x73 | winserver-2016 |
| Server 2019 | 0x75 | winserver-2019 |
| Server 2022 | 0x77 | winserver-2022 |
| Server 2025 | 0x79 | winserver-2025 |
Módulo del kernel
APIs relacionadas
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 ENDPcMinimal 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