Bug en Internet Explorer

Muchos usuarios de Windows desconocen mucho del software que el Sistema Operativo lleva integrado. Es más, el usuario medio cree que solo existe Windows y que es una parte inseparable del Computador, lo cual no es verdad. Seguidamente intentare mostraros de una manera mas o menos detallada un ERRORAZO, porque no tiene otro nombre, del archiconocido Internet Explorer, que viene integrado en Windows.

Bienvenidos una vez más. Esta vez, a diferencia del resto de mis artículos, hablaremos de un bug que afecta exclusivamente al Microsoft Internet Explorer, software integrado en Windows. Como algunos sabréis, soy usuario de Linux, así que comentaré, además del bug, como conseguir un entorno de pruebas sin tener si quiera que reiniciar el ordenador y como funciona el exploit. Lo que haremos será simular una computadora al completo, con su Bios y todo, e instalaremos en ella un Windows XP con una versión de Internet Explorer vulnerable, pero no avancemos acontecimientos y empecemos por el principio.

El bug

Este bug, es en realidad una pequeña modificación de otro que salió con anterioridad, así que mejor empezamos por el primero que se publicó.

El primer Advisory se nos presentaba como un simple DoS (Denial of Service) de riesgo Bajo, simplemente, si tu entrabas en según que web, el Internet Explorer fallaba. Éste fue publicado el día: 31/05/2005.

El segundo Advisroy, publicado el 21/11/2005 nos dice que este error se puede aprovechar para ejecutar código en la máquina de la víctima que visite la web, así pues, sólo necesitamos convencer a alguien para que entre a un site, de ese modo se podría ejecutar cualquier comando en la máquina víctima. Este bug ya pasaba de un riesgo Bajo a un riesgo Muy Alto.

Lo gracioso del tema es que Microsoft no sacó ningún parche para Internet Explorer que corrigiera el primer bug, seguramente no le dieron importancia a que al cliente se le colgara el navegador en según que sites. En un principio es lógico pensar que si tu entras a una web y se te cuelga el Internet Explorer ya no entrarás más, de esta manera el que sale perjudicado es el dueño del site ya que nadie le visitará. Microsoft debió pensar eso y deducir consecuentemente que el propio error no era importante y que los sites evitarían la sentencia que provoca el DoS.

Los pobres no tuvieron en cuenta el factor "Desconocido" del Underground, y aunque el Advisory saliera al cabo de 6 meses, seguro que alguien lo descubrió antes y lo ha estado usando durante todo este tiempo, todo porque M$ no quiso perder tiempo en arreglar su fallo...

Por si todo esto fuera poco, hay que tener en cuenta que el Internet Explorer sigue siendo una parte inseparable de nuestro Windows, aunque lo intentemos desinstalar, en realidad lo único que hacemos es borrar los accesos directos del escritorio y accesos rápidos que tengamos puestos por el sistema. Todo el "cuerpo" del programa sigue estando en nuestro disco duro. Es más, si estamos en "MiPC" y ponemos una web en la barra de direcciones, nuestro Explorador se nos va a convertir en un Internet Explorer supuestamente borrado con anterioridad. Un simple SpyWare podría abrirnos una web con el código necesario para instar un troyano en nuestra máquina, lo cual no gusta mucho, la verdad.

Pero ya vale de teoría y especulaciones, veamos en que consiste el bug en la realidad, vamos primero a ver como conseguir un entorno Windows bajo cualquier sistema operativo.

Construyendo nuestro sistema de prueba

En este apartado intentaré explicar como instalar una máquina virtual, yo usaré VMWare, vosotros podéis usar cualquier otra aplicación parecida como son: qemu, bohs,... Yo tuve la suerte de poder conseguir un Serial legalmente para el VMWare, si no tenéis esa oportunidad mejor usar alguno de los otros que son libres.

Primero vamos a bajarnos el programa propiamente dicho, bajo cualquier distribución de Linux que se precie, bastará con poner:
$ emerge vmware-workstation (Gentoo)
$ apt-get install vmware-workstation (Debian)
...
O si no tenemos gestor de paquetes o no nos interesa usarlo, siempre podemos ir a la web oficial y bajar el software:
http://www.vmware.com/products/ws/
Una vez tenemos el software descomprimido y compilado ya solo nos faltará configurarlo. Primero ejecutamos el siguiente comando:
/opt/vmware/workstation/bin/vmware-config.pl
Al ejecutar dicho script se nos preguntarán cuatro cosas de configuración. VMWare nos permite configurar el adaptador de red de nuestra Máquina Virtual de 3 modos distintos.

  • Bridged La máquina virtual será como si fuera otra máquina real de la red, tendrá su propia dirección IP y estará acorde con la red del host anfitrión, usándolo como puerta de enlace.

  • NAT La máquina virtual se conectará al host anfitrión en otra subred con distinta IP y teniendo como puerta de enlace el propio host anfitrión. De esta manera conseguimos que nuestra VM (Virtual Machine) este protegida por nuestro host y podamos controlar sus conexiones como si nuestro host fuera el router. Compartimos nuestra IP en la red con la VM, ya que todo el tráfico pasa por nuestro host antes de llegar a la red.

  • Host-only Este modo genera una subred privada entre el host anfitrión y la VM.

