Ingenieria inversa utilizando Radare
Radare es un software realmente potente, este se compone de varios elementos:
radare2: Editor hexadecimal y debugger
rabin2: Extractor de info de los ejecutables binarios
rasm2: Ensamblador, desensamblador desde la CLI
rahash2: Generador de hashes
radiff2: Utilidad para buscar diferencias utilizando varios algoritmos
rafind2: Buscador de patrones en un fichero
ragg2: Compilador de binarios
rarun2: Nos permite correr el programa en diferentes entornos, variables de entorno, argumentos, directorios...
Hay un libro online que nos puede resultar realmente útil.
En la propia web se recomienda instalar desde los repos ya que asà obtendremos siempre la última versión.
cd /usr/src git clone https://github.com/radare/radare2 cd radare2 sys/install.sh
Instalamos los bindings(librerias de integración) de varios lenguajes de programación, Valabind, SWIG, Ctypes, NodeJS, Dlang, Go:
emerge -av dev-lang/vala ln -s /usr/bin/valac-0.24 /usr/bin/valac cd .. git clone https://github.com/radare/valabind cd valabind make make install PREFIX=/usrAhora para python, nodejs, ruby:
cd .. git clone https://github.com/radare/radare2-bindings cd radare2-bindings ./configure --prefix=/usr cd python make make installTesteamos la instalación:
cd ../.. git clone https://github.com/radare/radare2-regressions cd radare2-regressions makeInstalamos el editor hexadecimal ired:
cd .. git clone https://github.com/radare/ired cd ired make make install PREFIX=/usrsdb: base de datos clave-valor similar a redis, utilizada para operaciones internas de radare.
cd .. git clone https://github.com/radare/sdb cd sdb make make -C testsAhora que ya tenemos todo lo necesario procedemos con la programación de un pequeño crackme:
vi 00.c #includeint main(void){ char str1[20]; printf("Crackme 0x00 Coded by Kr0m\n"); printf("Introduzca password: "); scanf("%s", str1); if (strcmp(str1, "666-666") == 0){ printf("Ohu yeyesss Password Correcto!\n"); } else { printf("ERROR: Password incorrecto!\n"); } }
Compilamos el software:
gcc 00.c -o 00Lo probamos:
./00 Crackme 0x00 Coded by Kr0m Introduzca password: asd ERROR: Password incorrecto! ./00 Crackme 0x00 Coded by Kr0m Introduzca password: 666-666 Ohu yeyesss Password Correcto!Radare nos permite dumpear las cadenas de un binario:
rabin2 -z 00
vaddr=0x004007e8 paddr=0x000007e8 ordinal=000 sz=27 len=26 section=.rodata type=a string=Crackme 0x00 Coded by Kr0m
vaddr=0x00400803 paddr=0x00000803 ordinal=001 sz=22 len=21 section=.rodata type=a string=Introduzca password:
vaddr=0x0040081c paddr=0x0000081c ordinal=002 sz=8 len=7 section=.rodata type=a string=666-666
vaddr=0x00400828 paddr=0x00000828 ordinal=003 sz=31 len=30 section=.rodata type=a string=Ohu yeyesss Password Correcto!
vaddr=0x00400847 paddr=0x00000847 ordinal=004 sz=28 len=27 section=.rodata type=a string=ERROR: Password incorrecto!
Abrimos el binario en modo writeble, vamos al main del programa y mostramos las instrucciones desensambladas:radare2 -w 00 [0x004005c0]> s sym.main [0x004006ad]> pd 0x004006c4 bfe8074000 mov edi, str.Crackme_0x00_Coded_by_Kr0m ; "Crackme 0x00 Coded by Kr0m" @ 0x4007e8 0x004006c9 e882feffff call sym.imp.puts 0x00400550(unk) ; sym.imp.puts 0x004006ce bf03084000 mov edi, str.Introduzca_password: ; "Introduzca password: " @ 0x400803 0x004006d3 b800000000 mov eax, 0 0x004006d8 e893feffff call sym.imp.printf 0x00400570() ; sym.imp.printf 0x004006dd 488d45e0 lea rax, qword [rbp - 0x20] 0x004006e1 4889c6 mov rsi, rax 0x004006e4 bf19084000 mov edi, 0x400819 ; "%s" @ 0x400819 0x004006e9 b800000000 mov eax, 0 0x004006ee e8bdfeffff call sym.imp.__isoc99_scanf 0x004005b0() ; sym.imp.__isoc99_scanf 0x004006f3 488d45e0 lea rax, qword [rbp - 0x20] 0x004006f7 be1c084000 mov esi, str.666_666 ; "666-666" @ 0x40081c 0x004006fc 4889c7 mov rdi, rax 0x004006ff e88cfeffff call sym.imp.strcmp 0x00400590() ; sym.imp.strcmp 0x00400704 85c0 test eax, eax ,=< 0x00400706 750c jne 0x400714 | 0x00400708 bf28084000 mov edi, str.Ohu_yeyesss_Password_Correcto_ ; "Ohu yeyesss Password Correcto!" @ 0x400828 | 0x0040070d e83efeffff call sym.imp.puts | 0x00400550() ; sym.imp.puts ,==< 0x00400712 eb0a jmp 0x40071e |`-> 0x00400714 bf47084000 mov edi, str.ERROR:_Password_incorrecto_ ; "ERROR: Password incorrecto!" @ 0x400847 | 0x00400719 e832feffff call sym.imp.puts | 0x00400550() ; sym.imp.puts `--> 0x0040071e 488b55f8 mov rdx, qword [rbp - 8] 0x00400722 64483314252. xor rdx, qword fs:[0x28] ,===< 0x0040072b 7405 je 0x400732 | 0x0040072d e82efeffff call sym.imp.__stack_chk_fail | 0x00400560() ; sym.imp.__stack_chk_fail `---> 0x00400732 c9 leave
Podemos ver en naranja la parte del código donde se realiza la comparación de las cadenas, en verde la parte de código ejecutada si se ha introducido un pass correcto y en rojo sino lo es.
Nos interesa modificar el salto condicional: jne 0x400714 para que salte de forma incondicional a la parte del pass correcto: jmp 0x400708, para ello nos movemos a la posición de memoria donde está el salto:
[0x004006ad]> s 0x00400706Podemos hacer uso de esta chuleta de comandos rápidos, en nuestro caso queremos escribir assembler "a pelo"
[0x00400706]> wa jmp 0x00400708 [0x00400706]> pd ,=< 0x00400706 750c jne 0x400714 ,=< 0x00400706 eb00 jmp 0x400708 [0x00400706]> q
Rejecutamos y Baaannnggg!!
./00 Crackme 0x00 Coded by Kr0m Introduzca password: asd Ohu yeyesss Password Correcto!
Como veis ha sido realmente sencillo, tan solo modificando una pequeña parte del código hemos conseguido desviar el flujo del programa hacia donde nos interesa ;)
Ingenieria inversa utilizando Radare
Reviewed by PDFREEBOOK
on
11:01
Rating:
Post a Comment