Crack-me Challenges and reverse engineering
Understanding Crack-me Challenges and Techniques
What is a crack-me challenge?
Crack-me challenges are a type of computer security challenge that typically involves reverse engineering or cracking a piece of software to extract a "flag" or a password that is hidden within the software.
The goal of a crack-me challenge is to test the skills of computer security enthusiasts or professionals in identifying vulnerabilities, exploiting them, and finding ways to bypass security measures.
Crack-me challenges often involve modified or intentionally vulnerable versions of executable files, such as binary files or executable scripts. Participants are usually given instructions on how to run the program and are challenged to bypass security measures or find ways to extract the hidden flag or password.
Why learn Crack-me challenges ?
Can be used for various purposes, including:
Training and testing the skills of security professionals, such as penetration testers or reverse engineers.
Evaluating the security of a system or a piece of software, by identifying weaknesses that could be exploited by attackers.
Crack-me challenges can range from easy to very difficult, and they often require a combination of technical skills, creativity, and persistence to solve. They can be found in various online forums, websites, and competitions, and they are a popular way for security enthusiasts to challenge themselves and learn new skills.
What are some common techniques used to solve crack-me challenges?
There are several common techniques used to solve crack-me challenges. Here are some of them:
Reverse engineering: This involves analyzing the software's code to understand how it works, including its algorithms, data structures, and security measures. Reverse engineering can be done using tools such as disassemblers, debuggers, and decompilers.
Debugging: This involves using a debugger to step through the code and examine the program's state and memory at different points during execution. This can help identify vulnerabilities or hidden data that can be used to extract the flag or password.
Machine code versus Assembly :
Machine code and assembly code are both low-level representations of instructions that can be executed by a computer's processor, but they differ in their levels of abstraction and human readability.
Machine Code:
Machine code is a binary representation of instructions that the computer's processor can directly understand and execute. It is composed of sequences of 0s and 1s, representing specific operations and data manipulation.
Example of x86 machine code:
10110000 01100001 00000000
Assembly Code:
Assembly code is a human-readable representation of machine code. It uses mnemonic instructions and symbolic representations of memory locations, registers, and other elements to represent the low-level instructions. serves as a bridge between machine code and high-level programming languages.
Example of x86 Assembly code:
mov al, 0x61
So we need A disassembler to take this machine code as input and reverses the process. It analyses the binary instructions and translates them into assembly code, which is a human-readable representation of the machine code
How to deal with crack me files ?
Usually you can break permission denied with : chmod 755 crackmefile
Commands you can use :
strings command
To extract printable strings from a file called "crackmefile," you can use the
strings
command in Linux or macOS. Here's how you can use it:
Open a terminal and navigate to the directory where the "crackmefile" is located.
Run the following command:
strings crackmefile
The command will scan the file and display all the printable strings it finds. You can then examine the output to look for any potential passwords or relevant information.
bjdump
commandobjdump is a disassembler. It can be used to disassemble binary files, object files, shared libraries, and executables into their corresponding assembly language code. When used with the "-d" option, objdump will display the disassembled code for the specified file.
To extract the .rodata
section from the "crackme" file, you can use the objdump
command. Here's how you can do it:
Open a terminal and navigate to the directory where the "crackme4" file is located.
Run the following command:
objdump -s -j .rodata crackmefile
The objdump
command is a powerful tool for analyzing object files and executables. The -s
option tells objdump
to display the contents of the specified sections, and the -j .rodata
option specifies that you want to extract the .rodata
section.
After executing the command, you should see the contents of the .rodata
section displayed in the terminal. This section typically contains read-only data, such as string literals and other constant values used by the program.
Sometimes
objdump
command may generate an error due to unknown crackme file type, it is useful to check file type by :
file crackmefile
it will gives you file typoe like :
file crackmefile
example : crackmefile: python 3.4 byte-compiled
Note that The objdump
command is typically used for analyzing compiled object files and executables, not Python byte-compiled files (.pyc). Python byte-compiled files are not in the same format as object files and do not have sections like .rodata
. However, you can use other methods to extract information from Python byte-compiled files.
How to recover the original Python source code from a compiled .pyc
file ?
you can use a third-party library called uncompyle6
. This library provides a decompiler for Python bytecode, allowing you to convert compiled bytecode back into human-readable source code.
To use uncompyle6
, you need to install it first. You can install it using pip:
pip install uncompyle6
uncompyle6
: a third-party library specifically designed to decompile Python bytecode back into human-readable source code. It can handle compiled.pyc
files and generate equivalent Python source code. It attempts to recreate the original code as closely as possible, including variable names, control flow structures, and function definitions.uncompyle6
is useful when you want to recover the original source code from compiled bytecode.
Command to use it on a certain file will be:
uncompyle6 crackmefile.pyc
“so you need to rename file to .pyc” if you assured its type by :
file fileName
command
Using the
python -c
command with semicolon-separated code resulted from uncompyle6 crackmefile.pyc command is a convenient way to test and verify small portions of code without the need for a separate script file. It allows you to quickly execute and observe the results of specific code segments from the command line.Including the
print
statement in thepython -c
command is particularly useful when you want to quickly check the output of a specific code/variable:example :
python3 -c "ok = 'shaza aly';
ok = ok[1:3] + ok[3];print(ok)"
What is a keygen ?
A keygen, short for "key generator," is a program or algorithm that generates a valid serial number or license key for a specific software application. It is commonly used in the context of cracking or bypassing software protection mechanisms.
In the case of crackme5, the objective is to create a keygen that can generate a valid key for a given username, which will allow the user to successfully run the crackme program without encountering a segmentation fault.
Creating a keygen typically requires reverse engineering the algorithm used to generate the keys in the target software.
1- Check file type : file filename
example : file crackmeFile
: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,….
this means it is an ELF (Executable and Linkable Format) binary file,
hint : if binary is not stripped means that symbol information, such as function names and variable names, is preserved in the executable. This can be helpful during the reverse engineering process as it allows for easier analysis and understanding of the code.
2- radare2:
It is an open-source framework for reverse engineering and analyzing binary files. It is commonly used for tasks like analyzing malware, reverse engineering software, and solving crackmes (challenges designed to test reverse engineering skills).
To use radare2 to solve a crackme, you can follow these general steps:
Install radare2: Visit the official radare2 website https://radare.org/ or faster with:
sudo snap install radare2
aaa
: Auto-analyze the binary to identify functions and symbols.afl
: List all functions present in the binary.pdf @main
: Disassemble themain
function and analyze its instructions.s <address>
: Set the current seek address to a specific location.pdf
: Disassemble the instructions at the current seek address.Example :
let us try : pdf @main as an example
seek pattern like │ add rax, 1 and seek hexadecimal representaion to be compared with, or read it from address provided:
0x0040099b 4883c001
add rax, 1
│ 0x0040099f 0fb610 movzx edx, byte [rax]
│ 0x004009a2 8b459c mov eax, dword [var_64h]
│ 0x004009a5 4898 cdqe
│ 0x004009a7 0fb64405b0 movzx eax, byte [rbp + rax - 0x50]
│ 0x004009ac 38c2 cmp dl, al
│ ┌─< 0x004009ae 7405 je 0x4009b5
To read from the memory location at address 0x4009b5, you can use the following GDB command:
The GDB command
x/1xb
0x4009b5 examines one byte of memory starting at the address 0x4009b5. The output you provided shows the hexadecimal values of this one byte, along with their corresponding ASCII characters, if they are printable.x/1xb 0x4009b5 x/2xb 0x4009e7 /*2 bytes" - offset - E7E8 E9EA EBEC EDEE EFF0 F1F2 F3F4 F5F6 789ABCDEF0123456 0x004009e7 8b55
.Uso memory address holds letter u, which represents
rax, 1
which means 2nd char
Remember : Usually you can break permission denied with : chmod 755 crackmefile
PRACTICE : how to make a C program that generates and prints passwords for the "crack-me file" executable:
intro.
in this type of programs we need a string to be used as a reference or lookup table from which specific characters are selected randomly to generate the password
used as a
pool of characters from which the program can select specific characters based on the calculations performed on the input argument. Each character in the password is determined by performing calculations and using the result as an index to select a character fromthat pool
.
The author likely chose a combination of different character types (uppercase, lowercase, numbers, and special characters) to increase the complexity and variety of the generated passwords. This helps ensure that the generated passwords are strong and not easily guessable.
Your code is supposed to generate a password based on the user input provided as a command-line argument (
argv[1]
).The length of the user-provided input (
argv[1]
) is used to perform calculations and transformations to generate the password.
The specific characters in the generated password depend on the calculations performed on the user input.
Example :

password
array. In this simplified version, the modification is simply incrementing each character by 1, make modification more complex as more as you need!.Notes on logic :
For modification purposes we can for example
:
password[i] = argv[1][i] + 1;
would indeed increment the ASCII value of each character inargv[1]
by 1.
For example, if argv[1]
is "shaza":
's' (ASCII value 115) + 1 equals 116, which corresponds to the ASCII value of 't'.
Please note that the approach of simply incrementing characters in this way is not suitable for generating secure passwords. It is used here only as a simple example for demonstration purposes. In real-world scenarios, more robust and secure methods should be used to generate passwords.
Have some whiteboarding to share ? welcome to comments…
Example(Important)
objdump -d crackme
The command objdump -d crackme
disassembles the executable file crackme
and displays the disassembly, look for .f
sections to investigate functions:
The xor $0x3b,%eax
instruction performs a bitwise XOR operation between the value of %eax
and the immediate value 0x3b
(which is 59 in decimal), and stores the result back into %eax
.
example C Code : command line input length ^ 59
random_idx = (len ^ 59) & 63;
Another function f2:
The xor $0x4f,%eax
instruction performs a bitwise XOR operation between the value in the %eax
register and the immediate value 0x4f
. This operation effectively subtracts 79 from the value in %eax
.
(random_idx ^ 79) & 63 : we can use it to be a random index for array of random chars so as to generate random letter.
to be continued….
wow i like it tanks