Skip to content

Commit 8c3c9bc

Browse files
authored
Merge pull request #2154 from HackTricks-wiki/update_Hooking_Windows_Named_Pipes_20260421_132327
Hooking Windows Named Pipes
2 parents 601613a + 65a2be2 commit 8c3c9bc

1 file changed

Lines changed: 42 additions & 22 deletions

File tree

src/windows-hardening/windows-local-privilege-escalation/named-pipe-client-impersonation.md

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -122,24 +122,41 @@ from-high-integrity-to-system-with-name-pipes.md
122122
service-triggers.md
123123
{{#endref}}
124124

125-
## Named Pipe IPC Abuse & MITM (DLL Injection, API Hooking, PID Validation Bypass)
126-
127-
Named-pipe hardened services can still be hijacked by instrumenting the trusted client. Tools like [pipetap](https://sensepost.com/blog/2025/pipetap-a-windows-named-pipe-proxy-tool/) drop a helper DLL into the client, proxy its traffic, and let you tamper with privileged IPC before the SYSTEM service consumes it.
128-
129-
### Inline API hooking inside trusted processes
130-
- Inject the helper DLL (OpenProcess → CreateRemoteThread → LoadLibrary) into any client.
131-
- The DLL Detours `ReadFile`, `WriteFile`, etc., but only when `GetFileType` reports `FILE_TYPE_PIPE`, copies each buffer/metadata to a control pipe, lets you edit/drop/replay it, then resumes the original API.
132-
- Turns the legitimate client into a Burp-style proxy: pause UTF-8/UTF-16/raw payloads, trigger error paths, replay sequences, or export JSON traces.
133-
134-
### Remote client mode to defeat PID-based validation
135-
- Inject into an allow-listed client, then in the GUI choose the pipe plus that PID.
136-
- The DLL issues `CreateFile`/`ConnectNamedPipe` inside the trusted process and relays the I/O back to you, so the server still observes the legitimate PID/image.
137-
- Bypasses filters that rely on `GetNamedPipeClientProcessId` or signed-image checks.
138-
139-
### Fast enumeration and fuzzing
140-
- `pipelist` enumerates `\\.\pipe\*`, shows ACLs/SIDs, and forwards entries to other modules for immediate probing.
141-
- The pipe client/message composer connects to any name and builds UTF-8/UTF-16/raw-hex payloads; import captured blobs, mutate fields, and resend to hunt deserializers or unauthenticated command verbs.
142-
- The helper DLL can host a loopback TCP listener so tooling/fuzzers can drive the pipe remotely via the Python SDK.
125+
## Named Pipe IPC Abuse & MITM (ACLs, First-Instance Races, Client Hooking)
126+
127+
When a privileged service and a low-privileged process communicate over `\\.\pipe\...`, treat the pipe like any other untrusted IPC boundary. Beyond classic server-side impersonation, weak pipe ACLs, unsafe creation flags, and client-side trust decisions can all become local privilege escalation primitives.
128+
129+
### Enumerate candidate pipes first
130+
- List pipes quickly from PowerShell: `Get-ChildItem \\.\pipe\`
131+
- Sysinternals `pipelist64.exe` is useful to spot instance counts and single-instance pipes.
132+
- Prioritize names used by services running as `SYSTEM`, especially helpers, updaters, launchers, and UI brokers.
133+
134+
### MITM via permissive DACLs and extra pipe instances
135+
- Any process that can talk to a privileged server can already fuzz its protocol and hunt privileged verbs.
136+
- The more interesting case is when the DACL grants `FILE_GENERIC_WRITE`/`GENERIC_WRITE` on the pipe object. On named pipes this implicitly includes `FILE_CREATE_PIPE_INSTANCE` (`FILE_APPEND_DATA` shares the same bit), so an attacker can create another server instance with the same name.
137+
- Because instances are matched in FIFO order, attacker-created and legitimate instances can be interleaved: create a rogue instance with `CreateNamedPipe`, then open the same pipe name with `CreateFile`, and wait for a real client to land on the rogue server instance.
138+
- Result: observe, modify, relay, or desynchronize privileged IPC without needing to own the original server process.
139+
140+
### First-instance race on pipe security descriptors
141+
- `lpSecurityAttributes` only defines the DACL when the first instance of a pipe name is created.
142+
- If a privileged service starts late and does not use `FILE_FLAG_FIRST_PIPE_INSTANCE`, an attacker can pre-create the pipe name with a permissive DACL, then let the service create later instances under the attacker-chosen security context.
143+
- This turns service startup into a race condition: win the first instance, then connect or MITM later clients using the weakened ACL.
144+
- Mitigation for defenders, and a key review point for attackers: check whether `CreateNamedPipe(..., dwOpenMode, ...)` includes `FILE_FLAG_FIRST_PIPE_INSTANCE`. If not, test pre-creation before the service starts.
145+
146+
### PID/signature checks are hardening, not a boundary
147+
- Some products try to restrict access by checking `GetNamedPipeClientProcessId`, process image path, or Authenticode signer of the connecting client.
148+
- This only helps until you inject into the legitimate client: once inside the trusted process, you inherit the exact PID/image/signature context the server expects.
149+
- For split desktop apps, instrumenting the low-privileged UI/helper process is often easier than attacking the `SYSTEM` service directly.
150+
151+
### Hook the client according to its I/O model
152+
- Synchronous I/O: intercept `NtWriteFile` before the syscall consumes the buffer, and inspect/patch `NtReadFile` after it returns.
153+
- Overlapped I/O: store the `OVERLAPPED`/`IoStatusBlock` seen in `NtReadFile`, then inspect the buffer after `GetOverlappedResult` or the relevant wait completes.
154+
- Completion ports: `GetQueuedCompletionStatus` reaches `NtRemoveIoCompletion`; the returned `ApcContext` links back to the `OVERLAPPED` used by the original read, which is the right pivot to find the now-populated buffer.
155+
- Completion routines (`ReadFileEx`): the completion callback is delivered as an APC. If you want to tamper with returned data or inject synthetic replies, hook the real completion routine and, for custom injection, use a one-argument `QueueUserAPC` dispatcher that reconstructs the routine's 3 expected arguments.
156+
157+
### Tooling notes
158+
- [pipetap](https://sensepost.com/blog/2025/pipetap-a-windows-named-pipe-proxy-tool/) proxies named-pipe traffic through an injected helper DLL and exposes a Burp-like workflow for editing/replay.
159+
- [thats_no_pipe](https://github.com/synacktiv/thats_no_pipe) takes a Frida-based approach and focuses on hooking `NtReadFile`/`NtWriteFile` plus the async/completion pivots above, then forwarding traffic to a WebSocket-backed editing workflow.
143160

144161
```bash
145162
pip install pipetap
@@ -151,12 +168,10 @@ client = pipetap.Client(("127.0.0.1", 47001))
151168
client.write(b"OP\x00\x01...")
152169
```
153170

154-
Combine the TCP bridge with VM snapshot restores to crash-test fragile IPC parsers.
155-
156171
### Operational considerations
157172
- Named pipes are low-latency; long pauses while editing buffers can deadlock brittle services.
158-
- Overlapped/completion-port I/O coverage is partial, so expect edge cases.
159-
- Injection is noisy and unsigned, so treat it as a lab/exploit-dev helper rather than a stealth implant.
173+
- Overlapped/completion-port/APC-driven clients need different hooks than simple `ReadFile`/`WriteFile` detours.
174+
- Injection into the trusted client is noisy and generally best kept for exploit development, protocol reversing, or local lab fuzzing.
160175

161176
## Troubleshooting and gotchas
162177
- You must read at least one message from the pipe before calling ImpersonateNamedPipeClient; otherwise you’ll get ERROR_CANNOT_IMPERSONATE (1368).
@@ -167,6 +182,11 @@ Combine the TCP bridge with VM snapshot restores to crash-test fragile IPC parse
167182
## References
168183
- [Windows: ImpersonateNamedPipeClient documentation](https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient)
169184
- [ired.team: Windows named pipes privilege escalation](https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation)
185+
- [Microsoft: Named Pipe Security and Access Rights](https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights)
186+
- [Microsoft: CreateNamedPipe function](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea)
187+
- [Microsoft: Named Pipe Server Using Completion Routines](https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-server-using-completion-routines)
170188
- [pipetap – a Windows named pipe proxy tool](https://sensepost.com/blog/2025/pipetap-a-windows-named-pipe-proxy-tool/)
189+
- [Synacktiv: Hooking Windows Named Pipes](https://www.synacktiv.com/en/publications/hooking-windows-named-pipes.html)
190+
- [Synacktiv: thats_no_pipe](https://github.com/synacktiv/thats_no_pipe)
171191

172192
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)