Durante las pruebas la VM estará puesta en modo Bridged. Al fin y al cabo, da igual el modo mientras tenga Internet Explorer vulnerable, en este caso. Vale, ahora que ya tenemos configurada nuestra VM, ya podemos arrancarla, primero iniciamos los módulos necesarios, normalmente, después de configurar el VMWare ya se nos auto-inicializan los módulos, pero nunca está de más saber como se hace manualmente, por si acaso:
LynaXa ~ # /etc/init.d/vmware start
 * Starting VMware services:            [ ok ]
 * Virtual machine monitor              [ ok ]
 * Virtual ethernet                     [ ok ]
 * Bridged networking on /dev/vmnet0    [ ok ]

LynaXa ~ #
Seguidamente ejecutamos "vmware" como usuario y ponemos el CD de instalación de Windows XP, aseguraos que el parche para el Internet Explorer no esté aplicado, de lo contrario no seremos capaces de observar el funcionamiento del error y de como se aprovecha (mientras escribo estas líneas, no hay versión del Internet Explorer no-vulnerable). Finalmente le damos a PowerOn e instalamos Windows (ver imagen1). Una vez hecho eso ya tendremos nuestro Sistema Operativo completamente funcional. Para terminar configuraremos la red teniendo en cuenta que está en modo "bridge".
     IP: 192.168.0.3
NetMask: 255.255.255.0
     GW: 192.168.0.2 (Host Anfitrión)
Y a disfrutar de nuestro Windows bajo Linux :)

IMAGEN 1

Comprendiendo el bug

Muy bien ya tenemos nuestro Windows corriendo en condiciones, ahora vamos a entender el bug en profundidad y vamos a comprobar que realmente ocurre lo que se nos dice. Primero echemos un ojo al siguiente advisory de Computer Terrorism:
http://www.computerterrorism.com/research/ie/CT21-11-2005
Aquí podemos leer todo lo relacionado con dicha vulnerabilidad. En el advisory nos cuenta que cuando el Internet Explorer evalúa la siguiente sentencia:
<BODY onload=window()>
Internamente lo que nos ejecuta es la siguiente instrucción:
CALL DWORD [ECX+8]
Lo que significa que llama (CALL) a una función que se encuentra en la posición [ECX+8] (direccionamiento indirecto), según nos cuenta el advisory, ECX en este momento siempre vale 0x006F005B, ¿Por qué debe ser? Luego lo veremos. Así pues, la dirección resultante será:
0x006F005B + 0x08 = 0x006F0063
Según lo que se decía en el primer Advisory, esa era una dirección no inicializada y posiblemente inexistente, en teoría, por eso el programa buscaba la dirección de la función en esa posición y no encontraba nada:
Digamos que como: 0x006f0063 = ?? ?? ?? ??
CALL ?? ?? ?? ?? <- ERROR no tiene ninguna dirección que leer.
Pero resulta que Windows guarda las propiedades de las ventanas (titulo, posición, tamaño....) a partir de la posición 0x00600000, jeje que casualidades por dios!. Una vez sabemos esto deducir lo que hace el exploit no es difícil, "simplemente" inyecta una dirección en esa posición que apunte a la shellcode, o un lugar cercano, de esta manera conseguiremos que en vez de saltar a una dirección no inicializada, saltaremos a una en la que se encontrará un código completamente ejecutable y el programa en vez de hacer un DoS lo que hará será seguir ejecutando lo que le pongamos ahí, en el caso del "proof of concept" de ComputerTerrorism se nos inyecta una shellcode que se encarga de ejecutar una calculadora ("calc.exe").

Esto de leer los advisories esta muy bien, pero vamos a partir de la idea de que no nos fiamos, y queremos comprobarlo por nosotros mismos, así que vamos a hacernos una web simple, para comprobar que el Internet Explorer se nos cuelga, el código lo podemos ver en el listado1.

LISTADO 1

<HTML>
	<TITLE> Test.html </TITLE>
	<BODY onload=window()> </BODY>
</HTML>
Vamos a abrir dicho archivo ("test.html") con el Internet Explorer, en la imagen2 podemos ver como se nos cuelga. Bueno, parece ser que realmente tiene problemas a la hora de cargar esa página. Vamos a ver un poco más en profundidad si realmente salta siempre a la misma dirección, hay que tener en cuenta que este tipo de errores no siempre son causados por los mismos problemas y el comportamiento del programa no tiene porque ser el mismo cada vez.

IMAGEN 2

Debugando Internet Explorer

Para poder realizar el análisis deberemos tener a mano un Debugger, yo he elegido "Olly DBG" por la influencia de Spark (saludos amigo :)), vosotros elegid el que más os guste. Para bajarlo basta con ir a su web oficial:
http://www.ollydbg.de
Una vez dentro, bajamos el archivo que se encuentra en el apartado "Files" que se llama: "Odbg110.zip" que es la última versión (mientras escribo estas líneas). Una vez lo tenemos descomprimido lo ejecutamos, le damos a Open y ponemos el Internet Explorer que normalmente se encuentra en:
C:\Archivos de Programa\Internet Explorer\IEXPLORE.exe
En un momento tendremos todo el código en nuestro debuger, le damos a F9 y empieza a ejecutarse del mismo modo que si hiciéramos "doble-click". Una vez tenemos el Internet Explorer completamente funcional, abrimos el fichero que hemos creado. En el momento que se produzca la llamada, en Olly tendremos lo que podemos ver en la imagen3.

IMAGEN 3


Si nos fijamos vemos que, efectivamente, tal y como decía en el advisory, al ejecutar la instrucción "CALL DWORD PTR DS:[ECX+8]" (el DS - Data Segment - esta implícito en la instrucción, que aparezca o no es solo algo adicional), en ECX tenemos el valor 0x006F005B y como vemos en el recuadro azul, la dirección resultante es: 0x006F0063 que es de donde intenta leer la dirección a la que saltar, pero en vez de eso no encuentra nada válido.

Si le damos con el botón derecho encima del cuadro dónde se vuelca la memoria (inferior izquierdo) y seleccionamos la opción: Go to -> expression, una vez allí introducimos la dirección de la que el Internet Explorer intenta leer y nos saldrá el error que vemos en la imagen4 ¿Cómo va a saber la posición de la función que debe llamar si no la puede leer de 0x006F0063? Anda mira! Si miramos un poco arriba del código vemos lo siguiente:
MOV DWORD ecx, [eax]

IMAGEN 4


Si vamos a la posición de memoria donde apunta eax, veremos que ahí se encuentra la cadena alfanumérica: ".[.o.b.j.e.c.t.]." (los puntos del medio representan bytes nulos, ya que cada carácter en unicode se expresa usando dos bytes en lugar de uno solo 0x0097 = 'a' en unicode, que si lo representamos en ascii byte a byte quedará “.a” ), tal y como podemos ver en la “ampliacion1” que corresponde a un Zoom del valor de “eax” de la imagen3, como se puede observar a continuación del valor pone: UNICODE “[object]” .

AMPLIACIÓN 1


