Alaa S

Alaa S

Tech nerd looking for new opportunities.

Guide to simple binary exploitation

Posted on November 4, 2024


Objective

The goal is to modify a program that checks a product key by altering the binary to always pass the check, regardless of the input.


Tutorial Video

If you’d like a visual walkthrough, watch the tutorial below:


Step-by-Step Guide

Step 1: Understand the Program Structure

  1. Obtain the Program Code or Binary: Start with the program’s source code or compiled binary. In this case, we have a C program that validates a product key using a hash function.(you can find the source code here)
  2. Identify the Hash Function:

    • The code contains a hash function (based on DJB2) that computes a hash for the input product key.
    • This computed hash is then compared to a hardcoded hash value. If they match, the program grants access.
  3. Analyze the Program Logic: The program’s validation flow looks like this:

    1. Prompt for the product key.
    2. Hash the product key input.
    3. Compare the computed hash with a predefined value.
    4. Allow access if the hashes match; otherwise, deny access.

Step 2: Compile and Test the Program

  1. Compile the Program (if you have the source code): Use a C compiler (like GCC) to compile the code:

    gcc -o product_key_checker product_key_checker.c

    This produces an executable file (product_key_checker.exe on Windows).

  2. Run the Program: Run the compiled binary to understand its behavior and confirm that it only accepts a valid product key.
  3. Identify a Known Valid Product Key (Optional): If possible, run tests to identify a product key that hashes to the correct value. For example, if 199 hashes to the expected value, use it to test the binary’s validation behavior.

Step 3: Disassemble the Binary to Locate the Comparison

  1. Disassemble the Binary: Use a disassembler like objdump to inspect the binary:

    objdump -d product_key_checker.exe > disassembled_code.txt

    This generates a disassembly file (disassembled_code.txt) with assembly instructions.

  2. Locate the Main Function: Search for the main function in the disassembly to find the product key validation logic.
  3. Identify the cmp Instruction: Look for a cmp instruction in main that compares the computed hash with the hardcoded hash. It might look like this:

    3d e8 8a 87 0b   cmp $0xb878ae8, %eax

    Here, 3d e8 8a 87 0b in hexadecimal represents cmp $0xb878ae8, %eax, where 0xb878ae8 corresponds to 193432296.

Step 4: Plan the Modification to Bypass Validation

  1. Objective: Change the cmp instruction to always evaluate as “equal.”
  2. Modify cmp to Compare eax with Itself: Replace cmp $0xb878ae8, %eax with cmp %eax, %eax, which will always yield equality since a register compared to itself is always equal. The hexadecimal for cmp %eax, %eax is 39 c0.
  3. Fill Remaining Bytes with NOP: Since the original instruction is 5 bytes and cmp %eax, %eax is only 2 bytes, use NOP (90) to fill the remaining bytes. This keeps the program aligned.
  4. Final Byte Sequence: Replace 3d e8 8a 87 0b with:

    39 c0 90 90 90

Step 5: Modify the Binary in a Hex Editor

  1. Open the Binary: Open the compiled program (product_key_checker.exe) in a hex editor (like HxD).
  2. Locate the Comparison Instruction: Search for the byte sequence 3d e8 8a 87 0b in the hex editor.
  3. Edit the Bytes: Replace 3d e8 8a 87 0b with 39 c0 90 90 90 to force the comparison to always succeed.

Step 6: Save and Test the Modified Program

  1. Save the Modified Binary: Save the file after making changes in the hex editor.
  2. Run the Modified Program: Run product_key_checker.exe to test it. Now, the program should accept any product key, as the comparison is forced to succeed.

Summary of Steps

  1. Analyze the Program: Identify the hash check and validation logic.
  2. Locate cmp Instruction: Find the cmp instruction in the disassembled code.
  3. Plan the Modification: Change cmp $0xb878ae8, %eax to cmp %eax, %eax.
  4. Edit in Hex Editor: Replace 3d e8 8a 87 0b with 39 c0 90 90 90.
  5. Save and Test: Run the modified binary to confirm that the product key check is bypassed.

This process effectively alters the binary’s validation flow, allowing any input as a valid product key.

refrences

Intel x86 Opcode Table and Reference