Introduction
Hey! Once again we have another reverse engineering challenge. This one is called racecars from the website crackmes.one. The author doesn't provide any hints or constraints regarding the challenge so it seems anything is fair game! This challenge isn't terribly difficult so we should be fine with some basic static analysis. If you want, you can check out the video tutorial on my channel.
Optional Materials to Follow Along
If you want to follow along feel free to download the VM I provide. You can find instructions on importing the VM here. If you don't want to use my VM that's fine, my feelings won't be shattered. But you will at least need the binary. You can download the binary here. The binary comes in a password protected zip file. The password is: crackmes.one.
You'll also need a disassembler. I recommend IDA or Ghidra. With all of that out of the way, let's get reversing!
Initial Triage
Let's start out by running file
on the binary.
Would you look at that! Not only is this binary not stripped but there are debug symbols! Sweet! Let's go ahead and look at the symbols!
Nothing really stands out here. Let's go ahead and take a look at the strings.
Again we don't get much information from the strings. We do see some output from the program. So, we don't have much information about this binary so let's go ahead and open this up in IDA.
Static Analysis in IDA
The great thing about having debug symbols is we don't have to worry about renaming any variables because they'll already have names. So, this allows us to get a feel for what the author was trying to achieve and the purpose of a given variable. We see that the program starts by grabbing the length of argv[0]
. It then subtracts 1 from the length and stores that in the end
variable. This is equivalent to end = strlen(argv[0]) - 1
. It then stores the end
in the start
variable. So, at this point start
also equals strlen(argv[0]) - 1
. Then it performs an unconditional jump to loc_1185
. So, let's take a look and see what's going on!
This section of code is rather simple. It's trying to locate the "/" character is argv[0]
. Remember argv[0]
contains the full path to our executable. We usually run executables with ./executable_name
but that is expanded to the full path of our file. So, in this case, argv[0]
contains: "/home/kali/reverse_engineering/crackmes/racecars/racecars". This block of code will subtract 1 from start
until it reaches a "/" character. When that happens we jump to loc_11E8
. So, let's keep in mind that once this loop finishes, start
will have have the value of strlen(argv[0]) - 7
. Let us continue!
The above is the rest of the main function! Seems we are getting close already! So, after the loop finishes the code jumps to loc_11E8
. First, it loads start
in the EAX
register and compares end
and start
. Surely, at this point, start
will be less than end
so it jumps up to loc_11A2
. Then, it indexes argv[0]
with start
and stores it in the EDX
register. So, EDX
holds, argv[0][start]
. Crazy I know! Then, it indexes argv[0]
with end
and stores that in the EAX
register. So, EAX
holds, argv[0][end]
. You might already have an idea of what the author is doing here. At address 0x00011C6
, the binary then compares DL
with AL
. If they aren't equal the program prints out the error message and quits. Otherwise, it subtracts 1 from end
and adds 1 to start
. This continues until start
and end
are equal to each other. If that ever happens then we get the success message. So, what do we need to do? It's simple, rename the file so that it's a palindrome! That is, the name is spelled the same forward and backward. Interestingly enough, racecar is a palindrome! Let's rename the binary to racecar and run it!
And that's it! Pretty simple challenge if you ask me! If you want to see my decompiled output here you go!
end = strlen(argv[0]) - 1;
start = end;
while(argv[0][start -1] != 0x2F)
{
start--;
}
while(start < end)
{
if(argv[0][start] != argv[0][end])
{
printf("Gimme what I want!");
exit(1);
}
start++;
end--;
}
printf("That's exactly what I wanted!");
And that's all there is to it! Pretty simple challenge if you ask me!
Conclusion
Alright another challenge down! I hope you all enjoyed this and learned something from this tutorial. If you have any questions feel free to hit me up on Twitter, Instagram, or Discord: jaybailey216#6540. If you have a challenge you want me to try next, let me know and I'll give it a shot! I'll see you all next time!
Peace out! ✌🏾