Infeccion de ejecutables portables bajo Win32
---------------------------------------------

  INDICE
  ------

        1 -. Introduccion.
        2 -. Metodologia del virus.
        3 -. Estructura de un PE.
        4 -. APIS en Win32.
        5 -. Tipos de infecciones en un PE.
        6 -. Tecnicas empleadas.
             6.1 -. El problema del Kernel 32.
             6.2 -. Solucion forwarder-chain
             6.3 -. File Mapping.
             6.4 -. Semi-Stealth.
             6.5 -. Anti-debug y SEH.
             6.6 -. Anti-heuristica.

        7 -. Ultimas palabras ...

        * Apendice A  (Implementacion)
        * Apendice B  (iZan PGP Public Key)
        

  1 -. Introduccion
  -----------------

        El presente documento ha sido dividido en secciones debido a
a la complejidad de la materia y a la disparidad de temas tratados.
Cada seccion tratara un tema basico en la infeccion como puede ser
la "Estructura de un PE", "APIs en Win32" o "Tipos de infeccion"
entre otras. Ademas, esta estructuracion en secciones permitira la 
inclusion de nuevas secciones que trataran las nuevas tecnicas que 
vayan apareciendo asi como la actualizacion de las ya publicadas.
        
        Este documento constituye un texto basico en la infeccion
de PE. Se trataran a fondo temas como la estructura de un PE y APIs en
Win32 por constituir los puntos fundamentales sobre los que se apoyan
estos virus de nueva hornada. De esta manera se dara al lector los
conocimientos necesarios para entender cualquier codigo virico actual.

        Los demas puntos seran tratados de una manera mas generica pero
lo suficientemente clara como para que aquellas personas que deseen
entrar en el tema mas profundamente puedan hacerlo tan solo con ojear
el codigo de algun virus que trate ese tema (ver Apendice A).

        Se ha decidido no incluir el codigo fuente de ningun virus
debido a que el presente texto no es una guia de infeccion o de
desinfeccion explicitamente aunque el uso que se pueda hacer de el
venga dado exclusivamente por el propio lector.
                    
        Por ultimo cabe decir que un virus es una porcion de codigo
complejo que hace un uso exhaustivo de los recursos de la maquina que lo
alberga de una manera increiblemente eficiente y portable.

                                                             
  2 -. Metodologia del virus
  --------------------------

        Cuando este tipo de virus llega a tu sistema (ya sea por Inet,
floppy ...) lo hace como mochila de un PE, es decir, viene aadido al
propio codigo del ejecutable. De tal forma, que cuando el usuario ejecuta
el fichero el control lo toma el codigo del virus para una vez hechas las
acciones oportunas pasarselo al codigo del programa (que a partir de ahora
llamaremos host).

        Dichas acciones seran establecer las condiciones oportunas para
un entorno de infeccion propicio y adecuado. En este punto, por lo tanto,
mirara si se puede reproducir y para ello buscara otro host que pueda
infectar. En la actualidad (para este tipo de virus, no para VxD infectors)
los tipos de infeccion conocidos son RUNTIME e infectors PER PROCESS que
en el apartado "Tipos de infeccion" podras ver con detalle.

        Una vez que el host esta infectado por el virus (como ya dije mas
arriba) el virus cede el control al host, en cambio, si se cumplen ciertas
condiciones lanzara una rutina (llamada en el mundillo "payload") que
afortunadamente en la ultima generacion de escritores de virus "profesionales" 
tienden a ser autenticas obras de arte e ingenios de programacion.


  3 -. Estructura de un PE.
  -------------------------

        Microsoft ha hecho uso de una nueva estructura para sus ficheros
almacenados en disco llamado PE (Portable Ejecutable) en contra de otras
estructuras utilizadas en sus propios sistemas operativos tiempo atras,
como es el caso de MZ en Ms-DOS o NE en Win16.

        Aunque estos cambios en el tipo de almacenamiento pueden resultar
incomodos para el programador hay que reconocer que el grupo de
desarrolladores de Msoft ha dado un gran paso con el formato PE hacia la
facilidad, portabilidad y abstraccion entre diferentes plataformas.

        Cabe destacar que un PE es practicamente una imagen del codigo 
que el cargador de Win32 (loader) pondra en memoria y al que cedera el 
control. Para eso el loader analiza la estrutura del PE mediante la
lectura de la PE header (cabecera del PE) que aporta diversa informacion
para establecer un entorno de ejecucion adecuado. Esta informacion vendra
dada en numero de objetos, tipo de maquina ... etc.

        Entremos ahora en una descripcion mas minuciosa de la estructura
de un PE.

    Ŀ  <Ŀ < Base of Image Header
     DOS 2 Compatible      
        EXE Header         
    Ĵ     
          unused           
    Ĵ     
      OEM Identifier       
      OEM Info             
                              DOS 2.0 Section
        Offset to             (for DOS compatibility only)
        PE Header          
    Ĵ     
       DOS 2.0 Stub        
       Program &           
       Reloc. Table        
    Ĵ  <
          unused      
    Ĵ  < Aligned on 8 byte boundary
        PE Header     
    Ĵ
       Object Table   
    Ĵ
       Image Pages    
         import info  
         export info  
         fixup info   
         resource info
         debug info   
    

        La anterior estructura la podras encontrar en cualquier PE.
Basicamente un PE contiene una cabecera compatible DOS para guardar
compatibilidad y que es la encargada de saltar al stub, que no es mas
que un pequeo programa DOS que muestra el tipico mensaje de
incompatibilidad 'This program requieres ...' o el mensaje oportuno cuando
se ejecuta el PE en un entorno que no es Win32 como es el Ms-DOS.

        Por el contrario si el entorno es el adecuado se podra obtener el
offset a la PE Header que contendra informacion sobre la tabla de objetos,
objetos y las paginas de informacion.

        Los objetos son tambien conocidos como secciones y estos pueden
ser de codigo o datos entre otros. Estas secciones tendran sus propias
propiedades, derechos ... etc ... que estaran contenidos en la tabla de
objetos.

        Las paginas de informacion contendran informacion sobre la
"import table" y "export table" entre otras, pero son estas sobre las que
nos centraremos debido a que en estas tablas el PE importa o exporta
recursos de otros modulos (no olvidemos que el PE puede exportar recursos
porque tambien el tiene status de modulo).

        La PE Header presenta la siguiente estructura.

    Ŀ
0         SIGNATURE BYTES        CPU TYPE     # OBJECTS  
    Ĵ
8          TIME/DATE STAMP              RESERVED          
    Ĵ
16            RESERVED           NT HDR SIZE    FLAGS    
    Ĵ
24    RESERVED   LMAJORLMINOR         RESERVED          
    Ĵ
32            RESERVED                  RESERVED          
    Ĵ
40         ENTRYPOINT RVA               RESERVED          
    Ĵ
48            RESERVED                 IMAGE BASE         
    Ĵ
56         OBJECT ALIGN                FILE ALIGN         
    Ĵ
64    OS MAJOR     OS MINOR   USER MAJOR   USER MINOR   
    Ĵ
72   SUBSYS MAJOR SUBSYS MINOR         RESERVED          
    Ĵ
80          IMAGE SIZE                HEADER SIZE         
    Ĵ
88         FILE CHECKSUM         SUBSYSTEM    DLL FLAGS  
    Ĵ
96     STACK RESERVE SIZE           STACK COMMIT SIZE     
    Ĵ
104    HEAP RESERVE SIZE            HEAP COMMIT SIZE      
    Ĵ
112          RESERVED            # INTERESTING RVA/SIZES  
    Ĵ
120    EXPORT TABLE RVA           TOTAL EXPORT DATA SIZE  
    Ĵ
128    IMPORT TABLE RVA           TOTAL IMPORT DATA SIZE  
    Ĵ
136   RESOURCE TABLE RVA         TOTAL RESOURCE DATA SIZE 
    Ĵ
144   EXCEPTION TABLE RVA        TOTAL EXCEPTION DATA SIZE
    Ĵ
152   SECURITY TABLE RVA         TOTAL SECURITY DATA SIZE 
    Ĵ
160     FIXUP TABLE RVA          TOTAL FIXUP DATA SIZE    
    Ĵ
        DEBUG TABLE RVA          TOTAL DEBUG DIRECTORIES  
    Ĵ
      IMAGE DESCRIPTION RVA      TOTAL DESCRIPTION SIZE   
    Ĵ
       MACHINE SPECIFIC RVA       MACHINE SPECIFIC SIZE   
    Ĵ
      THREAD LOCAL STORAGE RVA       TOTAL TLS SIZE       
    


        Los campos de la PE Header son identificativos y solo creo
necesario explicar algunos campos concretos y determinados conceptos
que Msoft usa habitualmente en la descripcion de sus estructuras como
son VA o RVA.

        Una VA es una direccion virtual. Cuando un modulo se carga en
memoria el principio del modulo recibe el nombre de "Base de la Imagen"
por lo que esa Base de la Imagen mas un offset da una direccion virtual
(ten en cuenta que ese offset puede ser 0). Ese determinado offset recibe
el nombre de RVA (Direccion Virtual Relativa). Una RVA de 0 en la 
cabecera PE significa que ese campo no es usado.

SIGNATURE BYTES = "PE/0/0". Firma del PE. Tamao de 4 bytes.

# OBJECTS = Numero de entradas en la tabla de objetos (=numero de objetos).

FLAGS = Los bits de esta palabra tomaran unos determinados valores para
        indicar si es una imagen ejecutable, si se puede cargar en la
        base de la imagen etc ...

ENTRYPOINT RVA = RVA del punto de entrada.

IMAGE BASE = VA de la base de la imagen. Apunta al primer byte del archivo
que coincide con la Dos Header. Debe ser un multiplo de 64K.

        Por lo tanto el punto de entrada exacto al programa sera la suma de
la ENTRYPOINT RVA + IMAGE BASE.

        Los campos que acaban con ALIGN es el tamao por el que se redondea
por exceso el concepto al que haga referencia el campo.

EXPORT TABLE RVA = RVA de la Export Table.

IMPORT TABLE RVA = RVA de la Import Table.

        El resto de los campos son identificativos por si solos por lo que 
no hare alusion a ellos, pero si estas interesado en su descripcion puedes 
buscar informacion en http://www.microsoft.com.

        La siguiente estructura importante dentro de un PE es la tabla de
objetos que como ya mencione anteriormente nos dara informacion valiosa
sobre cada tipo de objeto albergado por el PE. El numero de entradas en la
tabla de objetos viene dada en la PE Header por el campo # OBJECTS. Los
objetos son ordenados por el linker y la tabla empezara en uno. El tamao
de los objetos es redondeado por exceso usando el OBJETC ALIGN.

        Cada entrada en la tabla de objetos de un PE presenta la siguiente
estructura.

    Ŀ
                         OBJECT NAME                       
    Ĵ
           VIRTUAL SIZE                   RVA             
    Ĵ
          PHYSICAL SIZE              PHYSICAL OFFSET      
    Ĵ
            RESERVED                    RESERVED          
    Ĵ
            RESERVED                  OBJECT FLAGS        
    


OBJECT NAME = Nombre del objeto (tamao de 8 bytes) acabado en NULL.

VIRTUAL SIZE = Talla del objeto una vez cargado en memoria. Cualquier
               diferencia entre PHYSICAL SIZE y VIRTUAL SIZE es rellenada
               con ceros.

RVA = RVA de comienzo del objeto.
                                 
OBJECT FLAGS = Flags para el objeto que pueden presentar los siguientes
               valores.

  o  000000020h __Code object.
     
  o  000000040h __Initialized data object.
     
  o  000000080h __Uninitialized data object.
     
  o  040000000h __Object must not be cached.
     
  o  080000000h __Object is not pageable.
     
  o  100000000h __Object is shared.
     
  o  200000000h __Executable object.
     
  o  400000000h __Readable object.
     
  o  800000000h __Writeable object.


        El resto de bits son reservados para el futuro.

        Sobre las Paginas de Imagen lo mas destacado es que contienen todos
los datos inicializados de los objetos.

        La siguiente estructura interesante es la informacion para la Export
Table. Dicha informacion presenta la siguiente estructura.

    Ŀ
         DIRECTORY TABLE   
    Ĵ
         ADDRESS TABLE     
                           
                           
                           
                           
                           
                           
    Ĵ
         NAME PTR TABLE    
                           
                           
                           
    Ĵ
         ORDINAL TABLE     
                           
                           
                           
    Ĵ
         NAME STRINGS      
                           
                           
    

        La Export Directory Table contiene informacion para resolver
las referencias que se puedan plantear a los puntos de entrada con relacion
a la siguiente imagen.

    Ŀ
                EXPORT FLAGS           
    Ĵ
               TIME/DATE STAMP         
    Ĵ
      MAJOR VERSION     MINOR VERSION 
    Ĵ
                 NAME RVA              
    Ĵ
               ORDINAL BASE            
    Ĵ
               # EAT ENTRIES           
    Ĵ
                # NAME PTRS            
    Ĵ
             ADDRESS TABLE RVA         
    Ĵ
            NAME PTR TABLE RVA         
    Ĵ
             ORDINAL TABLE RVA         
    


