Insert valuable reasonable advice about learning what tools are right for a job and the value of learning how to use them. Throw in some relevant quote from someone far smarter than I am to get you thinking and to show you that I read shit outside of computer books. Now that that’s out of the way lets start learning about radare2.
What is it? From the github page it’s a set a library and tools for working with binary files. It’s available for just about any modern operating system including: Mac, Linux, Windows, Android, iOS, etc. So it’s a usable tool for the right price (free).
It’s said that there is a really high learning curve for Radare2 but there’s also a really good book that goes over some details. The best part is towards the end of the book that goes over some crackmes as a tutorial (in my opinion, which is worth what you paid for it). I’m going to go through the crackmes and see what I can add to what’s already being done.
Here’s a link to the book and a link to the crackme files. How to do the crackme’s is gone over step by step, so I’m going to try to dig a little deeper and play around with the commands to see what I can come up with.
The point of these crackme binaries is to get the password to be accepted. The first one we are going to go about that in the easiest way, providing the correct password. First we can run the binary (not advisable if you don’t know what it is) and see what happens. Since in this case we know what it is and are following a tutorial.
$ ./crackme0x00 IOLI Crackme Level 0x00 Password: test Invalid Password!
Basic enter a string and compare functionality from the looks of it. Technically we don’t know that though. The way to find out would be to check and see what we can find out about this file. We saw a way to do that previously using the
file command in Linux.
The first thing the tutorial does is tell us to look at the strings using Rabin2. I’m going to take a detour here. From the book Rabin2 allows us to pull information from the binary. From the list of commands we can see that the
-I flag will tell us the binary info.
$ rabin2 -I crackme0x00 havecode true pic false canary false nx true crypto false va true intrp /lib/ld-linux.so.2 bintype elf class ELF32 lang c arch x86 bits 32 machine Intel 80386 os linux minopsz 1 maxopsz 16 pcalign 0 subsys linux endian little stripped false static false linenum true lsyms true relocs true rpath NONE binsz 7537
There’s a lot of information there and what it’s telling us will come in vary handy when we get to more complicated files. The items that jump out to me right now are the following:
havecode: true – the code is included which is helpful for reverse engineering.
class: ELF32 – tells us what kind of binary it is. A 32-bit ELF file. Which means Linux but it tells us that in the output as well.
lang: C – tells us that the program was originally written in C. Which is good to know.
stripped: false – the binary hasn’t been stripped.
static: false – the binary is dynamically linked.
Imported Functions and Libraries:
I stated earlier that the binary looks like it just prints out some strings, accepts a string as input, compares the input string to something, and then outputs correct or incorrect. Without looking at the disassembly of the program one way to try and verify that’s all this executable does is to look at the functions it imports. We can do that with rabin2 as well.
$ rabin2 -i crackme0x00 [Imports] ordinal=001 plt=0xffffffff bind=UNKNOWN type=NOTYPE name=__gmon_start__ ordinal=002 plt=0x08048320 bind=GLOBAL type=FUNC name=__libc_start_main ordinal=003 plt=0x08048330 bind=GLOBAL type=FUNC name=scanf ordinal=004 plt=0x08048340 bind=GLOBAL type=FUNC name=printf ordinal=005 plt=0x08048350 bind=GLOBAL type=FUNC name=strcmp 5 imports
As we can see the executable only imports 5 functions. Even if we didn’t know that the original code was written in C we should be able to recognize the library functions from the import as C functions. The listed imports match what I expected from running the program. If you don’t know why I would expect to see something like this then go write a C program to verify if input matches a string you have.
What we should be looking for here are unexpected functions that point towards unknown functionality. For example if there was a syscall import we should be looking for ways in which the executable is interacting with the system that is not obvious from the execution output.
We can also look at what libraries the binary uses and see if there’s anything unexpected.
$ rabin2 -l crackme0x00 [Linked libraries] libc.so.6 1 library
Nothing unexpected here. So now we have a decent idea of what this binary contains and what it interacts with.
Where To Go Next:
There’s an obvious question now. What is going to get us that password or allow us to jump to the accept code portion of the binary. Since we have a walk through the obvious way is to follow it and get the goal. But that’s not the only way to get the goal. We will learn more about those ways as things move forward. Today it’s about Radare2 more than ways to crack a crackme.
Rather than just jump to the answer though lets think about the functions that the executable imports. The majority of those functions are for interacting with strings. The most important function that tells us what to think of is the strcmp() function. The interesting thing about the strcmp() function for us is the set of arguments that it takes, you should see that in the definition it’s linked to. arg2 is the string we are comparing to. That means that somewhere in the executable the correct string should be stored.
Which is where the tutorial leads us to, we can get rabin2 to output the strings in the executable.
$ rabin2 -z crackme0x00 vaddr=0x08048568 paddr=0x00000568 ordinal=000 sz=25 len=24 section=.rodata type=ascii string=IOLI Crackme Level 0x00\n vaddr=0x08048581 paddr=0x00000581 ordinal=001 sz=11 len=10 section=.rodata type=ascii string=Password: vaddr=0x0804858f paddr=0x0000058f ordinal=002 sz=7 len=6 section=.rodata type=ascii string=250382 vaddr=0x08048596 paddr=0x00000596 ordinal=003 sz=19 len=18 section=.rodata type=ascii string=Invalid Password!\n vaddr=0x080485a9 paddr=0x000005a9 ordinal=004 sz=16 len=15 section=.rodata type=ascii string=Password OK :)\n
Everything makes sense here in the program functionality except the
string=250382 string. Since that’s the only string that doesn’t appear in our execution it’s probably the second argument for strcmp().
$ ./crackme0x00 IOLI Crackme Level 0x00 Password: 250382 Password OK :)
And that’s the solution to the crackme. Which is pretty cool, but that was just from following the tutorial. So we can’t take any credit for actually solving it. But we have gained some experience with Rabin2.
This was a good introduction to Rabin2 and getting used to command line tools. I included my thought process about solving the crackme which isn’t explained very much in the tutorial in the Radare2 book. So I hope that added enough value to the writeup to make it worth the effort of reading it. There’s going to be a bunch more of this stuff so it is what it is.