Solucion de los niveles del 11 al 15 del Hack-it de la Euskal Encounter 2006

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:

  1. El cifrado es bastante simple, olvidémonos de cifrados asimétricos y cosas raras.
  2. _start = 79: habrá que empezar en el 79, muy probablemente.
  3. Los números están dispuestos en círculo y unas flechitas nos indican el sentido de la rotación.
  4. 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

level14

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.

level14

Y al mirar las cadenas de caracteres, encontramos muchas, pero no la contraseña del siguiente nivel:

level14

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.

level15

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.

level15

5 pensamientos en “Solucion de los niveles del 11 al 15 del Hack-it de la Euskal Encounter 2006

  1. txipi

    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 😀

    Responder
  2. txipi

    @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 😉

    Responder
  3. Daniel Medianero

    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

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *