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 |
$ 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) |
$ 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 .. |
$ 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....");
}
}
} |
// 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: > |
$ 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.