HackIt! 2013. Level 3

2013-08-05 05_50_39-Hackit - Main - IBM NotesHack It 3: Post-It v.1989. Así se titula la prueba. El nivel tiene enlazado un fichero .nsf , es decir, una aplicación Lotus Notes (ahora se llama IBM Notes).  La extensión NSF es un acrónimo de Notes Storage Facility. En estos ficheros se guardan tanto el diseño de la aplicación como los datos asociados. Los datos son documentos  (llamados «notes») que se muestran al abrir el fichero .nsf. Normalmente las aplicaciones se acceden a través de un servidor (Lotus Domino) pero, tal y como se demuestra en este nivel, también pueden abrirse en modo local. No me extenderé en hablar sobre el uso de Lotus IBM Notes, ya tuve en otra vida una experiencia con esta bestia y es por ello que conocía el modo «Diseño» de Notes. En este modo se pueden editar las acciones (normalmente programadas en LotusScript) que se ejecutarán al abrir o cerrar la base de datos, al abrir un documento, periódicamente…

Lo más importante es saber cómo pasar este nivel. Lo primero (y creedme, lo más complicado) es conseguir instalar el cliente Notes. Hay una versión llamada Open Social (IBM Notes 9.0), descargable en modo trial para Linux, MacOSX y Windows. La versión para Linux es nativa… pero me costó horrores instalarla (problemas de dependencias con libgnomeprint, libbonobo, libgnome-desktop… En fin, una vez instalada, abrimos la aplicación password.nsf que nos enlazan en este nivel y vemo que muestra una aplicación con 2 columnas: fecha y datos. Además, salta un mensaje indicando que «Your word for today is:  una ristra de carácteres no imprimibles 🙂

Así que entramos en modo diseño desde Actions / View Options / Design… y aquí es donde nos damos cuenta de que la versión de Notes para Linux está sin terminar :-O No tiene modo «Design» (o yo no lo he encontrado). En fin… probemos con la versión Windows. Anda, en esta sí que está el modo diseño. Lo abrimos y vemos que el evento «postopen» desencadena la ejecución de un script que básicamente encadena los números de la segunda columna, tratándolos como carácteres ASCII y muestra el mensaje indicado. Ok, ¿pero de dónde salen estos números? Si examinamos el diseño de esa columna veremos un código como el siguiente:

@Modulo((Data*123);256);
REM{FIXME. 123 IS WRONG};

Es decir, cada número es igual a calcular el módulo 256 de la fecha de su izquierda (interpretada como número), multiplicada por 123. El problema es que 123 no es el número correcto… ¿qué podemos hacer?
1) Apuntar los números de las fechas en crudo (dejando por ejemplo «Data» como valor a imprimir, sin módulos ni gaitas)
2) Una vez que tengamos la ristra de números en crudo, crear un programa que pruebe todas las opciones posibles de X tales que @Modulo((Data*X);256); nos arroje un mensaje con sentido.

