> Windows Syscalls
ntoskrnl.exeT1571T1090T1559

NtCreateNamedPipeFile

Erzeugt das Server-Ende einer Named-Pipe im Geräte-Namespace \Device\NamedPipe.

Prototyp

NTSTATUS NtCreateNamedPipeFile(
  PHANDLE            FileHandle,
  ULONG              DesiredAccess,
  POBJECT_ATTRIBUTES ObjectAttributes,
  PIO_STATUS_BLOCK   IoStatusBlock,
  ULONG              ShareAccess,
  ULONG              CreateDisposition,
  ULONG              CreateOptions,
  ULONG              NamedPipeType,
  ULONG              ReadMode,
  ULONG              CompletionMode,
  ULONG              MaximumInstances,
  ULONG              InboundQuota,
  ULONG              OutboundQuota,
  PLARGE_INTEGER     DefaultTimeout
);

Argumente

NameTypeDirDescription
FileHandlePHANDLEoutEmpfängt das Handle auf das neu erzeugte Server-Ende der Named-Pipe.
DesiredAccessULONGinZugriffsmaske, typischerweise GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE.
ObjectAttributesPOBJECT_ATTRIBUTESinBenennt die Pipe unter \Device\NamedPipe (z. B. \??\pipe\msagent_xx) und liefert den SECURITY_DESCRIPTOR.
IoStatusBlockPIO_STATUS_BLOCKoutEmpfängt den finalen NTSTATUS und Informationscode (FILE_CREATED / FILE_OPENED).
ShareAccessULONGinFILE_SHARE_*-Flags steuern die Semantik konkurrierender Öffnungen der Named-Pipe.
CreateDispositionULONGinFILE_CREATE, FILE_OPEN oder FILE_OPEN_IF; Verhalten falls der Name existiert.
CreateOptionsULONGinFILE_SYNCHRONOUS_IO_NONALERT etc. — gleicher Flag-Satz wie bei NtCreateFile.
NamedPipeTypeULONGinFILE_PIPE_BYTE_STREAM_TYPE oder FILE_PIPE_MESSAGE_TYPE — Übertragungsformat.
ReadModeULONGinFILE_PIPE_BYTE_STREAM_MODE oder FILE_PIPE_MESSAGE_MODE für Reads.
CompletionModeULONGinFILE_PIPE_QUEUE_OPERATION (blockierend) oder FILE_PIPE_COMPLETE_OPERATION (sofortige Rückkehr).
MaximumInstancesULONGinMaximale gleichzeitige Server-Instanzen dieses Pipe-Namens; PIPE_UNLIMITED_INSTANCES = 0xFF.
InboundQuotaULONGinPuffergröße für Client→Server-Daten in Byte.
OutboundQuotaULONGinPuffergröße für Server→Client-Daten in Byte.
DefaultTimeoutPLARGE_INTEGERinStandard-Timeout für blockierende Operationen (100-ns-Einheiten, negativ = relativ). NULL = 50 ms.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070xA8win10-1507
Win10 16070xAAwin10-1607
Win10 17030xADwin10-1703
Win10 17090xAEwin10-1709
Win10 18030xAFwin10-1803
Win10 18090xAFwin10-1809
Win10 19030xB0win10-1903
Win10 19090xB0win10-1909
Win10 20040xB4win10-2004
Win10 20H20xB4win10-20h2
Win10 21H10xB4win10-21h1
Win10 21H20xB5win10-21h2
Win10 22H20xB5win10-22h2
Win11 21H20xB8win11-21h2
Win11 22H20xB9win11-22h2
Win11 23H20xB9win11-23h2
Win11 24H20xBBwin11-24h2
Server 20160xAAwinserver-2016
Server 20190xAFwinserver-2019
Server 20220xB7winserver-2022
Server 20250xBBwinserver-2025

Kernel-Modul

ntoskrnl.exeNtCreateNamedPipeFile

Verwandte APIs

CreateNamedPipeWConnectNamedPipeDisconnectNamedPipeWaitNamedPipeWCallNamedPipeWNtFsControlFileNtCreateFile

Syscall-Stub

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

