Hoy, vamos a ver uno de los ejercicios de ciberseguridad del curso que tiene CORELAN. Vamos con el ejercicio 3, el servidor versión Kolibri v 2.0 :

Creamos una página inicial “index.htm” con el contenido que más le guste a uno y le cambiamos la ruta, donde se encuentre ese index.

Y comprobamos que al darle al botón “Start”, y que inicia correctamente, se ve en nuestro navegador, por ejemplo el Google Chrome.

Como tampoco queremos reinventar la rueda y sabemos que es vulnerable, buscamos por donde irán los tiros…

Vale así que el método HEAD tiene problemas, jeje. Vamos que peta por algún sitio.

Y además hay publicado un exploit para el metasploit:

Vale, pero ¿queremos ir a tiro hecho? ¡¡¡Claro que no!!! Nos gusta complicarnos y encontrar donde peta. ¿Y cómo buscarlo? Fuzzeando que es gerundio :P

Creo un sencillo script en Perl, ya sabéis que me encanta y para estas cosas es lo más rápido (para mí :P), pero en la máquina de Corelan no está el Active Perl instalado. Como no quiero tocarla mucho, utilizo un programa mío para redireccionar las peticiones desde mi PC host a la virtual de Corelan, ya que este servicio corre en la dirección localhost:

Cambiamos el adaptador de red:

Y abrimos una regla para que en el puerto 8081 de nuestra máquina vaya hacia el de la virtual.

$ nmap -sT -p8081 localhost

