As some of you may know, there is a “new” reverse engineering toolkit out there which tries to compete with IDA Pro in terms of reverse engineering. I’m talking about radare2, a framework for reversing, patching, debugging and exploiting.
It has large scripting capabilities, runs on all major plattforms (Android, GNU/Linux, [Net|Free|Open]BSD, iOS, OSX, QNX, w32, w64, Solaris, Haiku, FirefoxOS and even on your pebble smartwatch 😉 ) and is free.
Sadly, I had some problems finding good tutorials on how to use it, as the interface is currently a bit cumbersome. After fiddling around, I’ve decided to create a little tutorial series where we can learn together ;).
I will publish one binary per post and you will have time to reverse it till the next blog post is published (most of the time you have to find which data you have to enter to make the binary happy).
So let’s start 🙂
The most advisable way is to use the most current version from the github repository:
(As taken from the README:)
The easiest way to install radare2 from git is by running the following command:
If you want to install radare2 in the home directory without using root privileges and sudo, simply run:
If everything goes well, you’ll find multiple tools in your path:
- r2 – the “main” binary
- rabin2 – binary to analyze files (list imports, exports, strings, …)
- rax2 – binary to convert between data formats
- radiff2 – binary to do some diffing
- rahash2 – creates hashes from file blocks (and whole file)
- rasm2 – helps to play with assembler instructions
The default interface for radare2 is the command line. Just type
to start it. Radare has a very shortened command syntax (it is always logical, but in my opinion a few more characters wouldn’t hurt). So to start the analysis of your file, type aa (for analyze all; use aaa or aaaa to run even more analysis algorithms). Did you already get the idea behind the commands? Radare uses a tree structure like name of the commands so all commands which corresponds to analyzing something start with a. If you want to print something you have to use…. p. For example disassemble the current function: pdf (print disassembly function).
As no human could remember all available commands in radare (there are many of them), the ? character is used to display context sensitive help text. A single ? shows you which command categories are available and some general help about specifying addresses and data. A p? shows you the help about the different print commands, pd? which commands are available for printing disassemblies of different sources, etc.
An important command to walk through your targets is the seek command. By using
you’ll jumping into the main function (as long as you’d analyzed the binary in the first step and symbols are available). The following shows you the output of the pdf command after seeking to the main function of the /bin/true binary.
;-- section_end..plt: ;-- section..text: / (fcn) main 160 | ; DATA XREF from 0x0040142d (main) | 0x00401370 83ff02 cmp edi, 2 ;  va=0x00401370 pa=0x00001370 sz=11465 vsz=11465 rwx=--r-x .text | ,=< 0x00401373 7403 je 0x401378 | | 0x00401375 31c0 xor eax, eax | | 0x00401377 c3 ret | `-> 0x00401378 53 push rbx | 0x00401379 488b3e mov rdi, qword [rsi] | 0x0040137c 4889f3 mov rbx, rsi | 0x0040137f e84c050000 call fcn.004018d0 | 0x00401384 be6d404000 mov esi, 0x40406d | 0x00401389 bf06000000 mov edi, 6 | 0x0040138e e81dffffff call sym.imp.setlocale | 0x00401393 bef6404000 mov esi, str._usr_share_locale ; "/usr/share/locale" @ 0x4040f6 | 0x00401398 bfe8404000 mov edi, 0x4040e8 ; "coreutils" @ 0x4040e8 | 0x0040139d e86efdffff call sym.imp.bindtextdomain | 0x004013a2 bfe8404000 mov edi, 0x4040e8 ; "coreutils" @ 0x4040e8 | 0x004013a7 e844fdffff call sym.imp.textdomain | 0x004013ac bf20184000 mov edi, 0x401820 | 0x004013b1 e85a2c0000 call fcn.00404010 | 0x004013b6 488b5b08 mov rbx, qword [rbx + 8] ; [0x8:8]=0 | 0x004013ba be08414000 mov esi, str.__help ; "--help" @ 0x404108 | 0x004013bf 4889df mov rdi, rbx | 0x004013c2 e839feffff call sym.imp.strcmp | 0x004013c7 85c0 test eax, eax | ,=< 0x004013c9 743b je 0x401406 | | 0x004013cb be0f414000 mov esi, str.__version ; "--version" @ 0x40410f | | 0x004013d0 4889df mov rdi, rbx | | 0x004013d3 e828feffff call sym.imp.strcmp | | 0x004013d8 85c0 test eax, eax | ,==< 0x004013da 7526 jne 0x401402 | || 0x004013dc 488b0dcd4d20. mov rcx, qword [rip + 0x204dcd] ; [0x6061b0:8]=0x404383 str.8.25 | || 0x004013e3 488b3d3e4e20. mov rdi, qword [rip + 0x204e3e] ; [0x606228:8]=0x2029554e4728203a LEA obj.stdout ; ": (GNU) 5.3.0" @ 0x606228 | || 0x004013ea 4531c9 xor r9d, r9d | || 0x004013ed 41b819414000 mov r8d, str.Jim_Meyering ; "Jim Meyering" @ 0x404119 | || 0x004013f3 bae4404000 mov edx, str.GNU_coreutils ; "GNU coreutils" @ 0x4040e4 | || 0x004013f8 be64404000 mov esi, str.true ; "true" @ 0x404064 | || 0x004013fd e86e220000 call fcn.00403670 | `--> 0x00401402 31c0 xor eax, eax | | 0x00401404 5b pop rbx | | 0x00401405 c3 ret | `-> 0x00401406 31ff xor edi, edi | 0x00401408 e803010000 call fcn.00401510 \ 0x0040140d 0f1f00 nop dword [rax]
Nearly all radare commands which operates on addresses (like disassmble) allow to use an argument to specify a different position instead of the current one by using an @. Therefore a
produces the same result. You like the tree view of IDA? Enter the visual mode of radare by entering V. Now you see an hexeditor were you can navigate through. By typing ?, you’ll get a list of possible keyshortcuts for this mode. Press V (capital v) to get this:
Awesome, isn’t it? Now let’s rename the function fcn.00401510 in our disassembly to a more meaningful name. This could either be done by
Or by using
afn better_name fcn.00401510
afn better_name 0x00401510
afn better_name @fcn.00401510
afn better_name @0x00401510
If you’re a little afraid of this huge amount of command line fu, you could also try the webinterface:
r2 -c=H your_binary
Which gets you this:
You will find the first challenge here (linux64 dynamically linked, linux64 statically linked, win64):
MD5 (challenge01) = b6449993d4278f9884f45018fc128d15
MD5 (challenge01.exe) = 1d78ad3807163cfb7b5194c1c22308c4
MD5 (challenge01-static) = 833cdfe2b105dfda82d3d4a28bab04bd
SHA1 (challenge01) = 55d7755be8ea872601e2c22172c8beccefca37cc
SHA1 (challenge01.exe) = 108837eeffb6635aa08e0d5607ba4d502d556f32
SHA1 (challenge01-static) = 2ad83f289e94c3326d3729fc2c04f32582aba8a3
SHA256 (challenge01) = 56f239d74bdafd8c2d27c07dff9c66dc92780a4742882b9b8724bce7cc6fb0d1
SHA256 (challenge01.exe) = 9ef57cbd343489317bef66de436ebe7544760b48414ca2247ced1ce462b4591d
SHA256 (challenge01-static) = 99f15536cc8a4a68e6211c3af6a0b327c875373659bf7100363319e168c0deb7
Your goal is to find the correct password for the login in the binary (
hint: hardcoded passwords are bad) . Next time I’ll give you a walkthrough for the challenge and challenge #2.