Crackmes.de - The_thing by prout
This is a crackme level 2 (Easy) from https://crackmes.one/crackme/5ab77f5433c5d40ad448c1d6 )
Fast static analysis Link to heading
First, let’s see what type of file it is:
$ file thething
thething: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.4.1, dynamically linked, interpreter /lib/ld-linux.so.2, no section header
Ok, so 32 bits ELF and dynamically linked (this detail will be useful later). Not sure if stripped or not because of the “no section header”.
Let’s see what the ``strings’’ command says:
$ strings thething
read
ptrace
strcmp
sprintf
scanf
[TRUNCATED]
Serial:
In fact, your serial have to be equal or bigger than 4 letters
[TRUNCATED]
__init_array_start
_IO_stdin_used
sprintf@@GLIBC_2.0
__data_start
_Jv_RegisterClasses
read@@GLIBC_2.0
__gmon_start__
A lot of symbols and function names, so it doesn’t seem to be stripped, good news. And also a lot of strings.
Dynamic analysis and cracking part Link to heading
Lets run the program :
$ ./thething
Name: toto
Serial: ze32r1ze312r
Error ! I can't process this name/serial
Depending on the input, we can trigger an other error :
"In fact, your serial have to be equal or bigger than 4 letters"
We know that the string is at least 4 characters long. Lets keep digging with ltrace
to see what sprintf
or strcmp
do:
$ ltrace ./thething
Couldn't find .dynsym or .dynstr in "/proc/6541/exe"
Not working, probably because of the “no section header”. Instead, I try to use the LD_PRELOAD trick with strcmp. I choosed strcmp because it’s often use to compare actual user input with expected input.
Prepare the file for the hook:
#include <stdio.h>
int strcmp(const char *s1, const char *s2){
printf("cmp : <%s> <%s>", s1, s2);
return 0;
}
(Always return 0, so strings will always match)
Compile to create the .so lib :
gcc -o strcmp.so -fPIC -shared strcmp.c -m32
note :
-fpic
for position independant code)-shared
for shared library-m32
to force x86 because my computer is x86_64 and the binary is x86
Try it :
$ LD_PRELOAD=$PWD/strcmp.so ./thething
Name: Toto
Serial: EZRE
cmp : <'-160141484'> <EZRE>Well done :-)
The hook worked, we can see that the serial we entered is compared to a number (the expected serial). Let’s try it without LD_PRELOAD:
$ ./thething
Name: Toto
Serial: -160141484
Well done :-)
No need to disassemble here, but by doing so we can see in IDA that the serial is the string representation of an integer (%d
). This string is then compared to our input with strcmp
.
Ok it works, next step, create a keygen for arbitraries names.
Keygen Link to heading
## Lazy way
Use the .so file can be used as a keygen.
#include <stdio.h>
int strcmp(const char *s1, const char *s2){
printf("Serial found : <%s>", s1);
return 0;
}
and …
LD_PRELOAD=$PWD/strcmp.so ./thething
Name: AAAA
Serial: 339820865
Serial found : <339820865>Well done :-)
./thething
Name: AAAA
Serial: 339820865
Well done :-)