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’2012, solucionario. Level 3.

Descargamos el fichero enlazado y vemos que es un zip con ficheros binarios .class (Java) dentro:

$ unzip jkhil.zip 
Archive:  jkhil.zip
   creating: org/
   creating: org/euskal/
   creating: org/euskal/hackit/
   creating: org/euskal/hackit/crypt/
  inflating: org/euskal/hackit/crypt/CryptUtil.class  
  inflating: org/euskal/hackit/PasswordRevealer.class  
  inflating: org/euskal/hackit/FileClassLoader.class  
  inflating: org/euskal/hackit/trololo.clazz

Vamos a ejecutar el que más llama la atención:

$ java org.euskal.hackit.PasswordRevealer
Exception in thread "main" java.lang.VerifyError: Bad local variable type in method org.euskal.hackit.trololo.damagedMethod()I at offset 7
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2404)
	at java.lang.Class.getConstructor0(Class.java:2714)
	at java.lang.Class.newInstance0(Class.java:343)
	at java.lang.Class.newInstance(Class.java:325)
	at org.euskal.hackit.PasswordRevealer.main(PasswordRevealer.java:23)

¡Anda!, un método que se llama damagedMethod()… con un tipo de datos de variable local incorrecto (menudo binario nos ha «regalado» cymo, el autor de este level 😉

Curiosamente, al ejecutar el .class anterior se ha creado el fichero trololo.clazz.dec (deciphered?) :

$ ls -alt org/euskal/hackit/
total 28
drwxr-xr-x 3 juanan juanan 4096 Sep 18 00:24 .
-rw-rw-r-- 1 juanan juanan 2320 Sep 18 00:24 trololo.clazz.dec
-rw-r--r-- 1 juanan juanan 1672 Jul 19 19:04 PasswordRevealer.class
-rw-r--r-- 1 juanan juanan 3101 Jul 19 18:57 FileClassLoader.class
-rw-r--r-- 1 juanan juanan 2320 Jul 19 18:53 trololo.clazz
drwxr-xr-x 2 juanan juanan 4096 Jul 19 14:53 crypt
drwxr-xr-x 3 juanan juanan 4096 Jul 19 13:59 ..

Antes de seguir investigando ese fichero, ¿qué ocurriría si le decimos a la máquina virtual Java que no verifique el bytecode del .class anterior? (la idea sería saltarse la excepción java.lang.VerifyError de algún modo):

$ java -noverify org.euskal.hackit.PasswordRevealer
Exception in thread "main" java.lang.SecurityException: Can't run unmannaged code. System error: 0x1337
	at org.euskal.hackit.PasswordRevealer.main(PasswordRevealer.java:20)

Pues no le ha gustado…

Ahora no sé si el camino que seguimos en mi grupo (kudos to @ochoto por ser el que rompió este nivel) es el que el autor del level pensó, pero a nosotros nos funcionó O:-)

Estos son los pasos: renombrar el trololo.clazz.dec a trololo.class y crear una clase que lo use:

 
// guardarlo en un fichero dl.java en /tmp
// compilarlo con javac dl.java
 
import org.euskal.hackit.trololo;
 
public class dl {
	public static void main(String args[]) {
		try {
			trololo t = new trololo();
 
		}
		catch(java.lang.VerifyError ve) {
                          System.err.println("Errooooooor....");
		}
	}
}

Si ejecutamos el main anterior, veremos que salta la excepcion «VerifyError». Por lo que vamos a volver a intentar la ejecución sin verificación del bytecode con la opción -noverify (ver documentación de esta opción en la especificación oficial de la máquina virtual Java):

$ cd /tmp
$ java -noverify dl
Mr. Trololo was born ...
Please enter: Year: >

Premio! 🙂 Buscamos los datos que nos piden y tendremos acceso al siguiente nivel. Si algún grupo (o el autor del level) siguió otro camino para resolver, le agradecería que añadiera sus comentarios. Nos vemos en el level 4.