Eso significa que en esa dirección se encuentra esa cadena alfanumérica especificada en Unicode, tal y como ya habíamos visto por nuestros propios medios. Entonces, si cogemos una DWORD (4 bytes) a partir de esa dirección obtendremos precisamente (recordad el LittleEndian):
0x006F005B  = “.[.o”  ( 0x6F='o' y 0x5B='['
Ahora ya sabemos porque siempre se mantiene el valor en ecx :).

Comprendiendo el exploit

Muy bien, ya hemos visto con nuestros propios ojos el problema, ahora veamos que ocurre cuando ejecutamos el "proof of concept" de ComputerTerrorism, para ello repetimos el procedimiento anterior, pero esta vez en vez de abrir el fichero "Test.html" lo que haremos sera entrar en el siguiente enlace:
http://www.computerterrorism.com/research/ie/poc.htm
En esta página podremos elegir el Sistema Operativo para el cual vamos a realizar el test, como en este caso se trata de un Windows XP SP0 pues lo seleccionamos, siempre debugando, por supuesto. Encontrar el método para llenar la memoria y hacer que en prácticamente todos los casos el exploit se ejecute con éxito no es tarea fácil, ahí es donde recae el mérito de los programadores de exploits, implementar buenas técnicas y que sirvan siempre.

Llegados a este punto pueden pasar dos cosas, una es que se ejecute bien el exploit y se arranque una calculadora, y otra opción es que se nos cuelgue el Internet Explorer y no salga nada... No desesperéis, la memoria ya ha sido llenada aunque no se ejecute nada. Lo malo de este error es que depende mucho del uso anterior del sistema, ya que la memoria que se desea modificar no depende sólo del Internet Explorer, depende también del resto de aplicaciones con ventanas de todo el sistema operativo.

Como ya tenemos la memoria llena, en caso de que no se nos haya ejecutada nada, lo que podemos hacer es cerrar el Internet Explorer actual y abrir otro, dentro del mismo Olly. Esta vez abriremos nuestro fichero, el "test.html", y... Magia! Se nos ejecuta la calculadora, el resultado era de esperar, el exploit ha escrito los bytes necesarios en la memoria y ésta no ha sido refrescada. Si desde que hemos ejecutado el exploit, hemos abierto multitud de ventanas seguramente al cargar el “test.html” no funcionará la shellcode y tendremos un DoS igual que la primera vez.

Ahora vamos a probar de acceder de la misma manera que antes a la dirección: 0x006F0063. Veremos como esta vez no falla, nos deja ver lo que hay en ella y lo que aparece es lo que podemos ver en la imagen5, que corresponde a la ampliación del cuadro de volcado de memoria.

IMAGEN 5


Ahora veamos que pasará cuando ejecute el "CALL", vayamos pues a la posición que tenemos en la dirección 0x006F0063 que es: 43 30 70 00, pero como estamos en LittleEndian pues la dirección real es: 0x00703043, veamos que hay en esa dirección (ver imagen6).

IMAGEN 6


Anda... si nos sale lo mismo... Mmm... esto no parece tener lógica, vayamos a ver el código fuente del exploit que nos servirá de pequeña guia:
http://www.frsirt.com/exploits/20051121.IEWindow0day.php
El exploit esta dividido en varias páginas .htm, todas ellas tienen su propia función. Claro que hay una que nos llama especialmente la atención que es la de "fillmem.htm", veamos que hace para rellenar la memoria:
//
// Address called by the bug (also serves as slide code)
//

for (spearson=1 ; spearson <=500 ; spearson++)
{
eip = eip + unescape("%u7030%u4300")
}
Je je, esto ya nos lo deja algo más claro, utiliza una dirección que también sirve como código. Lo normal hubiera sido rellenarla usando NOPs ( NoOperation - 0x90), pero entonces al hacer el CALL saltaríamos a la posición "0x90909090" y nos iríamos fuera de los límites. Entonces la dirección "0x00703043" salta dentro de lo permitido y además nos sirve como instrucción, ya que no es mas que un "xor" seguido de un "inc ebx", ambas operaciones bastante rápidas e inocuas, así conseguimos llegar al código en cuestión sin que nos salte el programa provocando un DoS, va ejecutando “xor” e “inc ebx” hasta llegar a la “prep_shellcode”..

Así pues el exploit nos llena la memoria de la siguiente manera:

  • Rellena con DWORDS de: 43 30 70 00 (Dirección y Código a la vez).
  • Pone la Shellcode para llamar a la Calculadora (ver imagen7).

IMAGEN 7

(fillmem = fillmem + prep_shellcode + shellcode)
Como vemos al final concatena todas las cadenas, la "prep_shellcode" se encarga de copiar la shellcode propiamente dicha a donde se encontraba la cadena alfanumérica ".[.o.b.j.e.c.t.].", de esta manera tenemos menos posibilidades de que sea modificada, porque la dirección 0x007C22C3 (en este caso) es la que se usa para las ventanas, y en caso de abrir muchas, esta quedaría modificada.

Si comparamos los primeros bytes que vemos en la imagen7, veremos que corresponden con los bytes que salen en el exploit de ComputerTerrorism, en la cadena "prep_shellcode".

Conclusión

Hasta aquí el artículo de este mes, espero que hayáis sido capaces de entender algo de lo que intentaba transmitir con mi mala expresión. Lo curioso de este error es que es consecuencia directa de las pocas ganas de Microsoft por ayudar a sus clientes a menos que sea estrictamente necesario (como ha pasado ahora).

Gracias a __simkin de www.badchecksum.com por ayudarme con el análisis del bug. Desde aquí os animo a que probéis varios sistemas operativos ahora que conocéis las herramientas para construir máquinas virtuales, si no las conocíais ya, claro.

Por cierto, ya ha salido otro bug de Internet Explorer / Windows, antes de que terminara el articulo, ahí lo tenéis:
http://www.frsirt.com/english/advisories/2005/3086
Esto es un no parar jeje.

EOF