EXPORT FLAGS = Actualmente vale 0.

TIME/DATE STAMP = Time/Date cuando fue creada.
                                              
NAME RVA = RVA del nombre Ascii de la DLL.

ORDINAL BASE = Primer ordinal valido para la export address table.
               Normalmente vale 1.

# EAT ENTRIES = Numero de entradas en la Export Address Table.

# NAME PTRS = Numero de entradas en la Name Ptr Table (coincide con el
              anterior).

ADDRESS TABLE RVA = RVA de la Export Address Table.

NAME TABLE RVA = RVA de la Export Name Table Pointers. Esta tabla es un
                 array de RVAs con un numero de # NAMES entradas.

ORDINAL TABLE RVA = RVA de la entrada para la Export Ordinals Table.


        En relacion a la Export Address Table decir que contiene la
direccion de los puntos de entrada exportados. Un numero ordinal es usado
para indexar en dicha tabla. El ORDINAL BASE debe ser restado del numero
ordinal antes de indexar en dicha tabla.

        El formato de entrada de la Export Address Table puede verse a
continuacion.

    Ŀ
               EXPORTED RVA            
    
    

EXPORTED RVA = RVA a la exported entry.

        La Export Name Table Pointers es un array que contiene la direccion
en la Export Name Table. Los punteros son de 32 bits cada uno.

        La Export Name Table Pointers y la Export Ordinal Table forman dos
arrays paralelos. El segundo permite obtener los punteros en el primero.

        La export name table contiene los nombres en ASCII de las entradas
exportadas. Esto es usado con el array de la Export Name Table Pointers
y el array de la Export Ordinals para traducir nombres en numeros ordinales.
De esta manera el numero ordinal es usado para localizar el punto de entrada
correspondiente a la informacion en la export address table.

        Cada entrada en la tabla presenta el siguiente formato.

    Ŀ
     ASCII STRING ::: ::::::::   '\0'  
    
    

ASCII STRING = DB ASCII String (recuerda que es case-sensitive).


        Complementariamente a la export information aparece la import
information con el siguiente formato.

    Ŀ
         DIRECTORY TABLE   
                           
                           
                           
    Ĵ
        NULL DIR ENTRY     
    
    
    Ŀ
       DLL1 LOOKUP TABLE   
                           
    Ĵ
             NULL          
    
    
    Ŀ
       DLL2 LOOKUP TABLE   
                           
    Ĵ
             NULL          
    
    
    Ŀ
       Dll3 LOOKUP TABLE   
                           
    Ĵ
             NULL          
    
    
    Ŀ
        HINT-NAME TABLE    
                           
    
    
    Ŀ
       DLL1 ADDRESS TABLE  
                           
    Ĵ
             NULL          
    
    
    Ŀ
       DLL2 ADDRESS TABLE  
                           
    Ĵ
             NULL          
    
    
    Ŀ
       DLL3 ADDRESS TABLE  
                           
    Ĵ
             NULL          
    

        La import information empieza con la Import Directory Table la cual
describira el resto de la import information. La Import Directory Table
contiene informacion de direcciones que es usada para resolver referencias
a los puntos de entrada en la imagen de una DLL. La import directory table
consiste en un array de entradas al directorio de la import (una entrada
para cada DLL). La ultima entrada de directorio es un NULL que indica el fin
de directory table.

Una Import Directory Entry presenta el siguiente formato.

    Ŀ
 0              IMPORT FLAGS           
    Ĵ
 4             TIME/DATE STAMP         
    Ĵ
 8    MAJOR VERSION     MINOR VERSION 
    Ĵ
 12               NAME RVA             
    Ĵ
 16       IMPORT LOOKUP TABLE RVA      
    Ĵ
 20       IMPORT ADDRESS TABLE RVA     
    
 24 

IMPORT FLAGS = Actualmente toman el valor de 0.
                      
NAME RVA = RVA del nombre ASCII de la DLL

IMPORT LOOKUP TABLE RVA = Este campo contiene la direccion del principio
                          de la import lookup table para esta imagen.

IMPORT ADDRESS TABLE RVA = Este campo contiene la direccion de comienzo de
                           la import addresses para esta imagen.


        La Import Lookup Table es un array de ordinal o "hint/name RVA's"
para cada DLL. La ultima entrada es vacia (NULL) la que indica el fin de
la tabla.

        El ultimo elemento es vacio.

     3                                 0
     1
    Ŀ
    0   ORDINAL#/HINT-NAME TABLE RVA  
    
    

ORDINAL/HINT-NAME TABLE RVA = 31-bits (mask = 7fffffffh)
                              Numero ordinal o RVA de la Name Table.
                              Si la import es por ordinal el campo contiene
                              un ordinal con valor 31 bits activos.
                              Si el import es por nombre, este campo
                              contiene una direccion de 31 bits relativa
                              a la Image Base y a la Hint-Name Table.

O = 1-bit (mask = 80000000h) Import by ordinal flag.

  o  00000000h __Import by name.
     
  o  80000000h __Import by ordinal.


        El formato de la Hint-Name Table es el siguiente:

    Ŀ
           HINT       ASCII STRING |||
    Ĵ
    |||||||||||||||||  '\0'     PAD   
    
    
    
        El campo PAD es opcional.
    
HINT = El valor de hint es usado para indexar el array de la Export Name
       Table Pointers (supone busquedas mas rapidas).

ASCII STRING = String case-sensitive acabado en NULL.

PAD = Aparece si necesario para redondear en relacion con la proxima entrada.

        El cargador sobreescribe la import address table cuando carga la
imagen en memoria con las direcciones correctas.
                   
        La Import Address Table es un array de direcciones de las rutinas
importadas para cada DLL. La ultima entrada es vacia (NULL) la cual indica
el fin de la tabla.

        Para la infeccion de PE esto es todo lo que necesitas saber para
entender la infeccion por lo que el resto de estructuras del PE no las
tocaremos.


  4 -. APIs en Win32.
  -------------------

        Igual que los virus de 16 bits utilizaban las INT (interrupciones)
que Msoft proporcionaba con Ms-DOS los virus de 32 bits utizaran algo
parecido llamado APIS para acceder a la maquina a bajo nivel proporcionando
a los programas abstrabilidad y portabilidad entre diferentes y futuras
versiones del sistema operativo.

        Los API (interface de programacion de aplicaciones) son colecciones
de funciones que normalmente estan almacenados en bibliotecas de enlazado
dinamico (.dll) o en bibliotecas estaticas (.lib). Sirven de ayuda para
implementar tipos especificos de funcionalidad en una aplicacion, tal
como los gr ficos, el sonido, el acceso a bases de datos o las
comunicaciones; esto se hace proporcionando una capa de codigo que se
interpone entre nuestra aplicacion y el hardware que le sirve como base.

        Cualquier programa usa APIS. Cuando nosotros codeamos una aplicacion
y hacemos uso de determinados APIS, el linker, "adaptara" la import table para
que una vez cargado el programa en memoria por el loader, este ultimo,
rellene la import table con las diferentes direcciones de los APIS que
nosotros hemos demandado al compilar el programa. De esta manera, el trabajo
recae sobre el loader facilitando la portabilidad ya que la asignacion de
direcciones hardcode se hace dinamicamente. Ademas de todo esto, ten en
cuenta que el loader solo tiene que poner la direccion correcta en un lugar
y todas las referencias se haran a este lugar en vez de tener que patchear
todos los calls de la imagen una vez cargada en memoria.

        Cuando nosotros hacemos un CALL NombreAPI, el call realmente es un
salto a una tabla de saltos de tipo JMP DWORD PTR [XXXXXXXX], es decir,
saltaria a un un salto a doble palabra. Esta doble palabra sera la direccion
del API en memoria que el programa encontrara en la import table. Ya que,
como dijimos antes, la direccion de NombreAPI es rellenada por el loader en
el momento de carga de la imagen.

        Es importante conocer que la direccion del JMP DWORD PTR [XXXXXXXX]
puede estar en cualquier lugar en la seccion de codigo, es decir, posee
direccion variable en la seccion de codigo aunque siempre esta en este lugar.

         Cabe mencionar tambien que la import table una vez compilado y
linkado el programa no se puede modificar en absoluto. Por lo que cualquier
modificacion que se quiera hacer en ella no es posible.

        La solucion que adopto la comunidad virica es la trivial y quizas la
mas simple, es decir, hacerle un bypass a todo el metodo anterior sabiendo
que las direcciones de los modulos que vamos a usar residen en memoria
estaticamente para versiones identicas del mismo sistema operativo.

        Un call NombreAPI una vez ensamblado se convierte en un

        db 9ah     ; call
        dd ????    ; offset en tabla de saltos

        El codigo que aparece en ese determinado offset es un

        JMP DWORD PTR [XXXXXXXX]

        donde [XXXXXXXX], como ya dijimos, es la direccion que aparece en la
