sábado, 5 de febrero de 2011

Radiografia de un virus

Los virus informáticos están hechos en Assembler, un lenguaje de programación de bajo nivel. Las instrucciones compiladas por Assembler trabajan directamente sobre el hardware, esto significa que no es necesario ningún software intermedio –según el esquema de capas entre usuario y hardware- para correr un programa en Assembler (opuesto a la necesidad de Visual Basic de que Windows 9x lo secunde). No solo vamos a poder realizar las cosas típicas de un lenguaje de alto nivel, sino que también vamos a tener control de cómo se hacen. Para dar una idea de lo poderoso que puede ser este lenguaje, el sistema operativo Unix está programado en C y las rutinas que necesitan tener mayor profundidad para el control del hardware están hechas en Assembler. Por ejemplo: los drivers que se encargan de manejar los dispositivos y algunas rutinas referidas al control de procesos en memoria.


Sabiendo esto, el virus puede tener control total de la máquina -al igual que lo hace el SO- si logra cargarse antes que nadie. La necesidad de tener que "asociarse" a una entidad ejecutable viene de que, como cualquier otro programa de computadora, necesita ser ejecutado y teniendo en cuenta que ningún usuario en su sano juicio lo hará, se vale de otros métodos furtivos. Ahora que marcamos la importancia para un virus el ser ejecutado, podemos decir que un virus puede encontrarse en una computadora sin haber infectado realmente algo. Es el caso de personas que pueden coleccionar virus en archivos comprimidos o encriptados.

Normalmente este tipo de programas se pega a alguna entidad ejecutable que le facilitará la subida a memoria principal y la posterior ejecución (métodos de infección). Como entidades ejecutables podemos reconocer a los sectores de arranque de los discos de almacenamiento magnéticos, ópticos o magneto-ópticos (MBR, BR), los archivos ejecutables de DOSs (.exe, .com, entre otros), las librerías o módulos de programas (.dll, .lib, .ovl, .bin, .ovr). Los sectores de arranque son fundamentales para garantizar que el virus será cargado cada vez que se encienda la computadora.

Según la secuencia de booteo de las PCs, el microprocesador tiene seteada de fábrica la dirección de donde puede obtener la primer instrucción a ejecutar. Esta dirección apunta a una celda de la memoria ROM donde se encuentra la subrutina POST (Power On Self Test), encargada de varias verificaciones y de comparar el registro de la memoria CMOS con el hardware instalado (función checksum). En este punto sería imposible que el virus logre cargarse ya que la memoria ROM viene grabada de fábrica y no puede modificarse (hoy en día las memorias Flash-ROM podrían contradecir esto último).

Luego, el POST pasa el control a otra subrutina de la ROM BIOS llamada "bootstrap ROM" que copia el MBR (Master Boot Record) en memoria RAM. El MBR contiene la información de la tabla de particiones, para conocer las delimitaciones de cada partición, su tamaño y cuál es la partición activa desde donde se cargará el SO. Vemos que en este punto el procesador empieza a ejecutar de la memoria RAM, dando la posibilidad a que un virus tome partida. Hasta acá el SO todavía no fue cargado y en consecuencia tampoco el antivirus. El accionar típico del virus sería copiar el MBR en un sector alternativo y tomar su posición. Así, cada vez que se inicie el sistema el virus logrará cargarse antes que el SO y luego, respetando su deseo por permanecer oculto hará ejecutar las instrucciones del MBR.

Con la información del MBR sabremos qué partición es la activa y en que sector se encuentra su sector de booteo (boot record o BR). El BR contiene una subrutina que se ocupará de cargar los archivos de arranque del SO. Los demás pasos de la carga del SO son irrelevantes, pero es importante recordar que el SO es el último en cargarse en la secuencia de booteo antes de que el usuario pueda introducir comandos en la shell. El antivirus es cargado por los archivos de configuración del SO personalizables por el usuario.

Cuando un virus infecta un archivo ejecutable .EXE, por ejemplo, intenta rastrear en el código los puntos de entrada y salida del programa. El primer punto señalado es en donde, dentro del archivo, se iniciará la ejecución de instrucciones. El segundo punto resulta ser lo opuesto. Cuando un virus localiza ambos puntos escribe su propio código antes de cada uno. Según el tipo de virus, este código cargará el virus en memoria –si es que no lo estaba- y apuntará a esa zona infectada con el virus. A partir de ahí el programa virósico determinará cuáles son las acciones a seguir: puede continuar infectando archivos que sean cargados en memoria, ocultarse si es que detecta la presencia de un antivirus o ejecutar el contenido de su módulo de ataque. El virus puede infectar también las copias de los archivos cargados en memoria que están en la unidad de almacenamiento. Así se asegura que ante un eventual apagado de la computadora su código igualmente se encuentra en los archivos de la unidad.

Es importante comprender que la computadora no estará infectada hasta que ejecutemos algo parasitado previamente con el virus. Veamos un ejemplo sencillo: nosotros bajamos de Internet un archivo comprimido (con la extensión .ZIP según el uso popular) sabiendo que es un programa de prueba que nos gustaría instalar. Lo que no sabemos es que uno de los archivos dentro del .ZIP es un virus informático, y lo peor de todo es que viene adosado al archivo Install.exe. Al momento de descomprimir el contenido, el virus todavía no fue ejecutado (ya que la información dentro del .ZIP no puede ser reconocida como instrucciones por el procesador). Luego identificamos el archivo Install.exe como el necesario para instalar el programa y lo ejecutamos. Recién en este momento el virus se cargará en memoria y pasará a hacer las cosas para lo que fue programado.

El ejemplo anterior es un modo muy básico de infección. Pero existen otros tantos tipos de virus que son mucho más sofisticados y no podrá ser reconocida su presencia con mucha facilidad.

Según sus características un virus puede contener tres módulos principales: el módulo de ataque, el módulo de reproducción, y el módulo de defensa.


  • Módulo de reproducción. Es el encargado de manejar las rutinas para infectar entidades ejecutables que asegurarán la subsistencia del virus. Cuando toma el control del sistema puede infectar otras entidades ejecutables. Cuando estas entidades sean trasladadas a otras computadoras se asegura la dispersión del virus.
  • Módulo de ataque. Es el módulo que contiene las rutinas de daño adicional o implícito. El módulo puede ser disparado por distintos eventos del sistema: una fecha, hora, el encontrar un archivo específico (COMMAND.COM), el encontrar un sector específico (MBR), una determinada cantidad de booteos desde que ingreso al sistema, o cualquier otra cosa a la que el programador quisiera atacar.
  • Módulo de defensa. Su principal objetivo es proteger el cuerpo del virus. Incluirá rutinas que disminuyan los síntomas que delaten su presencia e intentarán que el virus permanezca invisible a los ojos del usuario y del antivirus. Las técnicas incluidas en este módulo hoy en día resultan ser muy sofisticadas logrando dar información falsa al SO -y en consecuencia al usuario- y localizándose en lugares poco comunes para el registro de los antivirus, como la memoria Flash-Rom.
  • Algunos métodos de infección
Añadidura o empalme. Por este método el código del virus se agrega al final del archivo ejecutable a infectar, modificando las estructuras de arranque del archivo anfitrión de manera que el control del programa pase primero al virus cuando se quiera ejecutar el archivo. Este cambio de secuencia permite al virus realizar sus tareas específicas y luego pasar el control al programa para que este se ejecute normalmente. La principal desventaja de este método es que el tamaño del archivo infectado es mayor al original, lo que permite una fácil detección.

Inserción. Los virus que utilizan el método de inserción buscan alojarse en zonas de código no utilizadas o en segmentos de datos dentro de los archivos que contagian, de esta manera la longitud total del archivo infectado no varía. Este método, parecido al de empalme, exige mayores técnicas de programación de los virus para poder detectar las zonas posibles de contagio dentro de un ejecutable, por lo que generalmente no es muy utilizada por los programadores de virus informáticos.

Reorientación. Este método es una variante interesante del anterior. Bajo este esquema se introducen centrales virósicas (los códigos principales del virus) en zonas físicas del disco rígido marcadas como defectuosas o en archivos ocultos del sistema. Estos códigos virales, al ejecutarse, implantan pequeños trozos de código en los archivos ejecutables que infectan, que luego actúan como llamadores de las centrales virósicas. La principal ventaja de este método es que el cuerpo del virus, al no estar inserto en el archivo infectado sino en otro sitio oculto, puede tener un tamaño bastante grande, aumentando así su funcionalidad. La desventaja más fuerte es que la eliminación de este tipo de infecciones es bastante sencilla. Basta con borrar archivos ocultos sospechosos o reescribir las zonas del disco marcadas como defectuosas.