`NtCreateNamedPipeFile` ist mit 14 Parametern die größte einzelne Native API und Grundlage von `CreateNamedPipeW`. Pipe-Namen liegen unter `\Device\NamedPipe\`; die User-Mode-Form ist `\\.\pipe\<Name>` oder remote `\\<Host>\pipe\<Name>`. Remote-Öffnungen laufen über SMB und unterliegen Firewall/NetBIOS — genau deshalb hört Cobalt Strikes SMB-Beacon auf einer Named-Pipe statt einem TCP-Socket. Der SSN ändert sich alle zwei bis drei Feature-Updates (`0xA8` auf Win10 1507 → `0xBB` auf Win11 24H2); portabler Shellcode löst dynamisch auf.

Häufige Malware-Nutzung

Named Pipes sind der *de-facto* IPC-Kanal moderner Post-Exploitation: - **Cobalt-Strike-SMB-Beacon**: Peer-Beacons verbinden sich über eine Server-Named-Pipe (default `\\.\pipe\msagent_xx`, `\\.\pipe\status_xx` etc.). C2-Verkehr läuft tunneled in der Pipe, ohne den Netzwerkadapter des Egress-Hosts zu berühren. - **Sliver Named-Pipe-Transport**: gleiche Idee — Implant↔Implant-Kommunikation für Lateral Movement, ohne neue TCP-Ports zu öffnen. - **PsExec-artige Dienste** legen `\pipe\psexesvc` für den Befehlsrückkanal an. - Viele Ransomware-Familien (Conti, BlackCat) koordinieren ihre Verschlüsselungs-Worker über eine Pipe, um Fortschrittsmeldungen zu zentralisieren. Angreifer wählen Namen, die legitime Microsoft-Dienste nachahmen (`\pipe\lsass`, `\pipe\spoolss`, `\pipe\mojo.*`), um im IPC-/Browser-Rauschen unterzugehen.

Erkennungs­möglichkeiten

Sysmon **Event ID 17 (PipeEvent: Pipe Created)** und **18 (PipeEvent: Pipe Connected)** sind die ergiebigsten Detektionen für diesen Syscall. Ungewöhnliche Pipe-Namen — zufällige Suffixe, GUID-artige Namen, `msagent_*` auf einem nicht von Cobalt anvisierten Host, oder `\pipe\`-Öffnungen aus unerwarteten Prozessen (notepad.exe, wmiprvse.exe) — sind starke Indikatoren für SMB-Beacons oder Peer-to-Peer-Implants. Der ETW-Provider `Microsoft-Windows-Kernel-File` deckt Create/Open der Pipe-File-Objekte ab. EDRs alarmieren auch auf das Muster `NtCreateNamedPipeFile` gefolgt von `NtFsControlFile(FSCTL_PIPE_LISTEN)` aus einem Nicht-Dienst-Prozess.

Direkte Syscall-Beispiele

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtCreateNamedPipeFile (SSN 0xBB on Win11 24H2)
NtCreateNamedPipeFile PROC
    mov  r10, rcx          ; FileHandle
    mov  eax, 0BBh         ; SSN — version-sensitive, resolve dynamically
    syscall
    ret
NtCreateNamedPipeFile ENDP

cCobalt-Strike-style SMB beacon listener

// Create \\.\pipe\msagent_42 as a message-mode server pipe.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtCreateNamedPipeFile)(
    PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
    ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, ULONG, PLARGE_INTEGER);

HANDLE OpenBeaconPipe(void) {
    UNICODE_STRING name;
    RtlInitUnicodeString(&name, L"\\??\\pipe\\msagent_42");
    OBJECT_ATTRIBUTES oa;
    InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
    IO_STATUS_BLOCK iosb = {0};
    LARGE_INTEGER timeout; timeout.QuadPart = -50LL * 10000LL; // 50 ms
    HANDLE hPipe = NULL;

    pNtCreateNamedPipeFile fn = (pNtCreateNamedPipeFile)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtCreateNamedPipeFile");
    fn(&hPipe,
       GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
       &oa, &iosb,
       FILE_SHARE_READ | FILE_SHARE_WRITE,
       FILE_CREATE,
       FILE_SYNCHRONOUS_IO_NONALERT,
       1 /* FILE_PIPE_MESSAGE_TYPE   */,
       1 /* FILE_PIPE_MESSAGE_MODE   */,
       0 /* FILE_PIPE_QUEUE_OP       */,
       0xFF /* PIPE_UNLIMITED_INSTANCES */,
       0x1000, 0x1000,
       &timeout);
    return hPipe;
}

rustwindows-sys wrapper

// Cargo: windows-sys = "0.59", features = ["Wdk_Storage_FileSystem", "Win32_System_IO"]
use std::ptr::null_mut;
use windows_sys::Wdk::Storage::FileSystem::NtCreateNamedPipeFile;
use windows_sys::Win32::Storage::FileSystem::*;
use windows_sys::Win32::System::IO::IO_STATUS_BLOCK;
use windows_sys::Win32::System::WindowsProgramming::*;
use windows_sys::Wdk::Foundation::OBJECT_ATTRIBUTES;

pub fn create_message_pipe(_name: &str) -> isize {
    let mut handle: isize = 0;
    let mut iosb: IO_STATUS_BLOCK = unsafe { std::mem::zeroed() };
    let timeout: i64 = -50 * 10_000; // 50 ms relative
    // ObjectAttributes / UNICODE_STRING construction elided — see ntdll helpers.
    let oa: OBJECT_ATTRIBUTES = unsafe { std::mem::zeroed() };
    unsafe {
        NtCreateNamedPipeFile(
            &mut handle,
            (GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE) as u32,
            &oa, &mut iosb,
            (FILE_SHARE_READ | FILE_SHARE_WRITE) as u32,
            FILE_CREATE,
            FILE_SYNCHRONOUS_IO_NONALERT,
            1, 1, 0, 0xFF, 0x1000, 0x1000,
            &timeout as *const _ as *mut _,
        );
    }
    handle
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20