VR22: Analisis de virus: Emma
Por Fernando Bonsembiante
En este número analizamos un virus argentino que usa una técnica muy poco convencional para ocultarse en memoria.
Los virus más modernos no escatiman esfuerzos para ocultarse en el disco. Para esto están técnicas de stealth, polimorfismo, encriptación, etcétera. Pero no es común que un virus intente ocultase en la memoria. La causa de esto es que es muy difícil hacerlo, ya que el código no puede estar encriptado mientras se ejecuta, y la única forma de hacer un stealth completo en memoria es entrando en modo protegido en una 386 o superior. Este método es imposible de usar en la práctica, ya que es incompatible con todos los manejadores de memoria existentes.
De todas formas, algo se puede hacer para ocultar un virus en memoria. Un ejemplo de esto es el virus Emma, hecho por Trurl, autor argentino de virus. Ya su nombre lo indica: Expanded Memory Major Anoyance (Gran molestia de la memoria expandida). Este virus pone una parte de su código en la tabla de interrupciones, y otra parte en memoria expandida. De esta forma, la mayor parte del virus está oculta de los anti-virus mientras permanece en memoria. En disco no hace ningún esfuerzo por ocultarse, pero es un virus hecho para probar la idea de la memoria expandida, es sencillo agregarle una rutina polimórfica y/o de stealth para que se oculte en disco tan bien como en memoria. La idea de funcionamiento es sencilla: una rutina en la memoria convencional, particularmente en la tabla de interrupciones, maneja el resto del código del virus, y lo mapea en memoria convencional cada vez que hace falta, y lo hace desaparecer en la memoria extendida el resto del tiempo.
Funcionamiento
Lo primero que hace el virus al cargarse es verificar si ya se encontraba en memoria. Para eso verifica que los bytes en 24h:0h sean 2E9Ch. Estos bytes corresponden al principio de la rutina que queda en la tabla de interrupciones, y empieza con el par de instrucciones pushf y cmp. Como el virus siempre se aloja en esta parte, no hay posibilidad de que esté cargado y esos bytes sean distintos. En el caso de que el virus ya esté en memoria, no se carga y devuelve el control al programa huesped. En el caso de que no esté, debe determinar si hay un manejador de EMM. Como el virus necesita que esté instalada la EMM, no puede cargarse sin este driver. Para esto busca el vector de la interrupción 67h, que es la que controla la EMM, y a partir de la dirección a la que apunta busca el string EMMXXXXX0. Si está presente, hay un manejador de EMM en funcionamiento y el virus puede instalarse. Caso contrario, le devuelve el control a su huesped. Para saber si tiene lugar en la EMM, el virus verifica si hay por lo menos una página libre. Si es así, busca la dirección del page frame, reserva una página de memoria, guarda el handle de dicha página en una variable, y mapea la página en el page frame. Luego guarda la dirección de la interrupción 21h en una variable, copia el virus en la memoria expandida, saca la página del page frame (la des-mapea) copia la parte del virus que va en la tabla de interrupciones, apunta la interrupción 21h a este lugar y ejecuta el huésped. De esta forma el virus queda instalado en memoria. Volvamos a repasar como queda: una parte del virus está en EMM y otra parte, muy pequeña, en una parte no usada de la tabla de interrupciones. La interrupción 21h del virus apunta a esa rutinita, que luego mapeará el resto del virus que está en EMM para poder usarlo cada vez que se necesite.
Interrupción 21h
La rutina que atiende a la interrupción 21h instalada por el virus se divide en dos partes. Una es la que está en la tabla de interrupciones. Esta rutina, cuando es llamada, verifica si está prendido o no un flag. Este flag indica si la rutina se está interrumpiendo a si misma, ya que, como no es reentrante, si sucede se cuelga. En el caso de que no sea así, mapea la página de memoria EMM donde está el virus, y llama a la rutina que atiende a la interrupción 21h. Cuando vuelve de ejecutar el handler de la interrupción 21h, des-mapea la página de EMM, y retorna de la interrupción. Si el flag estaba prendido ejecuta la interrupción 21h original. Todo este problema de los flags viene porque no se puede usar la interrupción 21h modificada dentro de la int 21h instalada por el virus en EMM, de alguna manera hay que indicarle al virus si se llama desde fuera o dentro de la interrupción 21h.
El handler en EMM verifica si la función llamada es la 4B00h, load and execute. Si no es así, ejecuta la interrupción 21h original. En el otro caso, procede a infectar el archivo que se intenta ejecutar. Primero que nada prende el flag de ocupado para que no se intente mapear nuevamente la página de EMM, y llama a la interrupción 21h original para que ejecute el programa. Luego lee los tres primeros bytes del programa y verifica si está previamente infectado o si se trata de un .EXE. En ese caso vuelve sin infectar. Si debe infectar el archivo, escribe el virus al final del mismo y agrega en el principio del programa un jump al principio del virus. Terminada la infección, apaga el flag, y vuelve de la interrupción.
Como vemos, es un virus muy sencillo, y su novedad es su uso de la memoria EMM para ocultarse. Seguramente el autor no pretendió hacer un virus complicado, sino simplemente probar su idea de ocultar un virus en memoria.
Fernando Bonsembiante es jefe de redacción de Virus Report y está estudiando los virus informáticos dese hace varios años. Tambien es miembro del Círculo Argentino de Ciencia Ficción, (CACyF) y participa como columnista de varias revistas sobre informática. También es asesor en seguridad informática y virus en varias empresas. Puede ser contactado por Fido en 4:901/303 o en Internet en ubik@ubik.to