Polimorfismo. Este es el método más avanzado de contagio logrado por los programadores de virus. La técnica básica usada es la de inserción del código viral en un archivo ejecutable, pero para evitar el aumento de tamaño del archivo infectado, el virus compacta parte de su código y del código del archivo anfitrión de manera que la suma de ambos sea igual al tamaño original del archivo. Al ejecutar el programa infectado actúa primero el código del virus descompactando en memoria las porciones previamente compactadas. Una variante mejorada de esta técnica permite a los virus usar métodos de encriptación dinámicos para disfrazar el código del virus y evitar ser detectados por los antivirus.

Sustitución. El método de sustitución, usado con variantes por los Caballos de Troya, es quizás el método más primitivo. Consiste en sustituir el código completo del archivo original por el código del virus. Al ejecutar el programa infectado el único que actúa es el virus, que cumple con sus tareas de contagiar otros archivos y luego termina la ejecución del programa reportando algún tipo de error. Esta técnica tiene sus ventajas, ya que en cada infección se eliminan archivos de programas válidos, los cuales son reemplazados por nuevas copias del virus.

Tunneling. Es una técnica usada por programadores de virus y antivirus para evitar todas las rutinas al servicio de una interrupción y tener así un control directo sobre esta. Requiere una programación compleja, hay que colocar el procesador en modo kernel. En este modo de funcionamiento, tras ejecutarse cada instrucción se produce la INT 1. Se coloca una ISR (Interrupt Service Routine) para dicha interrupción y se ejecutan instrucciones comprobando cada vez si se ha llegado a donde se quería hasta recorrer toda la cadena de ISRs que halla colocando el parche al final de la cadena.

Los virus utilizan el tunneling para protegerse de los módulos residentes de los antivirus que monitorean todo lo que sucede en la máquina para interceptar todas las actividades "típicas" de los virus.

Para entender como funciona esta técnica basta saber como trabaja este tipo de antivirus. El módulo residente queda colgado de todas las interrupciones usualmente usadas por los virus (INT 21, INT 13, a veces INT 25 Y 26) y entonces cuando el virus intenta llamar a INT 21, por ejemplo, para abrir un ejecutable para lectura / escritura (y luego infectarlo), el antivirus emite una alerta, pues los ejecutables no son normalmente abiertos, ni menos para escritura. Y así con todas las llamadas típicas de los virus.

En cambio, cuando se hace una llamada común y corriente, el antivirus no le da mayor importancia y la deja pasar, llamando a la INT 21 original. Un virus con tunneling, entonces, antes de llamar a ninguna función ni hacer nada, intenta obtener el address absoluto de esta INT 21 original, que está en alguna parte de la memoria del antivirus residente. Una vez que obtiene este address, accede al MS-DOS por medio de el, sin llamar al antivirus. Y así, efectivamente, le "pasa por debajo", lo "tunelea". ¿Cómo se hace esto?

  • La primera, y la mas usada, es utilizando la interrupción de trace (INT 1) y la trap flag. (Que son usadas por los DEBUGGERS) para atravesar el código línea por línea hasta hallar lo que se busca. Es usada por todos los virus que usan esta técnica, como por ejemplo, el Predator II o el (ya viejo) Yankee Doodle.
  • La segunda, hacer un simple y llano scanning del código, byte a byte, hasta hallar el address. Se usa en pocos virus, pero es la que usa Kohntark en su célebre Kohntark Recursive Tunneling Toolkit.
Problemas Generales del Tunneling.

Pero el problema principal del tunneling es que aún teniendo éxito en obtener la INT 21 posta, se pueden tener problemas si hay algún residente importante y uno lo esta pasando por debajo. Es famoso ya el caso del Predator II y el DoubleSpace. El predator II tuneleaba por debajo del DoubleSpace y trataba de acceder al disco directamente por MS-DOS. Esto produjo que destruyera el contenido de varios discos rígidos. En definitiva, esto es contrario a las intenciones del tunneling.

No hay comentarios:

Publicar un comentario