This page looks best with JavaScript enabled

Reverse Engineering using Radare

 ·  🎃 kr0m

Some time ago we took our first steps in the world of reverse engineering, learning about stack organization, how to execute a shellcode, how to write our own shellcodes, and how to execute a shell using shellcode. To perform all these tasks, we used GDB, a magnificent software for debugging our programs, but the reversing task became somewhat cumbersome. This time we will use Radare, focused from the ground up on reversing.

Radare is a really powerful software, composed of several elements:

  • radare2: Hexadecimal editor and debugger
  • rabin2: Extractor of info from binary executables
  • rasm2: Assembler, disassembler from the CLI
  • rahash2: Hash generator
  • radiff2: Utility to search for differences using various algorithms
  • rafind2: Pattern finder in a file
  • ragg2: Binary compiler
  • rarun2: Allows us to run the program in different environments, environment variables, arguments, directories…

There is an online book that can be really useful.

On the website itself, it is recommended to install from the repos as we will always get the latest version.

cd /usr/src
git clone https://github.com/radare/radare2
cd radare2
sys/install.sh

We install the bindings (integration libraries) for several programming languages, 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=/usr

Now for python, nodejs, ruby:

cd ..
git clone https://github.com/radare/radare2-bindings
cd radare2-bindings
./configure –prefix=/usr
cd python
make
make install

We test the installation:

cd ../..
git clone https://github.com/radare/radare2-regressions
cd radare2-regressions
make

We install the hexadecimal editor ired:

cd ..
git clone https://github.com/radare/ired
cd ired
make
make install PREFIX=/usr

sdb: key-value database similar to redis, used for internal operations of radare.

cd ..
git clone https://github.com/radare/sdb
cd sdb
make
make -C tests

Now that we have everything we need, we proceed with the programming of a small crackme:

vi 00.c

#include<stdio.h>
int 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");
    }
}

We compile the software:

gcc 00.c -o 00

We test it:

./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 allows us to dump the strings of a binary:

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!

NOTE: The old school would do it through string :)

We open the binary in writeble mode, go to the program’s main and show the disassembled instructions:

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

We are interested in modifying the conditional jump: jne 0x400714 to jump unconditionally to the correct pass part: jmp 0x400708, so we move to the memory position where the jump is:

[0x004006ad]> s 0x00400706

We can use this cheat sheet of quick commands, in our case we want to write assembler “by hand”

[0x00400706]> wa jmp 0x00400708
[0x00400706]> pd
 ,=< 0x00400706 750c jne 0x400714
 ,=< 0x00400706 eb00 jmp 0x400708
[0x00400706]> q

We run it again and Baaannnggg!!

./00

Crackme 0x00 Coded by Kr0m
Introduzca password: asd
Ohu yeyesss Password Correcto!

As you can see, it has been really easy, just by modifying a small part of the code we have managed to redirect the flow of the program to where we are interested ;)

If you liked the article, you can treat me to a RedBull here