import table y que correspondera con el valor para la funcion dispatcher
correspondiente a ese API. Esta direccion se puede obtener mediante un API
llamada GetProcAddress.

        Una vez que el control lo tiene el dispatcher para ese API lo que
hace es empujar un valor en la pila y llamar al punto de entrada para el
modulo correspondiente.

        push valor para funcion
        call PuntoEntrada del modulo

        Los primeros escritores de virus traceaban un programa para obtener
todos esos datos y despues usar hardcodes en sus virus.

        Lo anterior acarrea a priori un problema de portabilidad ya que un
virus escrito para Windows 95 OSR2 funcionaria perfectamente para todos los
Windows 95 OSR2 del mercado pero no funcionaria en Windows 98 o Windows 95.

        Posteriormente hablaremos de como soluciona la comunidad virica
esto a traves del uso de diferentes tecnicas para conseguir portabilidad
para las actuales plataformas que corren Windows 9x/NT.


  5 -. Tipos de Infecciones en un PE.
  -----------------------------------

        Dentro de infeccion para PE existen diferentes tipos de infeccion
segun hagan relacion a la forma o al metodo.

        Segun la forma existen infeccion mediante la adiccion del cuerpo
del virus en un nuevo objeto o mediante su inclusion en la ultima seccion
de la imagen.

        Segun el metodo de infeccion existen RUNTIME, PER PROCESS o una
combinacion de las anteriores.

    * Segun la forma :

        La adiccion de un nuevo objeto ejecutable al codigo del host y la
modificacion del punto de entrada a este ultimo constituye la primera forma
de infeccion conocida en Win32.

        Los siguientes datos son usados por virus que usan esta forma de
infeccion para rellenar los campos del objeto ...

  RVA = ((prev RVA + prev Virtual Size) / OBJ Alignment+1) * OBJ Alignment

 Virtual = ((size of virus+buffer any space)/OBJ Alignment+1)*OBJ Alignment
  Size

 Physical = (size of virus / File Alignment+1) * File Alignment
  Size

 Physical = prev Physical Offset + prev Physical Size
  Offset

 Object Flags = db 40h, 0, 0 c0h

 EntryPoint RVA = RVA

        Posteriormente habria que incrementar el numero de objetos de
la imagen en 1.


        Para los virus que infectan aadiendo su codigo en la ultima seccion
ellos lo hacen apuntando a la Section Table (ver Estructura de un PE) y
buscando la ultima seccion. El unico problema que encuentran es que el array
al que apuntan no guarda las secciones por orden por lo que deben mirar
cada seccion independientemente y observar el campo PointerToRawData. El
que tenga un valor mas alto coincide con la ultima seccion. Posteriormente
modificaran los datos para esa seccion, en concreto, VirtualSize y
SizeOfRawData.
              

    * Segun el metodo :

        RUNTIME es el metodo de infeccion en tiempo de ejecucion, es decir,
un virus infectara cualquier host al que pueda acceder en el momento que
toma el control. Ejemplos de RUNTIME son infectar los ficheros del directorio
actual o del anterior (mediante ..) o la lectura del autoexec.bat para
conocer la localizacion exacta de determinados ficheros predeterminados en
el sistema.

        La infeccion PER PROCESS consiste en una especie de pseudo residencia
en memoria ya que realmente lo que se hace es parchear un determinado API
(por ejemplo CreateProcess) y asi poder infectar todas las llamadas a ese
API para procesos hijos del que parchea y no para cualquier otro. Este metodo
de infeccion es bastante potente ya que en Win NT si se infecta el CMD el
virus se podria esparcir con un simple DIR.



  6 -. Tecnicas Empleadas.
  ------------------------

        En este apartado se trataran diversas tecnicas que emplean los
escritores de virus ya sea para facilitar la portabilidad de sus criaturas,
mejorar la productividad de la infeccion o simplemente ocultarse de programas
no deseados.

        Debido al numero de tecnicas que estan emergiendo y la disparidad de
temas que tratan se hablara de ellas independientemente manteniendo un indice
que facilitara su busqueda.

        6.1 El problema del KERNEL 32
        -----------------------------

        Como ya se ha mencionado anteriormente la mayoria de los virus