Starting Nmap 6.47 ( http://nmap.org ) at 2015-06-10 10:13 CESTNmap scan report for localhost (127.0.0.1)Host is up (0.000028s latency).PORT     STATE SERVICE8081/tcp open  blackice-icecap

Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds

Bien, parece que funciona:

A lo que iba, creo el script en Perl sencillito, sin hilos ni nada:

Este es el aspecto que tendría una vez se está ejecutando el script:

Y catapum!

Veamos los detalles:

Bueno, de esta forma poca cosa, ¿qué nos dirá el debugger?

Parece que el fallo viene cuando le pasas unas 215 ó 216 A…. seguramente el primero, así que lo compruebo.

Lo comprobamos:

Y efectivamente, peta al enviarle 215 A con el método HEAD, pero con ese tamaño no controlamos el EIP ni nada….

Lo abrimos con el Inmunity:

configuramos mona.py:

Creo este otro script y lo lanzo:

Vale, así que el EIP lo controlaré gracias a la zona en donde metí las C (43434343).

A mí el moma este no me guarda lo que necesito :P así que voy a explotarlo como antaño, jeje.

Creo el script con un patrón creado con el patter_create:

Y lo mismo:

Pufff!  Ese EIP parece una dirección de memoria, no algo que yo le haya metido en ese string… así que parece que aquí el tamaño importa…. Lo voy a acortar, lo dejaré en unos 600 en total.

El EIP es: 32724131 -> 2rA1 -> Little Endian -> 1Ar2

Vale, nosotros controlamos el servidor… pero ¿y si no tuviésemos ese control?

Nos la tenemos que jugar y jugar significa utilizar direcciones estándar para un Sistema Operativo concreto, en este caso un Windows XP SP3 (de la máquina Virtual de Análisis de Malware, no la de Corelan). Como veremos en el ejercicio 2, localicé un JMP ESP en kernel32 y utilizaré la misma:

Vale, entonces nuestro primer exploit para ejecutar la calculadora de Windows y que utilicé en el ejercicio 2 sería:

Vamos muy parecido la forma de explotarlo en remoto, de esta forma pero creo que no funcionará…

Pero esto qué es!!! Normal, hay que modificar el script original. Lo sé, juega con el “pack”, blah, blah, blah! Pero yo soy de la opinión de si algo no te gusta, cámbialo! No vayas hasta el final con algo que no te gusta sólo porque sí, cámbialo, mejóralo!

Lo probamos, no hay nada como usar sockets :P

Pero no hace nada… cachis. Voy a ver la dirección de memoria que puse… pues no está L Normal, no tiene porqué tener las mismas direcciones en máquinas distintas, ese es uno de los problemas más comunes a la hora de programar un exploit en la que no calculas la dirección en el mismo. Primer zas en toda la boca, como decía alguno! jeje

La modifico por una de las existentes:

Calc.exe, lo vemos… pero… nop ¿Qué ha pasado?

Eh! Esa no era mi dirección… ¿os acordáis lo que conté al principio del tamaño importa?

Además si nos fijamos en los registros:

Estoy saltando a una dirección en la que antes, hay código. Parece que eso no funciona…. Pensemos un poco… parece que podríamos controlar ebp, salta allí….

Vale, si le metemos la salida del pattern_create:

Así que esto debería funcionar:

Por más que pruebo no funciona…. No será por esto?

Nueva shellcode:

Me estoy volviendo loco para calcular como saltar al sitio, estoy desanimado, así que lo dejo para el día siguiente :-D Eso sí, dándole vueltas en la cabeza.

Un poco de ficción: llega la tarde y mi hija me dice….

Hija: papá ponme la peli de los boxtrolls, por favor (Es muy educada)

Yo: Claro, ahora mismo. - Conecto el disco duro y se la pongo –

Al rato…

Hija: has visto, papá, los malos quieren “cazar a Eggs”.

Yo: ¿Cómo? ¿qué has dicho?

Hija: que los malos quieren cazar a Eggs.

Este es Eggs:

Yo: Uhmmmm! Gracias, hija, me has dado una idea :P

Fin del poco de ficción.

Hablemos del mineralismo y de los “eggs hunters”

Ó de esta técnica utilizada por los exploiters…

Supongamos que podemos poner en la memoria un string, como “egg”, “FreeKevin”, o lo que más os guste, pudiésemos buscarlo y al encontrarlo, saber donde ejecutar la shellcode que nosotros hemos puesto a continuación…

Supongamos que como decía que el tamaño importa, solamente podemos poner un trocito de código aquí, otro allí….. que el primero busque el segundo (ahí no tenemos problemas de espacio) y ejecutar lo que queramos….

El flujo de ejecución sería algo similar a esto:

  1. En el primer buffer (limitado) introducimos nuestro cazador de huevos (egg hunter).
  2. Una vez controlamos el EIP (nuestro caso) apuntamos al segmento de memoria anterior para poder ejecutar el egghunter.
  3. El egghunter busca nuestra shellcode en toda la memoria (al ser un proceso proceso cíclico, consumirá recursos en el PC, se quedará como “pensando”, es lo que siempre me dicen cuando parece que el proceso está cuasi colgado :P).
  4. El EIP se sobreescribirá con la nueva dirección de memoria de la shellcode que haya encontrado y la ejecutará.

Sería esto:

Parece parte de la historia de ficción de los boxtrolls, pero no, esto es real al 100% :P

Al lío. Volvemos a calcularlo todo, esta vez con otro pensamiento de explotación en la mente, el ejercicio 3 es diferente, como nosotros, jeje.

Gracias a Alberto, que me envió un tutorial sobre el funcionamiento del Mona :-D

Sacamos el ESP, aunque deberían funcionar cualquiera, a mí me funcionó con la que está subrayada:

Ejecutamos el comando para que nos guarde el “cazador de huevos”, como suena:

Utiliza NTAccessCheckAndAuditAlarm:

Todo esto viene en los siguientes enlaces explicado:

  1. Egghunt Shellcode
  2. Heap
  3. Heap Only Egg Hunter

Leedlo, si no lo habéis hecho ya :P

Consideraciones para que todo esto funcione:

  • La palabra que busquemos debería ser única (cómo haya repes, como los cromos de fútbol cuando solamente te quedaban unos poco, fallará)
  • Es necesario definir la etiqueta de 4 bytes en el interior del egg hunter, y hacerlo 2 veces (2 veces después de cada uno, en total 8 bytes) antes de nuestra Shellcode que queremos explotar.
  • Hay varias técnicas para buscar en memoria y no todas tienen porqué funcionarte. (NTAccessCheckAndAuditAlarm es la que he utilizado y funciona, viene explicado aquí ).
  • Cada técnica es diferente y requieren un espacio determinado disponible para introducir nuestro código del egg hunter.

Vale, con todo esto ya tendríamos preparado el exploit, solamente hay que comprobar que funciona:

Y el resultado: FUNCIONA !!!

Así que hemos dado con la forma de explotar la vulnerabilidad en el servidor web Kolibri v2.0.

¿Nos arriesgamos con una Shell? La generamos con Metasploit: Shell_bind_tcp en el puerto 4444

La copiamos a nuestro exploit:

Lo ejecutamos y….

Shell al canto.

Nos conectamos para ver el resultado:

Estamos en el directorio del servidor vulnerable.

Pues nada, espero que os guste, yo me lo he pasado muy bien buscando y explotando la vulnerabilidad ;-)