Piece of cake! Y así llegamos al temido «Trollencio», level 4, que nos tuvo a casi todos los grupos epatados (que no empatados 😉

HackIt!2013: Level 2 (y II)

Según esta web, la contraseña para acceder a un repo Maven puede ser generada a partir de una contraseña maestra así:

$ mvn --encrypt-master-password Oone3vei
{wsJL3n5FpasHjLctHj2HuHIoc8DBGtpIWp2bc40vkBU=}
$ mvn --encrypt-password Thu8luuV
{uD995k4e9YEHeRC0LWz4jIEv/kAt5Mt/up3X62RoJIs=}

Es decir, si la contraseña maestra fuera Oone3vei, se generaría esto: {wsJL3n5FpasHjLctHj2HuHIoc8DBGtpIWp2bc40vkBU=}, lo que deberíamos guardar en el fichero settings-security.xml. A partir de esa contraseña maestra, podremos generar otras (¿para distintos repos Maven?¿para distintos usuarios del mismo repo?). En el ejemplo, tomando el password Thu8luuV, y a partir de la contraseña maestra, se generará el pass
{uD995k4e9YEHeRC0LWz4jIEv/kAt5Mt/up3X62RoJIs=}, que se guardará en setttings.xml.

Teniendo ambos ficheros, ¿es posible obtener el string que se usó como password y que generó el pass cifrado de settings.xml? Sí, usando el siguiente código Java:

import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.cipher.PlexusCipher;
import org.sonatype.plexus.components.cipher.PlexusCipherException;
 
public class Prueba {
 
	public static void main(String[] args) {
		PlexusCipher cipher;
		try {
			cipher = new DefaultPlexusCipher();
			String masterPw = cipher.decrypt("CO0lvhBKZAMHPlguhfnJAWS6zgpLe5BoQO/AwhVwJX/4UEPxkeqBjVKAq+yK37ft", "settings.security");
		String appPw = cipher.decrypt("9FANUCx4GboHlC12nghO/i+oVV4RRSw1grsm6or+KiYJ2tSEAG5BSWAgq1QCmejj9Q4kpppWwU8caX2PioJD1w==", masterPw);
		System.out.println(appPw);
 
	} catch (PlexusCipherException e) {
		e.printStackTrace();
	} 
	}
 
}

Por cierto, necesitarás instalar los paquetes .jar de Plexus Cipher para poder compilar ese código:

$ sudo apt-get install libplexus-cipher-java

Hackit!2013 : Level 2

Nos dicen que tenemos que recuperar el contenido de un archivo .rar que han protegido con un password. Dentro de ese archivo parece ser que podremos encontrar información sobre un repositorio de código (al que accederemos con una contraseña, que tendremos que recuperar). Pero el primer paso será obtener el password que protege el archivo RAR. Lo único que se sabe es que ese password cumple lo siguiente:

<? echo sha1(md5($password)); ?>
77134aa1b02b61cd841d2a81bf64796a31234e28

Teóricamente las funciones de resumen criptográfico (o funciones hash) md5 y sha1 no tienen función inversa. O dicho de otro modo, existe md5(X) para todo X, pero no existe una función Y tal que Y(md5(x))=x. Para colmo de males, el resultado de md5(x) se ha pasado por la función sha1 : sha1(md5(x)). Entonces, ¿qué podemos hacer? Bueno, supongamos que alguien decide generar una tabla para «todo» X, almacenando los resultados. Algo como md5(«a») –> guardar, md5(«aa»)–>guardar, md5(«aaa») –> guardar, md5(«aab»)–> guardar…. etc. Guardar todo eso puede ser muy costoso, sobre todo si la longitud de X empieza a crecer y además, combinamos letras (mayúsculas y minúsculas), números y caracteres no alfanuméricos. Hay «trucos» para no tener que guardarlo todo (ver Rainbow Tables), pero en general, es inviable llegar más allá de passwords de más de 8 o 9 caracteres si tratamos con pass que contienen todos esos símnbolos (Ophcrack guarda esas tablas.. ojito, habamos de ficheros de entre 500GB y 2TB 🙂

¿Y nos tenemos que descargar esos mastodontes sólo para probar? No. Además, los enlaces que indico no sirven para el algoritmo sha1… Vale, ¿entonces qué? Bueno, hay otros sitios web que nos permiten pasarle un hash sha1 o md5 para ver si están indexados en sus bases de datos. Crackstation.net es una de esas webs 😉 Y qué casualidad, tienen ese pass indexado… Una vez recuperado, procederemos a descomprimir el .rar. Veremos que hay un directorio .m2, con 2 archivos: settings.xml y settings-security.xml. Son 2 ficheros que se usan para acceder a un repositorio de código Maven… El 2º guarda una contraseña maestra, a partir de la cual se ha generado la que aparece en settings.xml. ¿Hay alguna forma de, teniendo la contraseña maestra, saber cuál es la palabra o frase que se cifró para obtener la contraseña de settings.xml? Por supuesto, ése será nuestro siguiente paso…

HackIt! 2013

Selection_421HackIt! 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.

Selection_423Comencemos 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.

Selection_424Si 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 🙂

Nola instalatu Xuxen zuzentzaile ortografikoa LibreOffice 4-n

Gaur bertan, @asiersar -en txio baten bidez, LibreOffice 4.0-rekin bateragarria den Xuxen zuzentzaile ortografikoaren bertsio berri bat atera dutela ikusi dut. Berez, bertsio berria uztailaren 19tik dago kalean, baina tira, ez nuen inon ikusi honen berri.

Bere instalazioa eta erabilera oso errazak dira. Lehendabizi,  XUXENIV-LO4.oxt fixategia hemendik jaitsi. Ondoren, LibreOffice ireki eta Tresnak / Hedapenen kudeatzailea ireki (Tools / Extensions manager).  Ondoren, «Gehitu..» (Add..) botoian sakatu, jaitsi berri duzun .oxt fixategia hautatu, leihoa itxi eta LibreOffice berrabiarazi.

Extension Manager_403Orain, euskaraz idatzitako testu bat idazterakoan, gogoratu, euskaraz (Basque) dagoela esan behar diozula Writer aplikazioari (defektuz ez baduzu horrela konfiguratu). Adibidez, nire bertsioan besterik ezeko konfigurazioan, ingelera da lehenetsitako hizkuntza. Beraz, testua idatzi, Ctrl-A (dena hautatu) sakatu, eta beheko-aldean dagoen hizkuntzen leihotxoan «Basque» aukeratu.

Workspace 1_404

 

Bukatzeko, gaizki idatzitako hitzak gorriz azpimarratuko dira. Eskubiko botoia sakatu baten gainean eta proposatutako zuzenketen artean bat hautatu. Testu osoa zuzentzea ere badago: F7 tekla sakatu eta zuzenketak egiteko leiho bat irekiko zaizu. Bertan, banan-banan, oso modu erosoan, zuzendu ditzakezu gaizki idatzitako hitz guztiak.

Spelling and Grammar: Basque_406