CTF DE BINARIO CON PTRACE

Aqui estuve resolviendo un reto de un crackme en binario la cual se trataba de saltar el ptrace y la solucion la muestro paso a paso.

Vamos a lo divertido...

#vemos que el archivo binario es estatic.
s1k0@s1k0:~$ file crackme.bin
crackme.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.9, not stripped



#ejecutamos el binario para ver su funcionamiento.
s1k0@s1k0:~$ ./crackme.bin
############################################################
##       
Bienvenido al cracking        ##
############################################################

Password : HOLA

Wrong password.


#exportamos el binario a code asm.
s1k0@s1k0:~$ objdump -D crackme.bin > crack.asm
#ejecutamos el binario con gdb.
s1k0@s1k0:~$ gdb -q crackme.bin
Leyendo símbolos desde /home/*/crackme.bin...

#ponemos un breakpoint en el main y nos da la posicion de memoria 0x80483f0 de el.
(gdb) b *main
Punto de interrupción 1 at 0x80483f0
#arrancamos el para debugear

(gdb) r
Starting program: /home/*/crackme.bin


Breakpoint 1, 0x080483f0 in main ()
(gdb)


#Ahora buscamos en el archivo crack.asm la posicion 0x80483f0 que corresponde al main del programa.
080483f0 (main):

80483f0:    8d 4c 24 04                  lea    0x4(%esp),%ecx

80483f4:    83 e4 f0                        and    $0xfffffff0,%esp
80483f7:    ff 71 fc                          pushl  -0x4(%ecx)
80483fa:    55                                  push   %ebp
80483fb:    89 e5                             mov    %esp,%ebp
80483fd:    51                                  push   %ecx
80483fe:    83 ec 14                        sub    $0x14,%esp
8048401:    c7 45 f4 88 28 0c 08  movl   $0x80c2888,-0xc(%ebp)
 
#En lo anterior podemos observar que en la posicion de memoria 8048401 se esta copiando todo lo de la memoria 0x80c2888 a -0xc(%ebp).

#Ahora veremos que es lo que contien la posicion 0x80c2888 y que se esta copiando.
(gdb) x/8s 0x80c2888
0x80c2888:     "ksuiealohgy"
0x80c2894:     "Debugger detecté ... Exit"
0x80c28af:     ""
0x80c28b0:     '#'
0x80c28ed:     ""
0x80c28ee:     ""
0x80c28ef:     ""
0x80c28f0:     "##       
Bienvenido al cracking        ##"
#Podemos observar que nos muestra algunos string, posiblemente podrian ser la password.

#Luego en unas posiciones mas abajo -> 804841a encontramos un sallto JNS la cual hace un salto a 8048436
8048418:    85 c0                    test   %eax,%eax
804841a:    79 1a                    jns    8048436(main+0x46)

804841c:    83 ec 0c                 sub    $0xc,%esp
804841f:    68 94 28 0c 08           push   $0x80c2894
8048424:    e8 a7 0e 00 00           call   80492d0 <_io_puts>
8048429:    83 c4 10                 add    $0x10,%esp
804842c:    b8 01 00 00 00           mov    $0x1,%eax
8048431:    e9 c3 00 00 00           jmp    80484f9 <_notng x62="">
8048436:    83 ec 0c                 sub    $0xc,%esp
 
#Ahora pondremos un breakpoint en la posicion del salto 804841a y vamos a ella con la opcion C
(gdb) b *0x804841a
Punto de interrupción 2 at 0x804841a
(gdb) c
Continuando.

Breakpoint 2, 0x0804841a in main ()
 
#Comprobaremos si se ejecuta el salto o nos deja pasar a la sigueinte posicion de memoria con un si.
 (gdb) si
0x0804841c in main ()
 
#Vemos que no se ejecuto el salto y nos dejo pasar a la pisicion, 
804841c:    83 ec 0c                 sub    $0xc,%esp
 
#Asi seguimos hasta la posicion del push 804841f y vemos que se esta insertando en la pila.
gdb) x /8s 0x80c2894
0x80c2894:     "Debugger detecté ... Exit"
0x80c28af:     ""
0x80c28b0:     '#'
0x80c28ed:     ""
0x80c28ee:     ""
0x80c28ef:     ""
0x80c28f0:     "##        Bienvenido al cracking        ##"
0x80c292d:    


#Llegamos  a la posicion 8048424 y ejecutamos el call, y podemos ver que retorna una salida o que esta a punto de terminar.
(gdb) si
0x08048424 in main ()
(gdb) x/1s 0x80c2894
0x80c2894:     "Debugger detecté ... Exit"

#Aqui se puede verificar que el programa esta a punto de salir.
8048431:    e9 c3 00 00 00           jmp    80484f9 <_notng x62="">

80484f9:    8b 4d fc                 mov    -0x4(%ebp),%ecx
80484fc:    c9                       leave
80484fd:    8d 61 fc                 lea    -0x4(%ecx),%esp
8048500:    c3                       ret  
8048501:    90                       nop

#Ahora que por ahi no esta la password,ahora lo que vamos hacer es que se ejecute el salto JNS hacia JMP 80484f9 para eso vamos a ver los flags de JNS.

#Volvemos a poner un breakpoin  al JNS y continuamos.
(gdb) b *0x804841a
Nota: puntos de rotura 2 and 3 también fijar en pc 0x804841a.
Punto de interrupción 4 at 0x804841a
(gdb) c
Continuando.

Breakpoint 2, 0x0804841a in main ()
#Verificamos sus flags.
(gdb) p $eflags
$1 = [ PF SF IF ]

#Si SF=0 se ejecuta el salto, entonces lo que aremos es desabilitar el SF, ya que SF es el septimo bit en el registro solo necesitamos ejecutar xor con 2 ^ 7 = 128.
(gdb) set $eflags = $eflags ^ 128
(gdb) p $eflags
$2 = [ PF IF ]

#Ahora el salto SF queda desactivado y nos deja pasar a la otra instruccion.
(gdb) si
0x08048436 in main ()


#Ahora ponemos un breakpoint en la posicion 8048495 aqui se ejecuta el Enter despues de introducir la pass y hace el salto a 8048497.
804848e:    8d 05 97 84 04 08        lea    0x8048497,%eax
8048494:    40                               inc    %eax
8048495:    ff e0                            jmp    *%eax

(gdb) b *0x8048495
(gdb) c
 Continuando.
############################################################
##        Bienvenido al cracking        ##
############################################################

Password : LOL

Breakpoint 6, 0x08048495 in main ()

#Aqui vemos que se encuentra un CMP donde se compara lo ingresado por teclado con la password original.
08048497 <_notng>:
8048497:    b8 8a 55 ea 8b     mov    $0x8bea558a,%eax
804849c:    45                            inc    %ebp
804849d:    f4                            hlt   
804849e:    83 c0 04                 add    $0x4,%eax
80484a1:    8a 00                      mov    (%eax),%al
80484a3:    38 c2                      cmp    %al,%dl

#Entonces seguimos avanzando de posicion asta llegar al CMP en 80484a3.
(gdb) si
0x08048498 in main ()
(gdb) si
0x0804849b in main ()
(gdb) si
0x0804849e in main ()
(gdb) si
0x080484a1 in main ()
(gdb) si
0x080484a3 in main ()
 
#Ya posicionado en el CMP obtenemos el valor de %al y %dl de la siguente manera.
0x080484a3 in main ()
(gdb) p $al
$6 = 101
(gdb) p $dl
$7 = 65

#La cual %al es la pass Real y %dl es la que se ingreso por teclado
101 = e
65   =A

#Despues debajo del CMP hay unos saltos JNE los cuales envian a 80484e4 donde contiene lo siguente.
80484e4:    83 ec 0c                   sub    $0xc,%esp
80484e7:    68 8e 29 0c 08          push   $0x80c298e
80484ec:    e8 df 0d 00 00          call   80492d0 <_io_puts>
80484f1:    83 c4 10                    add    $0x10,%esp
80484f4:    b8 00 00 00 00          mov    $0x0,%eax
80484f9:    8b 4d fc                      mov    -0x4(%ebp),%ecx
80484fc:    c9                              leave 
80484fd:    8d 61 fc                      lea    -0x4(%ecx),%esp

#Si obtenemos el valor de 0x80c298e veremos que es el mensaje de error.
(gdb) x/1s 0x80c298e 
0x80c298e:     "\nWrong password.\n"

#Entonces solo nos queda saltar los JNE para seguir con las intrucciones y para ello debemos cambiar el flags a 0 el cual es representado por ZF y es el sexto bit que en decimal es 2 ^ 6 = 64.
(gdb) si
0x080484a5 in main ()
(gdb) p $eflags
$8 = [ CF AF SF IF ]
(gdb) set $eflags = $eflags ^ 64
(gdb) p $eflags
$9 = [ CF AF ZF SF IF ]

#Ahora solo seguimos avanzando a cada CMP cambiando el valor de los JNE.
(gdb) si
0x080484b2 in main () 
(gdb) p $al
$6 = 97
(gdb) p $dl
$7 = 65

(gdb) si
0x080484bf in main () 
(gdb) p $al
$6 = 115
(gdb) p $dl
$7 = 65

(gdb) si
0x080484ce in main ()
(gdb) p $al
$6 = 121
(gdb) p $dl
$7 =65

-=[Felicitaciones]=-
Pass: ASII(101,97,115,121) = easy

AYUDA
PF: Flags de paridad
SF: Flags Sesion
IF : Interrupt enable flags
ZF: Zero Flags

LINKS
https://en.wikipedia.org/wiki/FLAGS_register
http://www.cavestory.org/guides/csasm/guide/asm_flags.html 


No hay comentarios:

Publicar un comentario