4 ms·
Good article, but I wish the author would've addressed securing these named pipes. Consider that if a user-mode application can send messages to a privileged p
by bloblaw 5y ago
Good article, but I wish the author would've addressed securing these named pipes.
Consider that if a user-mode application can send messages to a privileged process (like a Windows service).
What prevents any user-mode application from doing that? And if your Windows service is running as "NT_AUTHORITY/SYSTEM" and even executes privileged commands, well you might find you've got a simple privilege escalation vuln.
Remember, secure your named pipes...especially when the named pipe server runs as SYSTEM.
- https://stackoverflow.com/a/59983266 https://stackoverflow.com/a/59983266
- https://versprite.com/blog/security-research/vulnerable-named-pipe-application/ https://versprite.com/blog/security-research/vulnerable-name...
- merb 5y agoI think the package he used, also has some kind of pipe authorization access control.
- entrep 5y agoThat is correct.
- entrep 5y agoThanks! That’s very valid feedback. Could be my next write up.
- bloblaw 5y agoYou're welcome. An alternative I've used to named pipes among processes of different privilege levels is to build the service to listen for custom commands sent to it. These are just integers, and the service maps those to pre-defined commands. Then the only thing the user-mode application can send are just flags (integers) that the service has already pre-determined what it will do in response. Here's an article: https://www.codeproject.com/Articles/24434/How-to-Write-Windows-Service-and-Control-It-By-App https://www.codeproject.com/Articles/24434/How-to-Write-Wind... And here's a succinct example: https://stackoverflow.com/a/5805700 https://stackoverflow.com/a/5805700
- entrep 5y agoInteresting. Didn't know about it.
- ww520 5y agoGood to address the security aspects of named pipe. However none of those describes how to secure the server. The server needs to call ImpersonateNamedPipeClient() on the incoming client connection to assume the client’s security token, that would lower the server’s privilege to the level of the client. That’s it! A guest level client can connect to the server. The server’s privilege becomes guest, and cannot access any resources that guest has no permission to access. [1] https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient https://docs.microsoft.com/en-us/windows/win32/api/namedpipe...
- munchler 5y agoFWIW, the project in the article is explicitly intended to allow privilege elevation: "You have an application which runs in user context, without any administrative rights, and you need to perform some tasks which requires higher privileges."
- deleted 5y ago[deleted]
- ww520 5y agoThe server can do whatever it needs to do in its higher privilege. Just when it interacts with the client connection, it lowers its privilege to the client's level. It gets the incoming data, sanitizes it, and reverts back to higher privilege to do the work. This minimizes the attack surface to the area dealing with client interaction, not the whole server. The server might link in a 3rd party XML library to sanitizes the incoming data and you don't know what the library can do. Running that in the client privilege level ensures that whatever it does only under the client's privilege.
- monocasa 5y agoThat thread still has higher privilege write access to it's process's state, including the stacks of other threads that haven't impersonated that client. ImpersonateNamedPipeClient is a very leaky security barrier, and far from the only thing you need to know about when it comes to named pipe security.
- program9 5y agoI've worked on apps like this, and I didn't know or care which user was going to use the features requiring elevation. So I couldn't manage permissions per user. My approach to security was to simply limit the input (method parameters usually) from the unprivileged process. For example, not letting the client send arbitrary commands to execute, use filesystem path whitelists, only elevate when required, etc. If the privileged code uses a resource, and that resource can be changed/replaced by an unprivileged user, then the privileged code can be manipulated. Like a Registry key in HKCU for example, or a file in a user's AppData folder. Using enums as method parameters for privileged code helped me avoid some obvious vulns I might've otherwise created. I've definitely done it the wrong way before. It can be tough.
- bloblaw 5y agoThis is generally how I've approached this problem as well. I like using the `ServiceController.ExecuteCommand` method and just send some integer value from the client -> server...and the server maps the integer value to a pre-determined command. https://docs.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicecontroller.executecommand?view=dotnet-plat-ext-6.0 https://docs.microsoft.com/en-us/dotnet/api/system.servicepr... You've definitely outlined the risk clearly of allowing a client to specify anything arbitrarily. I once wrote a sudo implementation for Windows Vista / Windows 7 and first attempt used named pipes communicating to a windows service that did some token manipulation to execute things as the user (but with elevated token attached as well). There be (security) dragons. I like using named pipes and they are a great IPC mechanism for communicating amongst processes of the same privilege level. I would not use them for message passing between processes of different privilege levels.