Documente Academic
Documente Profesional
Documente Cultură
Autor
Alejandro Alcalde
Índice
Primera Bomba
Segunda Bomba
Referencias
El Baúl
Hace unas semanas hablé de un desafío propuesto por los profesores de Estructura de
computadores de mi facultad. Ahora que ha finalizado el plazo de entrega de la
práctica, escribo este artículo con los resultados que obtuve.
Todos los programas escritos por los alumnos estan basados en este:
char password[]="abracadabran";
int passcode = 7777;
void boom(){
printf("***************n");
printf("*** BOOM!!! ***n");
printf("***************n");
exit(-1);
}
void defused(){
printf("·························n");
printf("··· bomba desactivada ···n");
printf("·························n");
exit(0);
}
int main(){
#define SIZE 100
char pass[SIZE];
int pasv;
#define TLIM 5
struct timeval tv1,tv2; // gettimeofday() secs-usecs
El Baúl
gettimeofday(&tv1;,NULL);
gettimeofday(&tv2;,NULL);
if (tv2.tv_sec - tv1.tv_sec > TLIM)
boom();
gettimeofday(&tv1;,NULL);
if (tv1.tv_sec - tv2.tv_sec > TLIM)
boom();
defused();
}
Al cual se le aplican los métodos deseados por el alumno para cifrar la contraseña
que elija.
Conseguí descifrar 2 programas en total, aunque de unos de ellos solo la contraseña
Elalfanumérica,
Baúl luego veremos la razón. Empecemos con el primer programa:
Primera Bomba
Puedes descargar el programa desde este enlace:
Lo primero que hay que hacer es un estudio del comportamiento del programa
usando gdb y objdump -d. Tras ejecutar el programa paso a paso con gdb y predecir
cuales son los puntos críticos creé un archivo de configuración para gdb que me
ayudara a facilitar el depurado:
b main
b *0x804a034
b *0x8048706
b *0x80486ec
b *0x80486e7
b *0x80486c9
b *0x80486c4
b *0x804871e
b *0x804872c
b *0x804874e
display /wx $eip
display /32xw $esp
display /s $eax
display /w (char*)$eax
display (char*)0x804a034
display /wx 0x804a03
Mediante el proceso de depurado, me dí cuenta que las instrucciones clave eran las
siguientes; para la contraseña alfanumérica:
Luego, hace algo parecido con la cuarta letra de la contraseña introducida por el
usuario:
2: x/32xw $esp
0xffffd2f0: 0xffffd318 0x0804a034 0x0000000a 0xffffd3a4
1: x/xw $eip
0x804871e <strncmp>: 0xfffe01e8
Una vez descubierta la contraseña alfanumérica, pasé a la numérica, que resultó ser
bastante sencilla. Esta vez la clave de todo está en estas instrucciones:
Segunda Bomba
Puedes descargar el programa desde este enlace.
b main
b cambio
b *0x804882a
b begin
b change
b code
b *0x804880e
b *0x804888d
display /wx $eip
display /d $ecx
display /d $eax
display /d $edx
display /32xw $esp
display /s $eax
display /w (char*)$eax
display (char*)0x804a034
display /wx 0x804a034
movzbl (%eax),%eax
cmp $0x43,%al
jne 80486a1 <cambio>
call 804860c <boomb>
Por tanto, la contraseña que el usuario debe introducir es c4b3Z0n, para que al
realizar el cambio quede como C4b3Z0n. Si se introduce por contraseña Q4b3Z0n,
se reemplaza por c4b3Z0n que es distinto de C4b3Z0n, detonando la bomba.
080486cd <code>:
80486cd: 55 push %ebp
80486ce: 89 e5 mov %esp,%ebp
80486d0: 83 ec 18 sub $0x18,%esp
80486d3: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp)
80486da: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
80486e1: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp)
80486e8: 81 45 08 1a 27 00 00 addl $0x271a,0x8(%ebp)
80486ef: 81 45 08 e8 03 00 00 addl $0x3e8,0x8(%ebp)
80486f6: 83 45 08 02 addl $0x2,0x8(%ebp)
80486fa: 8b 45 08 mov 0x8(%ebp),%eax
80486fd: 89 45 f0 mov %eax,-0x10(%ebp)
El8048700:
Baúl eb 4f jmp 8048751 <code>
8048702: 8b 4d f0 mov -0x10(%ebp),%ecx
8048705: ba 67 66 66 66 mov $0x66666667,%edx
804870a: 89 c8 mov %ecx,%eax
804870c: f7 ea imul %edx
804870e: c1 fa 02 sar $0x2,%edx
8048711: 89 c8 mov %ecx,%eax
8048713: c1 f8 1f sar $0x1f,%eax
8048716: 29 c2 sub %eax,%edx
8048718: 89 d0 mov %edx,%eax
804871a: c1 e0 02 shl $0x2,%eax
804871d: 01 d0 add %edx,%eax
804871f: 01 c0 add %eax,%eax
8048721: 89 ca mov %ecx,%edx
8048723: 29 c2 sub %eax,%edx
8048725: 89 d0 mov %edx,%eax
8048727: 89 45 f4 mov %eax,-0xc(%ebp)
804872a: 8b 45 f4 mov -0xc(%ebp),%eax
804872d: 01 45 e8 add %eax,-0x18(%ebp)
8048730: 8b 4d f0 mov -0x10(%ebp),%ecx
8048733: ba 67 66 66 66 mov $0x66666667,%edx
8048738: 89 c8 mov %ecx,%eax
804873a: f7 ea imul %edx
804873c: c1 fa 02 sar $0x2,%edx
804873f: 89 c8 mov %ecx,%eax
8048741: c1 f8 1f sar $0x1f,%eax
8048744: 89 d1 mov %edx,%ecx
8048746: 29 c1 sub %eax,%ecx
8048748: 89 c8 mov %ecx,%eax
804874a: 89 45 f0 mov %eax,-0x10(%ebp)
804874d: 83 45 ec 01 addl $0x1,-0x14(%ebp)
8048751: 83 7d ec 04 cmpl $0x4,-0x14(%ebp)
8048755: 7e ab jle 8048702 <code>
8048757: 83 7d e8 17 cmpl $0x17,-0x18(%ebp)
804875b: 74 07 je 8048764 <code>
804875d: e8 aa fe ff ff call 804860c <boomb>
8048762: eb 05 jmp 8048769 <code>
8048764: e8 d9 fe ff ff call 8048642 <bomb>
8048769: 8b 45 08 mov 0x8(%ebp),%eax
804876c: c9 leave
804876d: c3 ret
Gran parte de este código se usa para calcular un simple módulo, la razón; gcc
Elrealiza
Baúl esta optimización porque la instrucción div a pesar de ser una sola, es más
lenta que todo este código. Si quieres profundizar más en este tema, en las
referencias hay un enlace a stackoverflow que explica qué método se sigue para
calcular el módulo.
/*
==========================================================================
Name : Boom.c
Author : Alejandro Alcalde
Version : 0.1
Description : Práctica sobre ingeniería inversa
==========================================================================
*/
#define SIZE 15
#define ESTO printf(
#define ES "%sn"
#define OFUSCACION ,(char *) v);
void boom() {
printf("***************n");
printf("*** BOOM!!! ***n");
printf("***************n");
exit(-1);
}
void defused() {
printf("·························n");
printf("··· bomba desactivada ···n");
El Baúl
printf("·························n");
exit(0);
}
double password[3];
if (strncmp(f,decode((char*)password),strlen(decode((char*)password))))
boom();
gettimeofday(&tv2;,NULL);
if (tv2.tv_sec - tv1.tv_sec > TLIM)
boom();
gettimeofday(&tv1;,NULL);
if (tv1.tv_sec - tv2.tv_sec > TLIM)
boom();
defused();
return 0;
}
08048870 <decode>:
8048870: 53 push %ebx
8048871: 83 ec 18 sub $0x18,%esp
8048874: c7 04 24 0f 00 00 00 movl $0xf,(%esp)
804887b: 8b 5c 24 20 mov 0x20(%esp),%ebx
804887f: e8 4c fc ff ff call 80484d0 <malloc>
8048884: 31 d2 xor %edx,%edx
8048886: 66 90 xchg %ax,%ax
8048888: 0f b6 4c 53 01 movzbl 0x1(%ebx,%edx,2),%ecx
804888d: 88 0c 10 mov %cl,(%eax,%edx,1)
8048890: 83 c2 01 add $0x1,%edx
8048893: 83 fa 0a cmp $0xa,%edx
8048896: 75 f0 jne 8048888 <decode>
8048898: 83 c4 18 add $0x18,%esp
804889b: 5b pop %ebx
804889c: c3 ret
804889d: 8d 76 00 lea 0x0(%esi),%esi
Que va sumando al pin el resultado de hacer un XOR de su valor con el valor de una
letra almacenada en %ecx y al resultado le suma 7777. Con lo cual tenemos que
conseguir un número al que al hacerle todas estas operaciones de 8305, que resulta
ser 555.
Referencias
¿Has visto algún error?: Por favor, ayúdame a corregirlo contactando conmigo
o comentando abajo.
Compártelo Suscríbete
Categorías:
dev
Etiquetas:
asm c hacking Ingenieria inversa
El Baúl
Quizá también te interese leer...
Cómo compilar todos los archivos CPP de una vez usando MakeFile
Sé el primero en comentar...
Nombre
Sé el primero en comentar.