Tip: ¿tu versión de Java está actualizada?

Tienes la versión 1.6.0_22 del JRE de Java. ¿Es la última? ¿Cómo saberlo?
Fácil, sólo tienes que visitar esta página de java.com. Un applet Java detectará tu versión y te indicará si estás trabajando con la última versión o no. En caso negativo te dará un enlace para descargar las versión más reciente (en este caso la 1.6.0_23)

Sinadura 1.3 publica el código fuente y manual técnico

David Olmos (Zylk.net) me envió a finales de año información sobre el código fuente de la versión 1.3 de Sinadura, la aplicación libre para el uso de firma digital en Linux (en concreto, para la firma digital de documentos PDF).

«Acabamos de publicar las fuentes de la versión 1.3 de sinadura, está dividido en en core y en desktop como en la v.1.0. Hemos estado limpiándolas un poco y, todavía no tenemos manual para explicar cómo se configura el proyecto para compilar desde las fuentes y satisfacer las dependencias, pero dános unas semanas y estará todo publicado.»

Dicho y hecho, han pasado unas semanas y ya tenemos manual técnico, que nos explica paso a paso cómo descargar y compilas las fuentes de Sinadura. Entre las funcionalidades que se requieren con más urgencia yo destacaría el soporte a la comprobación de listas de revocación (si no se comprueba no podremos realmente confirmar la validez de un certificado) y el soporte a la firma múltiple (imprescindible para firmar actas con certificado digital por parte de varias personas).

Igual hasta se podrían proponer estas funcionalidades al Google Summer Of Code 2009… si es que este año Google también se anima a llevarlo adelante (con eso de la crisis, lo veo difícil…)

Java Cache Viewer: dónde se esconden los jnlp

Como dice más o menos la Wikipedia, Java Web Start es un framework desarrollado por Sun Microsystems quer permite iniciar directamente desde el navegador aplicaciones Java preparadas específicamente (siguen el protocolo Java Network Launching Protocol – JNLP – ). A diferencia de los applets Java, las aplicaciones Web Start no se ejecutan dentro el navegador, por lo que las duras restricciones de seguridad del sandbox de los applets no se aplican en este caso (aunque este nivel de seguridad también puede configurarse para las aplicaciones JNLP).

Dicho lo anterior a modo de introducción, ayer mismo necesité ejecutar una aplicación Web Start, en concreto iRiverter. Es una mini aplicación Java que permite convertir, a golpe de ratón, un archivo de vídeo .AVI al formato necesario para distintos players de vídeo (en concreto, también para Creative Zen, mi nueva «mascota»). Todo muy bonito y muy bien, pero hoy, cuando he querido ejecutarla de nuevo, me ha surgido la duda. ¿Tengo que estar conectado a Internet para ejecutarla? ¿descargarla otra vez y volver a ejecutarla? No tiene mucho sentido. Además, seguro que está cacheada. Y efectivamente, la gente de SUN lo pensó muy bien. Y no sólo eso, sino que nos permite ver todas las aplicaciones JNLP que hemos descargado, ejecutarlas offline y si queremos, hasta crear un icono de acceso directo a la aplicación cacheada en local. ¿Cómo? Yo lo he hecho a través del Java Cache Viewer, pero seguro que hay alguna otra opción mejor (espero comentarios).


$ /opt/jdk1.6.0_10/bin/ControlPanel

Pulsamos ahora, dentro de la sección «Temporary Internet Files» en el botón «View…».
Se abrirá el «Java Cache Viewer». En el imagen vemos que tengo disponible iRiver, la aplicación que me interesa (y que descargué ayer).

Ahora, con el botón derecho sobre iRiver:

Vemos que tenemos la opción de ejecutar la aplicación Offline, y también de instalar un acceso directo (con icono correcto) en el escritorio. +1 para Java Web Start…