jueves, 11 de junio de 2009

Solución reto Pwtent Pwnables 100 Defcon 17 Quals

Que nombres mas raros Dios Santo. El pasado finde 6,7 de Junio se realizó una clasificación para asistir a la competición CTF, Capture The Flag, de la Defcon 17, en Las Vegas. Consiste en un montón de retos/pruebas/desafíos informáticos que hay que superar en equipo y así los 10 primeros van a Las Vegas para ver quien es el mejor del mundo. El nivel , altísimo. Suena guay, ¿verdad?

Mi querido Pedro Laguna nos invito a que nos apuntásemos con él a ver que se movía por ahí. Así que ahí estábamos el sábado 6 de madrugada Pedro, Manu (un compañero) y yo cagándonos en lo mal que funcionaba ese applet que era el panel de puntuación.

DefconFinal

Las pruebas eran muy raras y no se daban demasiadas indicaciones sobre como superarlas, es parte del juego ;)

Yo me tope con una especie de ejecutable que pedía un serial, ummm eso sonaba bien, al menos podía abrirlo con OllyDbg e intentar hallar un serial. Aquí os lo cuelgo A continuación os cuento como lo resolví.

Nada mas abrirlo veo una consola que no hace nada, mas que dejar un puerto a la escucha:

TCP 0.0.0.0:5832 0.0.0.0:0 LISTENING 1976

Me conecto con netcat y me pide un serial ¿?

image

Perfecto, lo abro con el OllyDbg, busco las cadenas referenciadas en el código:

image

Ahí está la cadena “Well done!” la cual en teoría tiene que aparecer cuando introduzca el serial bueno. Perfecto: Follow in Disassembler:

image

Mira justo un par de instrucciones antes de mostrar ese mensaje se hace una comparación de cadenas, strcmp, guay, pongo un breakpoint allí, veo lo que se está comparando y reto solucionado.

Pero no funciona…algo raro pasa, pongo otro breakpoint cuando directamente me muestra el mensaje de serial erróneo y tampoco se detiene.

Así que voy ejecutándolo desde el principio poco a poco para ver si tiene alguna protección o que… Veo una llamada a accept, me conecto con netcat y entonces me encuentro que llega a esta función:

image

Aja! Está creando un nuevo proceso por cada petición, es ese proceso el encargado de verificar si nuestro serial es correcto o no. Así que necesito abrir con OllyDbg el nuevo proceso, el proceso hijo, no este.

Resumen: al ejecutar el exe este se queda a la escucha en el puerto 5832 y por cada nueva conexión crea un proceso hijo que se encarga de recibir y verificar el serial que introducimos. Así que era normal que cuando ponía breakpoints en el proceso inicial no se detuvieran ahí nunca.

Tuve algunos problema iniciales para hacer Attach con OllyDbg sobre el proceso hijo, pero tras pensarlo un rato (dormir), me doy cuenta de que es de lo mas fácil, no hay que hacer nada :) Simplemente ejecutar el programa inicial, conectarnos por netcat y entonces hacer Attach sobre el proceso hijo.

image

En estos momentos el programa está esperando a que introduzcamos texto desde el netcat, así que pongo un breakpoint en recv, escribo algo en la consola donde tengo el netcat a la espera y llego a esta zona de código:

image

Podemos ver dos bucles donde se reciben bytes hasta encontrar el salto de linea, \n, y entonces se comparan ambos.

image

Así que en realidad se reciben dos líneas, claro! Ya decía yo que eso de dar dos veces al enter no era muy normal :) Estas dos líneas se comparan sin mas ¿? Aquí hay truco…vamos a a probar:

image

Uy que raro…es entonces cuando recapacito, ¿pero en serio que nos piden un serial? Pues no, lo que nos piden es que les petemos, si es que hay que leer el enunciado detenidamente antes de lanzarse a abrir el OllyDbg en cuanto vemos un exe…

image

Efectivamente peta, ¿será un Stack Buffer Overflow? Vemos donde está guardando el contenido de la primera línea introducida:

image

Guarda el contenido de la primera línea en 22FDC0 (fijaos que esta es la segunda vez que pasa por bucle, en la primera yo no estaba ni “Attacheado” al proceso).

Ahora mirad en el contenido de la pila:

image

Uhhh bonito Stack Buffer Overflow. Escribiendo 64 bytes sobrescribimos la dirección de retorno de la función actual haciendo que cuando termine salte a donde queramos, esto pinta bien. Ahora solo falta un sitio donde meter las instrucciones que queremos que se ejecuten, la shellcode.

El primer bucle tiene una limitación:

image

No deja escribir mas de 64 bytes, que casualidad ¿no? Pero teníamos dos bucles, el de la primera y el de la segunda línea.

El segundo bucle se guarda en la dirección 004099F8:

image

Y permite escribir todos los bytes que queramos hasta encontrar el salto de línea, así que nos sirve perfectamente para meter ahí la shellcode. Pero hay que tener cuidado, fijaos de nuevo en la situación de la pila en el primer bucle cuando íbamos a sobrescribir el valor de retorno, la dirección 0022FDEC (local.3) contiene el valor 004099F8:

image

Si nuestro primer buffer sobrescribe ese valor el segundo bucle intentara escribir donde le hallamos dicho. A nosotros no nos interesa modificar ese valor, queremos dejarle como está, sobrescribir la dirección de retorno y escribir en el segundo buffer la shellcode.

Voy probando diferentes valores hasta dar con la primera línea a introducir:

image

64 bytes que dejan intacta la variable utilizada por el segundo buffer y que sobrescriben la dirección de retorno para que al finalizar la función el programa salte al segundo buffer donde meteremos directamente la shellcode.

Para la shellcode use la página de metasploit, que poco h4x0r soy, ¿no?:

image

Solo hay que tener cuidado con que la shellcode no haga uso del carácter de salto de línea, 0x0A ya que nuestra función busca ese carácter para buscar el fin de las distintas líneas.

Desde la página de retos se suministraba esta dirección para ser atacada:

pwn2.ddtek.biz

Probé con varias shellcodes, hasta probar una para FreeBSD que me funcionó perfectamente.

nc pwn2.ddtek.biz 5832 <>

Argumento pasado:

image

La shellcode utilizada era una bind shell, vamos que deja un puerto a la escucha en el puerto 6969, pruebo y...eureka:

nc pwn2.ddtek.biz 6969 adsfadsf adsfadsf: not found pwd /usr/home/cabernet ls cabernet.exe key start_server.sh cat key Hacker Joe Where Are You?

Esta última cadena era la necesaria para superar el reto, 100 puntos. Al finalizar el maratón 800 puntos logró alcanzar mi equipo, McLoving, que buen nombre :D

Los Sexy pandas, un gran equipo español, terminaron terceros. Que genios. Suerte en Las Vegas fieras!

Si queréis aprender mas sobre el tema: Smashing The Stack For Fun And Profit