Your Service's Named Pipe Is a Backdoor to LocalSystem
A named pipe is how two processes on the same Windows machine talk to each other — fast, built into the OS, and the default choice when a privileged service needs to chat with its desktop client. And because both ends live on the same box, most of the code written against it treats the channel as internal, as trusted. That one assumption is what quietly turns a local pipe into a backdoor to LocalSystem. Red teams have known about it for years. The token-impersonation trick, where a low-privilege connection lets a pipe server act under a client's security context, is the exact same technique meterpreter's GetSystem and PowerUp reach for when they're trying to escalate. A successful pipe connection only proves the client was allowed to open the pipe. It does not prove the client is the application you intended, that the connecting user is authorized, or that the command is safe. Local is not a security boundary. The pipe is one.
This week's ThreatLocker piece on BleepingComputer walks through the fix, and it's the same discipline you'd apply to any network-facing API, just on localhost, where almost nobody applies it. Give the pipe an explicit security descriptor instead of the default access-control list, which is often wide enough for Everyone. Authorize each command on its own, because being able to connect is not the same as being allowed to execute. Frame and size-check every message, because a named pipe is just a byte stream until you say otherwise, and a declared payload length is not something to trust before you allocate memory. Treat every message as untrusted input even when the client authenticated. And a detail most designs miss: a pipe name is not a secret, and a local pipe is not automatically local-only — Windows named pipes will accept remote connections when the Windows Server service is running, so a genuinely local IPC channel should set PIPE_REJECT_REMOTE_CLIENTS or deny NT AUTHORITY\NETWORK. The kicker is that even a pipe that rejects every privileged command can still be denied service by a process that just connects, holds the connection open, and starves the legitimate client. Availability is part of the threat model, not an afterthought.
The line that stuck with me is the threat model itself: treat every named-pipe connection as hostile until the client's identity, its permissions, the requested operation, and the message contents have all been verified. That is the same model you'd apply to anything on the wire, and the fact that same-box IPC usually gets none of it is exactly the kind of quiet, systemic gap that makes a machine safe in theory and exploitable in practice. It's also the kind of surface you can enumerate in one line — Get-Ch

Sources
Comments
Post a Comment