Crackeando y Depurando ( #1 )

Y por aquí seguimos... parece que me lo vuelvo a tomar en serio... ya veremos cuánto me dura.

Mi amiguete d4ni, me dijo que cuándo iba a empezar a hablar un poco de los cracks, desemsamblar programas y tal...

Es que a mi colega le encanta trastear con los porgramas, siempre me anda picando para que haga no se qué, para que intente crackear el programita 'X', mil cosas. Así que hoy vamos a empezar con lo básico.

Primero una herramienta básica de muy bajo nivel (por decirlo de alguna manera): strace - system trace-. Básicamente muestra en el terminal las llamadas del sitema que realiza el programas que ejecutéis.

Tan fácil de probar como hacer:

-$ strace ls

Podréis ver todas las llamadas al sistema que hace - mmap2(..., access(... -, los ficheros que abre - open(... - y más o menos todo lo que hace un ls. Podéis probar con cualquier ejecutable o programa, y veréis a que va llamando.

También tenemos en linux una herramienta de depuración, para mí bastante decente, que es el gdb, normalmente viene instalada en Ubuntu por defecto. Es un programa que funciona por línea de comandos, existe su versión gráfica -gdb-, pero de esa hablaré en el próximo post dedicado a este tema. Voy a hablar un poco de cómo usarlo y las cuatro cosillas un poco básica que yo creo que son necesarias para empezar. Como con todo, lo ideal es empezar con algún tutorial y/o con ayuda de google y esas cosillas.

Bueno, pues vamos a hacer un pequeño ejemplillo que me he currado, es una tontería muy gorda, pero para empezar está muy bien. Os debo aclarar que para todo esto de los cracks y de "debuggear" hay que saber un poco de lenguaje ensamblador y algo del funcionamiento de los programas, con su pila y sus cosillas. Yo no sé mucho, un poquillo, lo justo - y ni eso - para poder trastear, así que a poquito que sepáis o seáis espabilaillos esto lo pillaréis más o menos rápido.

Lo dicho, aquí tenéis un ejecutable para Linux. Os diría que os lo descarguéis y lo ejecutárais, pero a lo mejor sois muy excépticos y no queréis jugároslo a correr un programa de a saber quién. Aquí tenéis el código fuente, lo suyo sería no mirarlo, y empezar con el ejecutable para que no veáis lo que hace ni como lo hace el programa y aprendáis más sobre la depuración de programas. Pero, bueno si lo que hacéis es bajaros el fuente, y echándole un vistazo rápido, para ver que no hay nada malo, pero tampoco viendo lo que hace, que si no no tiene gracia. Que me lío, ahora hacéis:

$ gcc -o crack crack.c

Y ya tenéis el ejcutable. Ahora ya tengáis el ejecutable mío descargado, o el vuestro compilado, lo ejecutamos, y veremos que es un progrmas tonto que nos pide una clave, si la introducimos bien nos da un "OK", sino un "FALLASTE".

Una vez visto el ejecutable, continuamos haciendo:

$ file crack

Y os dirá:

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped

Lo importante de aquí es el "not stripped", que significa que el ejecutable tiene los símbolos incluídos, que más o menos quiere decirque mantiene los nombres (los importantes) del código fuente. Esto quiere decir que mantiene el "main", que es donde empieza el programa, por que si el ejecutable fuera "stripped", el ejecutable empezaría en "_start".

Ahora hacemos:

$ objdump -D crack >> crack.asm

$ gedit crack.asm

Y veremos todas las funciones del ejecutable en ensamblador.

Empezemos ahora con nuestro gdb:

$ gdb crack

Con esto cargamos nuestro ejecutablesi ahora escribimos

(gdb) run

nuestro porgrama correrá más o menos igual que si lo ejecutáramos normalmente, aunque éste nos avisa del motivo de como termina.

Para poner puntos de ruptura se hace con 'b' o 'break' y donde queremos ponerlo.

(gdb) b 1 -> pone un punto de ruptura en la línea 1

(gdb) b main -> pone un punto de ruptura en la función main

Hemos podido poner un breakpoint en la función main por que esta existe y se llama igual, por que si la buscáis en crack.asm está:


080483d4 <main>:

sino también podemos hacer:

(gdb) b *0x080483d4

que es lo mismo, pero si otro ejecutable no tiene la función main, o lo que quieres es poner el punto de ruptura en otor sitio, con poner la dirección es suficiente (OJO!, no os olvidéis del '*').

Ahora vayamos al grano. Si buscamos en crack.asm el main, veremos lo que viene a ser el meollo del programa:


080483d4 <main>:
80483d4:    8d 4c 24 04          	lea    0x4(%esp),%ecx
80483d8:    83 e4 f0             	and    $0xfffffff0,%esp
80483db:    ff 71 fc             	pushl  -0x4(%ecx)
80483de:    55                   	push   %ebp
80483df:    89 e5                	mov    %esp,%ebp
80483e1:    51                   	push   %ecx
80483e2:    83 ec 24             	sub    $0x24,%esp
80483e5:    c7 04 24 0c 85 04 08 	movl   $0x804850c,(%esp)
80483ec:    e8 3f ff ff ff       	call   8048330 <printf@plt>
80483f1:    8d 45 f8             	lea    -0x8(%ebp),%eax
80483f4:    89 44 24 04          	mov    %eax,0x4(%esp)
80483f8:    c7 04 24 34 85 04 08 	movl   $0x8048534,(%esp)
80483ff:    e8 1c ff ff ff       	call   8048320 <scanf@plt>
8048404:    8b 45 f8             	mov    -0x8(%ebp),%eax
8048407:    3d 31 d4 00 00       	cmp    $0xd431,%eax
804840c:    75 15                	jne    8048423 <main+0x4f>
804840e:    c7 04 24 37 85 04 08 	movl   $0x8048537,(%esp)
8048415:    e8 26 ff ff ff       	call   8048340 <puts@plt>
804841a:    c7 45 e8 01 00 00 00 	movl   $0x1,-0x18(%ebp)
8048421:    eb 13                	jmp    8048436 <main+0x62>
8048423:    c7 04 24 3b 85 04 08 	movl   $0x804853b,(%esp)
804842a:    e8 11 ff ff ff       	call   8048340 <puts@plt>
804842f:    c7 45 e8 ff ff ff ff 	movl   $0xffffffff,-0x18(%ebp)
8048436:    8b 45 e8             	mov    -0x18(%ebp),%eax
8048439:    83 c4 24             	add    $0x24,%esp
804843c:    59                   	pop    %ecx
804843d:    5d                   	pop    %ebp
804843e:    8d 61 fc             	lea    -0x4(%ecx),%esp
8048441:    c3                   	ret

Vemos que hay un scanf:


80483ff:	e8 1c ff ff ff       	call   8048320 <scanf@plt>

que es donde recoge lo que introducimos por teclado. Pues vayamos ahí:

$ gdb crack

(gdb) b 0x80483ff

(gdb) run

Se nos parará en el breakpoint

Si hacemos

(gdb) x/10i $eip

nos mostrará en hexadecimal las 10 instrucciones siguientes desde donde estamos (desde el contador de programa, que es el 'eip', pero hay que indicarlo con el '$'):


0x80483ff <main+43>:    call   0x8048320 <scanf@plt>
0x8048404 <main+48>:    mov    0xfffffff8(%ebp),%eax
0x8048407 <main+51>:    cmp    $0xd431,%eax
0x804840c <main+56>:    jne    0x8048423 <main+79>
0x804840e <main+58>:    movl   $0x8048537,(%esp)
0x8048415 <main+65>:    call   0x8048340 <puts@plt>
0x804841a <main+70>:    movl   $0x1,0xffffffe8(%ebp)
0x8048421 <main+77>:    jmp    0x8048436 <main+98>
0x8048423 <main+79>:    movl   $0x804853b,(%esp)
0x804842a <main+86>:    call   0x8048340 <puts@plt>

Como podéis ver es bastante parecido al crack.asm. Ahora hay varias formas de ir avanzando por el programa:

(gdb) n -> o next sigue ejecutando el programa. Lo que ocurre que no se parará hasta que éste termine o llegue a otro breakpoint.

(gdb) nexti -> basicamente avanza hasta la siguiente instrucción. Pero si entrar en la instrucción que ejecuta.

(gdb) stepi -> muy parecido a nexti, lo único que en este caso si que se introduce en la instrocción que ejecutamos. Por ejemplo, si la instrucción a ejecutar es una llamada a una función, stepi entraría en ella, y nexti ejecutaría toda la función pero no veríamos nada de ésta.

Total que si miramos las instrucciones nos damos cuentas de que primero se llama a la función 'scanf':


0x80483ff <main+43>:    call   0x8048320 <scanf@plt>

Después recoge lo tecleado y lo mueve a eax


0x8048404 <main+48>:    mov    0xfffffff8(%ebp),%eax

Si una vez ejecuta esta instrucción, hacemos:

(gdb)p $eax

veremos que en 'eax' está guardada la contraseña que nosotros hemos introducido.

Y después vemos.... ¡¡¡OHHHH!!!, vaya, hace una comparación de 'eax' con un número decimal. Uhhhmmmm, y si no coincide salta a la dirección 0x8048423, e imprime algo y termina:


0x8048423 <main+79>:    movl   $0x804853b,(%esp)
0x804842a <main+86>:    call   0x8048340 <puts@plt>
y si no continúa e imprime otra cosa diferente y termina:


0x804840e <main+58>:    movl   $0x8048537,(%esp)
0x8048415 <main+65>:    call   0x8048340 <puts@plt>
0x804841a <main+70>:    movl   $0x1,0xffffffe8(%ebp)
0x8048421 <main+77>:    jmp    0x8048436 <main+98>

Pues ya está, hemos depurado y crakeado un programa MUUUUUUYYYYY estúpido, pero por algo hay que empezar.

Dentro de poco, vendrá la segunda parte de este post, y empezaremos con cositas un poco más serias, no demasiado, que si no, no podré enseñaros, jejejeje.

Espero que os sirva de algo, y os entretenga si tenéis tiempo suficiente como para "desperdiciar con esto", ;).

Un saludo.

Published 30 January 2008 11:30 AM by melculebras


Comments

# melculebras said on 30 January, 2008 11:30 AM

Debo pediros perdón a todos.

Publiqué el blog esta mañana, pero se me olvidó colgar el archivo con el que hacer las pruebas.

Ahora ya está colgado, hay un enlace en el 6º o 7º parráfo.

Disculpad

# Vindel said on 30 January, 2008 04:17 PM

melculebras solo puedo decirte, que eres un crack. Interesantisimo el post y espero ansiosamente la continuacion. A mi gusto de los mejores post que has hecho.

Gracias macho.

# melculebras said on 31 January, 2008 01:46 AM

PUUUFFF!!!

Muchísimas gracias Vindel. Así da gusto.

De todas maneras, no me digas eso, que luego me lo creo, jejejejeje.

Muchas gracias, pronto tendrás la próxima parte. Espero que sea tan buena como tus espectativas.

Un saludo.

# dani said on 01 February, 2008 06:22 AM

Muy bonito !!

lo leeré a menudo para estar al día de tus progresos :-)

Leave a Comment

(required ) 
(required ) 
(optional )
(required ) 

Captcha