utilizan direcciones raw para hacer referencia al modulo donde se encuentran
la mayoria de los APIs que podemos utilizar en una infeccion. El problema
consiste en que si se usan estas direcciones raw o hardcodes no podremos
asegurar la portabilidad entre diferentes plataformas o versiones.

        La solucion viene dada por dos APIs determinadas :

                GetModuleHandle y GetProcAddress.

        GetModuleHandle nos dara la direccion de cualquier modulo cargado
en memoria en el registro EAX, mientras que GetProcAddress nos dara la
direccion de cualquier API que deseemos con solo pasarle el nombre en
case-sensitive. Posteriormente lo unico que hace el virus es almacenar las
direcciones mediante un bucle y listo.

        Aparte de todo esto el problema va mas alla ya que como te habras
dado cuenta para llamar a estos dos APIs necesitamos saber su direccion.
La solucion a esto ultimo viene dada por la import table. Una vez que
la imagen esta cargada en memoria el loader habra puesto la direccion de
los APIs solicitados en la import table. Debido a esto la mayoria de virus
multiplataforma y portables solo infectan PEs que contengan dichos APIs
en la import table o que puedan conocer sus direcciones mediante trucos no
documentados (aunque usando esto ultimo los programadores se arriesgan a que
sus virus no sean compatibles con diferentes versiones).

Nota : Esta tecnica se dio a conocer a traves de virus programados por
       Jacky Qwerty / 29A. Aplicable tambien a la export table.


        6.2 -. Solucion forwarder-chain
        --------------------------------

        La solucion forwarder-chain toma su nombre de un campo del import
descriptor llamado ForwarderChain. Esta caracteristica no esta documentada
por Microsoft por lo que los virus que la utilizan la usan con reservas
ya que solo funciona (actualmente) con las versiones Win9x no con WinNT.

        Cuando un PE demanda un numero de APIs del KERNEL32 el loader del
sistema pone la direccion base del KERNEL32 en el campo ForwarderChain.

        Esto es utilizado por algunos virus para obtener dicha direccion
cuando el metodo de *fisgonear* en la import y export table fallan.


        6.3 File Mapping.
        -----------------

        El file mapping es una de las caracteristicas mas innovadoras con las
que Msoft dota a sus sistemas operativos. Basicamente consiste en un metodo
de entrada/salida que facilita muchisimo la tarea de manejo de ficheros por
parte del programador. Mediante el file mapping un fichero se le presenta al
programador como un puntero a un monton de bytes en memoria que constituyen
el fichero en si y a los cuales se puede acceder mediante la suma de un offset
a este puntero. Entre las ventajas que presenta sobresale la velocidad de
acceso a los datos del fichero.


        6.4 -. Semi-Stealth.
        --------------------

       Cuando un virus se preocupa de intentar pasar desapercibido y usa
rutinas especificas para tal efecto, se dice que incorpora tecnicas stealth.

        El grado de stealth que incorpore un virus puede ir desde el mas
bajo o trivial (guarda-restaura fecha y atributos del fichero) hasta
practicamente no ser visible por las utilidades de disco del propio sistema.

       Algunos virus per process aprovechan esta caracteristica para
camuflarse de ojos no deseados. Como ya se comento (ver "Tipos de Infeccion")
mediante la modificacion de la import table y una rutina adecuada el virus
es capaz de tomar el control de ciertos APIs cuando un proceso hijo intenta
llamarlos; como es el caso de FindFirstFile o FindNextFile. El virus es capaz
de devolver tamaos correctos, desinfectar on-fly ... etc. De esta manera
programas diseados para calcular checksums sobre tamaos, nombres, fechas
seran hackeados de manera transparente.


        6.5 -. Anti-debug y SEH.
        ------------------------

        Una vez que el virus ha sido detectado algunos virus incorporan
acciones destinadas exclusivamente a no dejarse examinar o autodestruirse.

        Para conseguir las acciones anteriores los nuevos virus para 32 bits
hacen uso de SEH (Structured Sception Handling). SEH hace alusion a la
manera de tomar el control sobre las excepciones que se producen cuando
ocurre alguna accion no permitida o que puede provocar la inestabilidad del
sistema bajo el que corre la aplicacion o codigo que la produce.

        Basicamente SEH en Win32 es usada por los virus para tomar el
control cuando se produce una excepcion y ejecutar parte de su codigo para
impedir el efecto que deseariamos que tuviese esa excepcion.

        Para tomar el control de una excepcion tratada previamente mediante
SEH lo unico que necesita el virus es tener una funcion CALLBACK que
tomara el control cuando dicha excepcion se produzca y que sera la encargada
de efectuar las acciones que el virus crea mas convenientes.

        Como te habras imaginado los debuggers trabajan mediante excepciones
asociadas que le permitiran tomar el control cuando traceamos o ejecutamos
codigo hasta cierto punto, por lo que el virus se interpondra entre ellos y
sus excepciones imposibilitando que se pueda debuggear su codigo.

        Aparte de lo anterior SEH constituye una herramienta muy potente
no usada exclusivamente para anti-debug.

        Uno de los debuggers vulnerables a esta tecnica es TD32, en
contraposicion a WinIce.


Nota: Podras encontrar codigo de ejemplo en virus como Win32.Cabanas de
      Jacky Qwerty / 29A.


        6.6 -. Anti-heuristica.
        -----------------------

        Una tecnica muy utilizada por diferentes anti-virus para detectar
virus no conocidos o para rentabilizar el tiempo y dar una probabilidad
mas o menos aceptable de posible infeccion de un fichero por un virus es la
llamada heuristica. Es decir, para aplicar esta tecnica los anti-virus dan
por sentado que un host infectado *tiene que* presentar ciertas huellas de
dicha infeccion (como por ejemplo ciertos virus que marcan su infeccion
poniendo el campo segundos de su fecha a 61, cosa irreal en la practica).

        Las tecnicas anti-heuristicas mas utilizadas en la actualidad pasan
por modificar lo menos posibles la PE header, no aadir nuevas secciones,
no modificar permisos de paginas, restaurar fechas y atributos ...

        En relacion al tema de la PE header los virus para Win32 de ultima
hornada pasan de modificar el ENTRYPOINT RVA y modificar los primeros 5
bytes al que apunta este ultimo con un JMP DWORD PTR al principio del
codigo virico en la ultima seccion (ejemplo de esta tecnica podras verla en
el virus Cabanas de Jacky Qwerty / 29A ).

        

  7 -. Ultimas palabras ...
  -------------------------

        La ultima version de este documento podras encontrarlo en las
siguientes direcciones:

        http://www.blackbrains.org

        http://www.galaxycorp.com/izan    (iZan homepage)

        Si deseas contactar con el autor para sugerencias, bugs o cualquier
otra cuestion dirigete a izan@blackbrains.org (si encuentras algun problema
con esta direccion prueba a cambiar el dominio por galaxycorp.com).

        Todo el correo sera confidencial y se tratara con la mayor privacidad
posible. Podras alcanzarme tambien a traves de PGP bajandote mi llave publica
de las direcciones anteriores o haciendo uso de la que se presenta en el
Apendice B.



                           --=[ APENDICES ]=--


  * Apendice A (Implementacion)
  -----------------------------

        Si estas interesado en la implementacion de virus para Win32 podras
encontrar ejemplo de codigo en los siguientes virus para todas las tecnicas
descritas en este release.


        Bizatch / Boza -. Primer PE infector para Win32. Programado por
                          Quantum del grupo Australiano VLAD. En el
                          podras ver un claro ejemplo de hardcodes, infeccion
                          por adiccion de un nuevo objeto. Runtime infector.
                          Muy basico pero increiblemente didactico.

        Win32.Jacky -. Programado por jQwerty del grupo espaol 29A. Sin
                       duda un claro ejemplo de portabilidad multiplataforma.

        Win32.Cabanas -. Programado por jQwerty del grupo espaol 29A.
                         Codigo increiblemente eficiente, portable y escrito
                         con gran elegancia. Modelo didactico a seguir y
                         pionero de los virus que estan por llegar.


  * Apendice B (iZan PGP Public Key)
  ----------------------------------


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- -----BEGIN PGP PUBLIC KEY BLOCK-----
Version: PGPfreeware 5.5.3i for non-commercial use
<http://www.pgpi.com>

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
5muhUf7bUoD3
=lBV5
- -----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.5.3i for non-commercial use <http://www.pgpi.com>

iQA/AwUBNnenI7ZfL1sis1A5EQL3QwCgxznyveMOvPINvimkV8hL89sHlyEAnAyz
lt6ULK/TQ31RCT7Vh3kdZVmT
=8bbj
-----END PGP SIGNATURE-----



                                                           iZan / BB'99
                                               --=[ izan@blackbrains.org ]=--
