Hello, dear reader. This is my first post on this blog and I wanted to use it to explain something that bugged me for a while. At ALX-Holberton, we had some optional tasks which involved cracking the passwords to compiled programs.
We were told we could use GDB, objdump, ltrace and other helpful tools. I tried doing this and found it daunting due to the sometimes necessary knowledge of assembly and the uphill tasks required in learning these tools.
I however found a relatively simple solution. Anybody can easily solve the crackme tasks and it doesn't have to be a headache. All you need is a working knowledge of C and a free cross platform reverse engineering software which I'll introduce now.
Hello Cutter
We will be going through how I did Crackme1.
prerequisites
- Fair knowledge of C programming
- Vim text editor
- gcc compiler
- Cutter software. download here Cutter
First of all we run chmod 755 101-crackme
to make the file executable.
Next up is to try running the program to figure out how it works and what is actually expected of us
Let's see how the program works
Ok, from the above.. we have a little understanding of what is required of us.
Let's jump into the fun part... :)
Fire up Cutter and select the program we want to crack
when you just open cutter
First click on select. Browse through your directories and select the program you want to crack. Then click open at the bottom right corner. And this should bring you here >>>
Default settings are ok
Leave the default setting the way it is and press Ok.
Don't let this scare you, we don't need most of it
Double click on main. One of the listed functions on the top left. Highlighted in green on the picture above
This takes you to the assembly view of the code. WE DON'T NEED THIS. Click on the decompiler tab at the bottom right of the screen. If you can't see, go to the top of the screen, click on windows and then click on decompiler. It should appear now.
Disassembly View
Decompiled to C - What we've been waiting for
from the beautiful C code above we see that if the number of command line arguments passed to the program is more than 2. It returns an error.
if (argc == 2) {
iVar2 = checksum((char **)argv[1]);
if (iVar2 == 0xad4) {
puts("\a\a\aTada! Congrats");
uVar1 = 0;
} else {
puts("Wrong password");
uVar1 = 1;
}
} else {
printf("Usage: %s password\n", *argv);
uVar1 = 1;
}
from the above code, if we convert 0xad4 to decimal from hex, it gives us 2772. Ok interesting.
We see another interesting function called checksum that surely holds the secret to what we are looking for. Lets unravel it! Double click on checksum
int64_t checksum(char **arg1)
{
char **var_18h;
int64_t var_8h;
var_8h = 0;
for (var_18h = arg1; *(char *)var_18h != '\0'; var_18h = (char **)((int64_t)var_18h + 1)) {
var_8h = var_8h + *(char *)var_18h;
}
return var_8h;
}
This is what we see when we double click on checksum. if you don't see this... on the bottom right corner. change your decompiler from jsdec to ghidra.
The code looks a bit incomprehensible but guess what? It's valid C code. So lets use some print statements to know whats actually happening. create a new program and call it test.c, copy the above code and paste, then add some print statements. The above code can be rewritten like this
#include <stdio.h>
#include <stdint.h>
int64_t checksum(char *arg1);
int main(void)
{
char *arg1 = "AAA";
int a = checksum(arg1);
printf("sum %d\n", a);
return (0);
}
int64_t checksum(char *arg1)
{
char var_18h;
int64_t var_8h;
var_8h = 0;
for (var_18h = *arg1; *arg1 != '\0'; arg1++) {
/*adding a printf statement to know what is getting added to var_8h*/
printf("%c\n", var_18h);
var_8h = var_8h + var_18h;
var_18h = *arg1;
}
return var_8h;
}
now type gcc test.c -o main
run the code and we see
wisdom@ubuntu:~/Documents/Vs_Code/ALX/crackmes/test$ ./main
A
A
A
sum 195
A in ASCII decimal is 65, and 65 * 3 is 195. Interesting!!
from this our conclusion is that checksum checks the sum of the individual characters in the string we supplied as password and if the sum is 2772, it passes it as correct.
Lets confirm this, shall we? The ASCII code in decimal for ~
is 126. 126 in 22 places is 2772. Time for the moment of truth. Count carefully....
Counting Exercise
The next part is to write a solution that generates random ascii codes that add up to 2772. I leave that to you.
Have fun. There is lots more you can do it with cutter and you can find easier ways to use it. Feel free to ask your questions.
Till next time. Bye.