Post

Cracking idanhajbeko's 'babyFirstCrackme' with Ghidra | Step-by-Step Tutorial

Cracking idanhajbeko's 'babyFirstCrackme' with Ghidra | Step-by-Step Tutorial

Video Tutorial

Introduction

Today, we’ll solve a very easy and basic crackme called “babyFirstCrackme” by idanhajbeko using Ghidra. This challenge is specifically designed for people who are interested in learning the basics of reverse engineering. The challenge comes with two files:

  1. babyFirstCrackme - The main crackme binary
  2. hints.exe - A helper program that provides hints for solving the challenge

Prerequisites

Before you begin, ensure you have:

  • Ghidra installed (see our Ghidra installation guide)
  • Basic understanding of C/C++ programming
  • Linux environment
  • Basic knowledge of hexadecimal numbers and bitwise operations

Challenge Information

  • Author: idanhajbeko
  • Language: C/C++
  • Platform: Unix/Linux
  • Difficulty: 1.2/5
  • Quality: 3.2/5
  • Architecture: x86-64
  • Upload Date: April 26, 2025, 4:04 PM
  • Original Name: babyFirstCrackme
  • Source: crackmes.one page

Analysis

Step 1: Initial Program Run

First, let’s try running the main program to see its behavior:

1
2
3
4
5
┌──(fr0stb1rd㉿kali)-[~/ctf]
└─$ ./babyFirstCrackme
Enter the password: 
test123
The password is incorrect

Step 2: Ghidra Analysis

Now, let’s analyze the program using Ghidra:

  1. Open Ghidra and create a new project
  2. Import the babyFirstCrackme binary
  3. Let Ghidra analyze the binary
  4. Find and analyze the main function

Here’s the decompiled main function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
undefined8 main(void)
{
  int iVar1;
  char *__format;
  char local_3f8 [1008];
  
  while( true ) {
    puts("Enter the password: ");
    __isoc99_scanf("%999s",local_3f8);
    iVar1 = strcmp(local_3f8,"!_-P@$$w0rD-_!");
    if (iVar1 == 0) break;
    printf("The password ");
    putchar(0x69);  // 'i'
    putchar(0x73);  // 's'
    putchar(0x20);  // ' '
    puts("\x1b[0;31mincorrect\x1b[0m");  // ANSI color code for red
  }
  printf("\x1b[0;32m");  // ANSI color code for green
  __format = getFlag();
  printf(__format);
  printf("\x1b[0m");  // Reset color
  return 0;
}

Step 3: Analyzing the Hints Program

Let’s also look at the hints program to understand what it does:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
undefined8 main(void)
{
  int iVar1;
  undefined8 uVar2;
  int local_40c;
  char local_408 [1008];
  char *local_18;
  char *local_10;
  
  displayAssciArt();
  local_10 = 
  "**********************************************************************\n* ENTER easy IN THE SECOND INPUT THEN YOU CAN ENTER THE 4 DIGIT CODE *\n**********************************************************************\n"
  ;
  printf(
        "\aThink twice before saying yes, \x1b[41mthere is no going back from knowing\x1b[0m\nDo you want to see the first clue? \x1b[0;32mY\x1b[0m/\x1b[0;31mN\x1b[0;31m: \x1b[0m"
        );
  uVar2 = takeInput();
  if ((int)uVar2 == 0) {
    printf("\x1b[0;32mGood choice good bye :)\x1b[0m");
  }
  else {
    puts(&DAT_00102178);
    printf("Tell me how was it: ");
    __isoc99_scanf(&DAT_001023b0,local_408);
    iVar1 = strcmp(local_408,"easy");
    if (iVar1 == 0) {
      puts(
          "ENTER THE 4 DIGITS CODE\n(and dont even thunk about brute forcing!!!! we have use new and secret methods to defended against that):"
          );
      local_18 = 
      "======================================================================\n+ here is a little snippet of the code where it check the digit code: +\n+         if (inputedCode == (0x4D2^(0x32 & 0x39)))                  +\n======================================================================"
      ;
      while( true ) {
        __isoc99_scanf(&DAT_00102574,&local_40c);
        if (local_40c == 0x4e2) break;
        puts("Incorrect code try again");
        delay(1000);
      }
      printf("\x1b[42mYou did it you got the secret code\x1b[0m");
      delay(1000);
      printf(
            "\x1b[0;33m\nIf you didnt got the code and just found this message when using string or whatever so try again you need to find the code\n\x1b[0m"
            );
      printf("Here is a little victory song for you\x1b[0m");
      delay(5000);
      do {
        putchar(7);
      } while( true );
    }
    printf("Thank you\ngood bye");
  }
  return 0;
}

Solution

The challenge has two parts:

Part 1: Main Program

The main program (babyFirstCrackme) is a simple password checker:

  1. It asks for a password
  2. Compares the input with the hardcoded string !_-P@$$w0rD-_!
  3. If correct, it displays the flag in green color
  4. If incorrect, it shows an error message in red color

Part 2: Hints Program

The hints program (hints.exe) provides a way to get the password:

  1. It first asks if you want to see a clue
  2. If you say yes, it asks you to enter “easy”
  3. Then it asks for a 4-digit code
  4. The code is checked against the result of 0x4D2^(0x32 & 0x39)
  5. The correct code is 1250 (0x4e2 in hexadecimal)

Code Analysis

Let’s break down the key parts:

Main Program

  1. Uses a buffer of 1008 bytes to store the input
  2. Uses strcmp to compare the input with the hardcoded password
  3. Uses ANSI color codes for colored output:
    • \x1b[0;31m for red
    • \x1b[0;32m for green
    • \x1b[0m to reset color

Hints Program

  1. The password check uses bitwise operations:
    • 0x32 & 0x39 = 0x30 (bitwise AND)
    • 0x4D2 ^ 0x30 = 0x4e2 (bitwise XOR)
    • 0x4e2 in decimal is 1250
This post is licensed under CC BY 4.0 by the author.