> Windows Syscalls
ntoskrnl.exeT1559T1106

NtAlpcAcceptConnectPort

Server-seitige ALPC-Accept-Routine — schließt eine ausstehende Client-Verbindung ab und liefert einen Per-Client-Kommunikationsport.

Prototyp

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

Argumente

NameTypeDirDescription
PortHandlePHANDLEoutEmpfängt ein Handle auf den neuen Per-Client-Kommunikationsport (oder NULL, wenn AcceptConnection FALSE ist).
ConnectionPortHandleHANDLEinHandle auf den lauschenden Server-Connection-Port, zuvor mit NtAlpcCreatePort erstellt.
FlagsULONGinALPC-Verbindungsflags (ALPC_MSGFLG_SYNC_REQUEST, ALPC_PORFLG_*); meist 0.
ObjectAttributesPOBJECT_ATTRIBUTESinOptionale Objektattribute für den neuen Kommunikationsport; meist NULL.
PortAttributesPALPC_PORT_ATTRIBUTESinServer-seitige Port-Attribute (Max-Message-Größe, View-Größe, Security-QoS) für diesen Client-Port.
PortContextPVOIDinOpaker Kontextwert, den der Server bei jedem Empfang auf diesem Port wieder erhält — meist ein Zeiger auf eine Per-Client-Struktur.
ConnectionRequestPPORT_MESSAGEinDie ursprüngliche LPC_CONNECTION_REQUEST-PORT_MESSAGE, empfangen über NtAlpcSendWaitReceivePort, die dieses Accept ausgelöst hat.
ConnectionMessageAttributesPALPC_MESSAGE_ATTRIBUTESinMessage-Attribute (Handle, Security-Context, View), die als Accept-Reply-Payload an den Client zurückgehen.
AcceptConnectionBOOLEANinTRUE, um die Verbindung anzunehmen (liefert ein Port-Handle); FALSE, um sie abzulehnen (Client erhält STATUS_PORT_CONNECTION_REFUSED).

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
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

Kernel-Modul

ntoskrnl.exeNtAlpcAcceptConnectPort

Verwandte APIs

NtAlpcCreatePortNtAlpcConnectPortNtAlpcSendWaitReceivePortNtAlpcDisconnectPortRpcServerListenRpcServerUseProtseqEpW

Syscall-Stub

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

Undokumentierte Hinweise

`NtAlpcAcceptConnectPort` ist das exakte Gegenstück zu `NtAlpcConnectPort`: die Server-Seite des ALPC-Drei-Wege-Handshakes. Das kanonische Muster: `NtAlpcCreatePort` (bind/listen) → `NtAlpcSendWaitReceivePort` (Empfang `LPC_CONNECTION_REQUEST`) → `NtAlpcAcceptConnectPort` (accept oder reject). Ein erfolgreiches Accept liefert einen Per-Client-Kommunikationsport; nachfolgender Nachrichtenverkehr fließt über dieses Handle, nicht über den Connection-Port. Jeder Windows-RPC-Dienst, der einen `ncalrpc`-Endpoint exponiert, fährt diese Schleife, fast immer via Wrapper `RPCRT4!RpcServerListen` und nicht direkt über die Nt-Routine. Es gibt keine öffentliche Win32-Oberfläche.

Häufige Malware-Nutzung

Für sich allein ist ein Aufruf von `NtAlpcAcceptConnectPort` aus Malware ungewöhnlich — er bedeutet, dass die Malware *selbst* einen ALPC-Server-Endpoint hostet, um andere Komponenten zu koordinieren (Loader ↔ injizierte DLL ↔ Persistenz-Dienst). Manche langlebigen modularen Implants tun genau das, weil ALPC für Sysmon-Netz-Telemetrie unsichtbar ist und auch ohne ausgehendes Netz funktioniert. Häufiger ist der Syscall in der *Gegenrichtung* interessant: ALPC-LPE-Exploit-Ketten (CVE-2018-8440 Task Scheduler, diverse Print-Spooler-Bugs) bringen die Accept-Schleife eines *privilegierten* Servers dazu, eine gefälschte `LPC_CONNECTION_REQUEST`-`PORT_MESSAGE` falsch zu behandeln — der Bug steckt im Aufrufer von `NtAlpcAcceptConnectPort`, nicht im Syscall.

Erkennungs­möglichkeiten

Asymmetrische Erkennung: dominiert von jedem legitimen Dienst auf der Maschine. Das Signal liegt darin, *welcher* Prozess aufruft. `handle.exe -a -p <pid>` (oder Äquivalent) auf einem Nicht-Service-/Nicht-Microsoft-Binary mit einem `ALPC Port \RPC Control\…`-Server-Endpoint ist anomal. Der ETW-Provider `Microsoft-Windows-Kernel-ALPC` liefert per-Port-Accept-Events, ist aber selten flächendeckend aktiv. SystemInformers ALPC-Tab enumeriert Server-Ports pro Prozess und ist das nützlichste Post-Incident-Werkzeug.

Direkte Syscall-Beispiele

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

MITRE ATT&CK-Mappings

Last verified: 2026-05-20