← Back to Writeups
CUSTOMEasyReversing

crackme1

XESXOR9/2/20262 min read
#reversing#custom#easy#constraint_solving#disassembly#static_analysis#xor_properties

crackme1

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: constraint_solving, disassembly, static_analysis, xor_properties

Summary

Walkthrough of the CUSTOM Reversing crackme1. Detailed walkthrough.

Description

Download binary: crackme1 (ELF 32-bit) or crackme1.exe (PE32). This task waits for ten numbers. Flag is the ten numbers that make the app say 'Correct!' (there may be many correct flags).

Task: Find 10 space-separated integers that make the binary print "Correct!". The binary implements Haskell-style functional combinators (foldl, mapM) in C.

Analysis

Binary reconnaissance:

  • ELF 32-bit LSB executable, Intel 80386, not stripped
  • Source file name visible in symbols: crackme1.c
  • Key function names: int_foldl, int_foldl1, mapM_, int_read, int_print, main
  • Output strings: "Correct!" and "Wrong!" ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The binary implements functional programming patterns in C:

  • int_foldl(func, init, count, arr) — fold left with initial accumulator value
  • int_foldl1(func, count, arr) — fold left starting with accumulator = 0
  • mapM_(func, count, arr) — applies function to each array element (monadic map)

Main logic disassembly reveals:

c
int arr[10] = {0};
mapM_(int_read, 10, arr);    // Read 10 integers from stdin
mapM_(int_print, 10, arr);   // Echo them back

result1 = int_foldl1(xor, 10, arr);     // XOR all numbers (init=0)
result2 = int_foldl(and, 1, 10, arr);   // Logical AND all (init=1)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

if (result1 == 0 && result2 != 0) {
    puts("Correct!");
} else {
    puts("Wrong!");
}

Helper functions:

  • xor(a, b) — returns a ^ b
  • and(a, b) — returns (a != 0 && b != 0) ? 1 : 0 (logical AND, not bitwise)

Solution

Conditions for "Correct!":

  1. XOR of all 10 numbers must equal 0
  2. All 10 numbers must be non-zero (logical AND chain starting with 1)

Constraint solving: Any 10 non-zero integers whose XOR is 0 work. The simplest approach is using pairs that cancel out:

python
#!/usr/bin/env python3
# Verification script
nums = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Check XOR = 0
xor_result = 0
for n in nums:
    xor_result ^= n
print(f"XOR result: {xor_result}")  # 0

# Check all non-zero
all_nonzero = all(n != 0 for n in nums)
print(f"All non-zero: {all_nonzero}")  # True

# Output flag
print(" ".join(map(str, nums)))

Verification:

$ echo "REDACTED" | ./crackme1
REDACTED
Correct!

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering constraint_solving, disassembly, static_analysis, xor_properties was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-03-09 • CUSTOM • crackme1 • Difficulty: Easy