viernes, 16 de enero de 2009

La persistencia del adware

Fragmento extraido de http://philosecurity.org/2009/01/12/interview-with-an-adware-author

¿Puedes contarnos más sobre como hacer que el adware sea complicado de eliminar en un ordenador?

Si. Primero prefiero contarte como funciona el adware. El objetivo fundamental del adware son los usuarios de Internet Explorer porque obviamente es el más utilizado en el mercado. Además, tienden a ser los más ingenuos. Si utilizas IE quiere decir que, o no pones cuidado, o no sabes nada sobre vulnerabilidades en IE.

IE tiene un mecanismo llamado Browser Helper Object (BHO), que básicamente es un trozo de código ejecutable que consigue información de las solicitudes web que se están produciendo. Esto corre en el proceso actual del navegador, quiere decir que puede hacer cualquier cosa que pueda hacer el navegador - y esto básicamente quiere decir: cualquier cosa. Nosotros podemos tener un BHO que actualmente es el servidor de ads, y lo hemos realizado de forma que para eliminarlo tengas que eliminar todas las instancias del navegador. Esto es una pequeña parte en cuanto a la persistencia.

Si además tienes un instalador, un pequeño ejecutable, puedes crear una entrada en el Registro para que en cada reinicio el instalador compruebe que el BHO existe. Si existe, bien. Sino existe lo instala. Esto funciona hasta que alguien elimina el ejecutable.

Lo siguiente es crear un ejecutable que continuamente compruebe cada 10 segundos que el BHO está activo y en su sitio. Si así es, perfecto. Sino, el ejecutable lo instalará. Para asegurarse de que el ejecutable sea dificilmente detectable, desarrollamos un algoritmo para hacer que los nombres de estos ejecutables sean aleatorios, a la vez que estén relacionados con el ordenador anfitrión y que sea complicado descubrirlos. Creo que utilizabamos los primeros 6 u 8 caracteres de la codificación DES de la dirección MAC del ordenador. Codificas la MAC con DES, tienes en cuenta los primeros 6 u 8 caracteres y ya está. Esto está muy bien. La pega es que el archivo en sí podía ser el mismo binario. Si sumas el MD5 del archivo siempre sería el mismo, y siempre estaría en el mismo ordenador (con esa MAC).

Lo siguiente que hicimos fue una función para repartir funciones, que podía ir dentro de un ejecutable, tomando funciones y repartiéndolas aleatoriamente, de forma que las firmas de los archivos estén mezcladas. También mezclábamos un montón de punteros con cada función corriendo. Esto cambia completamente la forma del ejecutable.

Luego creamos un lanzador, que es un minúsculo trozo de código escrito en ensamblador que descifraba el ejecutable en memoria y lo ejecutaba. Al mismo tiempo también creabamos un proceso ejecutable virtual. Nunca he oído que alguien hiciera esto antes. Windows tiene una cosa llamada Create Remote Thread. Semánticamente quiere decir: eres un proceso, yo soy un proceso distinto, puedo llamarte y decirte "¡Oye! tengo este código, y me gustaría que lo ejecutaras". Tu dices "Claro" porque eres un proceso de Windows -tu eres un hippie que crees en el amor libre-. Los procesos de Windows, dicho sea de paso, son peligrosamente promíscuos. Por tanto, podemos pillar unos cuantos procesos de Windows y darles un trozo de código para que lo ejecuten. Cada proceso conoce a los dos anteriores (el anfitrión y el que le hemos dado que es el trozo de código), y de esta forma podemos hacer un anillo para que se ayuden mutuamente, ¿ok?.

Hasta ahora tenemos una entrada en el registro, un ejecutable, nombres aleatorios para ejecutables, un ejecutable que es repartido en cada ordenador, uno de ellos está cifrado -y para más ofuscación- un ejecutable que ni siquiera se ejecuta como tal. Esto se ejecuta simplemente en forma de hilos. Ahora, esos hilos pueden comunicarse entre sí, pueden comprobar que el BHO está activo, y que cualquier otro software que queramos también esté bajo control.

Hay una cosa más avanzada que empezamos a realizar pero no terminamos de probar, y es prescindir de los hilos y utilizar los manejadores de las interrupciones.Resulta que en Windows puedes acceder facilmente al manejador de interrupciones. De hecho, puedes registrar con el OS un trozo de código para manejar una interrupción dada. Todo lo que tienes que hacer es pillar una interrupción, y cuando ésta se inicie, haces tu trabajo y listo. Nunca hemos hecho esto pero es algo que estamos pensando hacer.

Creamos claves de registro y nombres de archivos que no se podían modificar, explotando una "desajuste de impedancia" entre la API de Win32 y la API de NT. Windows XP está basado en el kernel de NT. La mayor parte de NT es un sistema Unicode, y debido a ello, los strings internamente son Unicode de 16-bit. La mayor parte de la API Win32 es ASCII. Existen strings que puedes expresar como Unicode 16-bit pero no puedes expresar en ASCII. Sorprendentemente, puedes ver cosas con un Null en medio de ello.

Esto quiere decir que podemos, por ejemplo, escribir una clave de Registro que contenga un Null. Debido a que la interfaz de usuario está basada en la API Win32, éste podría ver la clave, pero no podría modificarla porque no sabría interpretar el Null. De esta forma podemos hacer que las claves del Registro sean invisibles o inmodificables para cualquiera que utilice la API Win32. Esto es muy interesante, no para la gente común, pero sí para nuestros competidores y para las compañías antivirus.

También escribí un controlador y luego un controlador de impresora. Cuando escribes un controlador puedes hacer las cosas más locas que puedas imaginar, incluso más locas todavía que pudieras hacer normalmente con Windows. Esto ocurría cuando Eliot Spitzer demandó a la compañía y empezó a decaer. Tomaron una mala decisión justo cuando empezaron a dar más visibilidad a la compañía y entonces todo el mundo al mismo tiempo me quería para deshacerse de nuestros competidores y nosotros mientras tanto trabajando en todo lo anterior.

Por supuesto que se trataba de un plan. No nos gustaba escribir un nuevo programa en C cada vez que queríamos echar a alguien fuera de una máquina. Todo el mundo decía, "Lo que necesitamos es algo configurable". Yo decía, "Instalemos un lenguaje basado totalmente en Turing", y para eso utilicé tinyScheme, que es un intérprete muy pequeño y rápido con licencia BSD que puede compilarse en un ejecutable de 20kb, si sabes lo que estas haciendo.

A veces, en vez de escribir ejecutables independientes, utilizamos un gusano, así podemos escribir código, lo ponemos en el servidor, e inmediatamente las cosas deberían oscurecerse, llegando a repartirse el código en una guerra de entre 4 y 10 millones de nodos en red.

No hay comentarios: