HackIt! es el concurso de seguridad informática de la Euskal Encounter en el que compiten más de 80 equipos y gana w0per 😉 El resto de los equipos jugamos en otra liga por intentar quedar en segundo o tercer puesto. Este año en DL conseguimos el objetivo, tras andar como el gato y el ratón con Navarparty. Grandes estos navarros!
Realmente el HackIt! consta de 2 secciones, el propiamente llamado HackIt, +-10 retos donde en general se requieren amplios conocimientos técnicos/ informáticos para pasar más allá de la prueba 4) y SolveIt, +-8 retos, donde se plantean pruebas con menor componente técnico y más ingredientes de ingenio.
Esta edición del HackIt, como las últimas (2012, 2011, 2010) ha sido organizada por @marcan y está desde hace unos días online. Siempre estaré agradecido a su labor (este año. ademaś, le ha dedicado un toque especial generando banners de «patrocinadores», que servían como ayuda/pista en algún nivel :-P) De hecho, es la prueba que me sigue haciendo perder el sueño y dedicar 3 días a «jugar».
Como cada año, al terminar el HackIt! me gusta retomar algunas de las pruebas, para comentarlas con el resto de compañeros, y aprender de los demás. Nuestra forma de solucionar puede no ser la óptima, ni siquiera la forma más ortodoxa. Incluso en una de las pruebas (Trollencio!) fue pura chiripa, como veréis. Por ello, me gustaría que los grupos o individuos que se pasaron dichas pruebas (antes o ahora, post-mortem) comentaran sus impresiones en este post.
Comencemos con la primera. Hack It 1: WTF!»#$%&()~ . Analizando el código vemos que se carga un fichero Javascript desde la ruta /hackit/1/static/checkpw.js . ¿Y qué tenemos ahí? Un monstruo como el de la figura de la izquierda. Fíjense en el scroll vertical 🙂 Se trata de código Javascript codificado en un alfabeto con sólo 8 caracteres : ()[]{}!+ Una especie de codificación BrainFuck, pero en Javascript. Útil para intentar saltarse detectores de intrusión, reglas de firewall, etc… porque a ver quién es el majo que interpreta eso 😛
En fin, si abrimos una consola Javascript en Chrome y seguimos el artículo del autor de esta monstruosidad (o belleza, según cómo se mire), empezaremos a entenderlo. La idea es conseguir interpretar cualquier instrucción Javascript usando sólo ()[]{}+- . Lo primero será saber cómo obtener los caracteres alfanuméricos: a-z0-9, pues con ellos ya tendremos un buen camino recorrido.
Si ejecutamos +[] , obtendremos un 0 (casting de un array vacío a integer). Con ![] un false (casting a boolean de un array vacío). Si negamos ese valor !![] obtendremos un true, y al convertirlo a entero +!![], un 1. Con estos 2 números y el operador de suma, podremos obtener cualquier otro dígito (con algunos trucos que muestra el autor, esto se puede simplificar, para no tener ristras enormes cuando necesitamos un numero como 128). ¿Y las letras? Bueno, empecemos con algo más sencillo. Si esto es un array [] (vacío), y esto devuelve un 0 +[], entonces, ¿qué ocurrirá si intentamos acceder a la primera posición (0) de un array vacío? [][+[]] . Que obtendremos la cadena «undefined». ¿Y si hacemos un casting de un objeto a número? +{} . Javascript nos dirá que eso no es posible con la cadena «NaN» (not a number). Accediendo a los caracteres de esas cadenas (indexándolas como arrays de caracteres), tendremos ya unas cuantas letras (u, n, d, e, f, i , a) . Siguiendo este mismo truco el autor explica cómo conseguir todo el alfabeto. Ahora nos hace falta una función que, dado como parámetro un string, evalúe dicho string como si el nombre de una función se tratara. Este trabalenguas no es sino para introducir la función «Function», que hace precisamente eso:
Function(«alert(1)»)()
construirá la función alert() a partir de la cadena pasada como parámetro (en concreto, construirá alert(1) y la ejecutará, mostrando ese 1 en pantalla). Este post en castellano nos ayudó a terminar de entender cómo funcionaba todo, os lo recomiendo. En definitiva, es posible ejecutar en el navegador cualquier función a partir de un churro de caracteres ()[]{}+ . En su día, el maligno ya nos habló de este experimento, pero no le hice demasiado caso, hasta hoy 🙂
Bien, ¿y cómo pasarnos entonces este primer nivel? Realmente no hace falta entender nada de lo que he explicado hasta ahora 😛 , porque se puede resolver «de chiripa». La cuestión es que si conseguimos ejecutar checkpw.js en un navegador nos saltará un alert con el password. Ojo! Para que el brainfuck funcione, necesita acceder a la letra «p» de alguna forma, y el artículo indica que ésto es posible si el script se carga desde una localización http://loquesea.com (la p la sacará del nombre del protocolo, httP ) . Así que no vale con cargar el script con protocolo file:// o directamente desde la consola del navegador, como intentamos mil veces 🙂