Más soluciones a los niveles del Hack-it de este año en la Euskal, aquí van las 5 siguientes, de los niveles 11 al 15. Lo requetedicho, hay muchas soluciones posibles diferentes, así que, si queréis, podemos comentar soluciones alternativas en los comentarios 😉
Nivel 11
Nivel de cracking de un binario. Vamos a analizarlo previamente:
$ file level11-cacadecafe
level11-cacadecafe: ELF 32-bit LSB executable, Intel 80386, version 1, statically linked, corrupted section header size
Se trata de un binario para GNU/Linux, arquitectura IA-32, enlazado estáticamente y probablemente stripped.
Al mirar las cadenas de caracteres del binario, vemos que hay muchas y cortadas por la mitad. Esto es típico del empaquetador UPX:
$ strings level11-cacadecafe
Linux
/lib
nux.so.2
__gmon_start
exit$IO!d
used3&3ma
LIBC_2.0
O Ih
PTRh
#W$$
jH/X
La cjtraC
del siguie
e niv
es %s
+Com
obando
%"3F9-D1E
275A-7
7Hola, bTOS
El problema está en que el UPX no reconoce el binario como comprimido con él, porque el binario está modificado para quitar todas las referencias al programa:
$ upx -d level11-cacadecafe
Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.01 Markus Oberhumer, Laszlo Molnar & John Reiser Jun 06th 2006
File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: level11-cacadecafe: NotPackedException: not packed by UPX
Unpacked 0 files.
La manera más fácil de conseguir el binario sin comprimir es reconstruir esta información, y para saber qué ha sido quitado, se puede comprimir con UPX otro binario y ver las diferencias, para reestablecer las referencias a UPX en el binario que tenemos que crackear.
$ upx /bin/ls -o demo.upx
Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.01 Markus Oberhumer, Laszlo Molnar & John Reiser Jun 06th 2006
File size Ratio Format Name
-------------------- ------ ----------- -----------
77512 -> 38228 49.32% linux/elf386 demo.upx
Packed 1 file.
$ strings demo.upx | grep -i upx
UPX!
UPX!
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 2.01 Copyright (C) 1996-2006 the UPX Team. All Rights Reserved. $
UPX!u
UPX!
Como vemos, hay muchas referencias a UPX y en nuestro binario han sido eliminadas todas:
$ strings level11-cacadecafe | grep -i upx
$
Al reconstruirlas poco a poco, conseguimos un binario que puede descomprimirse finalmente con UPX y finalmente la única complejidad que tiene el binario es que comprueba dos strings que no son iguales. Simplemente modificando el resultado de la comparación o modificando uno de los dos strings, conseguimos que el binario nos dé la contraseña del siguiente nivel.
Nivel 12
Este nivel causó mucha confusión entre los participantes del hackit en la Euskal Encounter 2006, por la poca información explícita que se proporciona:
Un amigo dice que “la forma es fondo”, y creo que tiene bastante razón. Pensando en esa frase, este amigo ideó un cifrado bastante simple, averigua el mensaje para pasar al siguiente nivel:
NOTA: _start = 79;
107 55 50
46 -> 116
111 79
55 96
43 36
108 98
53 106
41 ^ v 103
59 118
101 116
34 100
112 112
108 <- 96
39 104 249
Lo que sabemos al ver esto es:
- El cifrado es bastante simple, olvidémonos de cifrados asimétricos y cosas raras.
- _start = 79: habrá que empezar en el 79, muy probablemente.
- Los números están dispuestos en círculo y unas flechitas nos indican el sentido de la rotación.
- La intrigante pista “la forma es fondo”.
Lo primero que hacemos es poner los números en órden, empezando por el primero:
79 96 36 98 106 103 118 116 100 112 96 249 104 39 108 112 34 101 59 41 53 108 43 55 111 46 107 55 50 116
Esto recuerda mucho al primer nivel de criptografía, donde teníamos una serie de números y un cifrado muy simple, XOR. El problema está aquí en que no tenemos la contraseña.
Después de darle unas cuantas vueltas, nunca mejor dicho ;-P, es posible darse cuenta de que los datos no están en círculo por cualquier razón, sino que la razón de un círculo, PI, tiene mucho que ver con este cifrado. Si aplicamos XOR con PI como clave…
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned char cyphertext[] = { 79, 96, 36, 98, 106, 103, 118, 116, 100, 112, 96, 249, 104, 39, 108, 112, 34, 101, 59, 41, 53, 108, 43, 55, 111, 46, 107, 55, 50, 116 };
unsigned char pi[] = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, 8, 8, 4, 1, 9, 7, 1};
int i;
for(i = 0;i < strlen(cyphertext);i++)
printf("%c", cyphertext[i]^pi[i]);
}
Y conseguimos la contraseña, “f3-3n-3l-c40s”, el subtítulo de la película PI.
Nivel 13
Otro nivel de cracking en Windows. Al descargarnos el binario vemos que se trata de un programa en Mono/.Net:
$ file Hackit.exe
Hackit.exe: MS-DOS executable PE for MS Windows (GUI) Intel 80386 32-bit Mono/.Net assembly
El ensamblado .Net está ofuscado, por lo que hay muchas referencias a métodos que se llaman “a” en diferentes ámbitos, lo que complica su cracking.
Y al mirar las cadenas de caracteres, encontramos muchas, pero no la contraseña del siguiente nivel:
Desensamblándolo vemos a qué funciones se llaman y modificando la llamada que se produce después de recibir el click en el botón de comprobación de usuario y contraseña, podemos hacer que se muestre la contraseña del siguiente nivel.
Después de desensamblar el binario, vemos que en IL_00f8 hay un salto condicional. Negándolo conseguimos que el código se comporte de forma opuesta y nos muestre la contraseña:
IL_00e8: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::a
IL_00ed: callvirt instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
IL_00f2: ldloc.0
IL_00f3: call bool [mscorlib]System.String::op_Equality(string, string)
IL_00f8: brfalse.s IL_0107
IL_00fa: newobj instance void A.B::.ctor()
IL_00ff: stloc.2
IL_0100: ldloc.2
IL_0101: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::Show()
IL_0106: ret
IL_0107: newobj instance void A.a::.ctor()
IL_010c: stloc.3
IL_010d: ldloc.3
IL_010e: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::Show()
Nivel 15
Otro nivel de cracking en Win32:
$ file level15.exe
level15.exe: MS-DOS executable PE for MS Windows (GUI) Intel 80386 32-bit
Como en el anterior, hay que rellenar correctamente el fichero llave, levelC2.lic. Para saber qué poner, lo recomendable es depurarlo con OllyDbg o un depurador similar. Después de analizar el código, vemos que el número de serie o “pass” tiene que tener 8 caracteres, comprendidos entre 0x41 y 0x53, es decir, serán todo mayúsculas, entre la “A” y la “R”.
Mirando un poco más profundamente vemos que en EAX:EDX se va haciendo la división por 0x0D de cada una de las letras del usuario (“euskal14”) en orden inverso (“41laksue”) y la parte que queda en EDX se compara con un valor que ahora comentaremos. Si esta comparación no es exacta, saltará al código de error.
Este valor que comentamos se calcula para cada vuelta del bucle de comprobación (se da una vuelta por cada caracter de la contraseña, es decir, 8 vueltas), y es el resultado de restar 0x41 a una letra que se toma de una lista de letras ordenada de una forma peculiar:
Lista: B C D A F E N K L R O M P G I H Q J
Indice: A B C D E F G H I J K L M N O P Q R
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52
L-0x41: 01 02 03 00 05 04 0D 0A 0B 11 0E 0C 0F 06 08 07 10 09
En L-0x41 está calculada la resta de cada letra de la lista con 0x41. Este cálculo nos vendrá muy bien cuando queramos igualar el resto de la división de cada letra de “41laksue”:
usuario: 4 1 l a k s u e
idiv 0x0D: 00 0A 04 06 03 0B 00 0A
Indice: D H F N C I D H
Si buscamos en la tabla anterior cada uno de esos resultados, veremos cuáles son los índices que corresponden, y obtendremos el número de serie.
Como siempre Txipi, eres la ostia…!
Recuerdos de un Mexicano!
Ey, Demonio, ¿has bajado a los infiernos o qué? 😉
Espero que te vaya muy bien en México, todavía me acuerdo del repaso que le pegamos al master la última noche que nos encontramos por ahí de fiesta 😀
Hola Txipi
Yo he superado el nivel 13 simplemente dejando user y serial en blanco y dandole a check.
Un saludo y gracias por la dedicación
Daniel Medianero
@Daniel: no me extrañaría nada ese error, el nivel lo programé en 10 minutos y no soy precisamente un experto en .Net. La función de validación hace unas comprobaciones entre user y serial, pero quizá si ambos están vacíos, todas esas comprobaciones no funcionan pero dan como resultado que el programa funcione. Un gran fallo, gracias por reportar el error 😉
Hola Txipi
Bueno yo más que verlo como un error lo veo como la prueba de que las cosas se pueden hacer de varias maneras.
La rabia que le dará a los participantes si alguno se quedó en este nivel ehhh, jejej.
Un saludo