← Back to Writeups
CUSTOMEasyReversing

MC 1 (Dynamic Analysis)

XESXOR9/2/20262 min read
#reversing#custom#easy#static_analysis#strings_extraction

MC 1 (Dynamic Analysis)

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

Summary

Walkthrough of the CUSTOM Reversing MC 1 (Dynamic Analysis). Language: C. Binary only (no source). "Flag is the input that makes app say 'Correct!'"

Description

RE5_5mc1 (display name "mc1") — Reverse. Flag is the input that makes the app say "Correct!".

The challenge ships a 64-bit x86-64 PIE ELF mc1.elf (not stripped). When run it prints Enter the long flag to verify: and, on the right input, replies Correct!. The flag is submitted via POST flag to rev-kids20.forkbomb.ru.

Analysis

Static analysis of main (radare2 / objdump) shows the validator does not compare the input against a single string. Instead it slices the input into three contiguous, fixed-width windows and compares each window against its own hardcoded constant in .rodata: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Compare callInput sliceLengthConstant offset
strncmp(input + 0x00, str@0x97b, 20)[0:20]200x97b
strncmp(input + 0x14, str@0x9a5, 12)[20:32]120x9a5
strcmp (input + 0x20, str@0x993)[32:]rest0x993

All three comparisons must succeed for the program to print Correct!. Note the offsets: 0x14 = 20 and 0x20 = 32, so the windows tile the input exactly with no gaps or overlaps. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The key observation: the three stored constants, laid out in the input's positional order, concatenate into the full flag. There is no transformation, no hashing, no obfuscation — the expected bytes are literally sitting in .rodata.

Solution

Read the three constant strings from .rodata at the referenced offsets and concatenate them in slice order [0:20] + [20:32] + [32:]:

bash
# Dump the constants at the offsets main references
objdump -s -j .rodata mc1.elf | less     # locate bytes at 0x97b, 0x9a5, 0x993
# or with radare2:
#   r2 -q -c 'ps @ 0x97b; ps @ 0x9a5; ps @ 0x993' mc1.elf

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

Concatenating in positional order:

  • [0:20] from 0x97b → V3ry_L0ng_f14g_70_4n
  • [20:32] from 0x9a5 → n0y_3v3ryb0
  • [32:] from 0x993 → dY_wh0_r3V3rS3S_1t

(The exact split between the stored constants does not matter for recovery; what matters is that placing the bytes referenced by each compare at the right input offset yields one contiguous string.)

Result:

REDACTED

This is leetspeak for "Very Long flag to annoy everybody who reverses it".

Verification by running the binary (amd64) and feeding the assembled string: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

bash
docker run --rm -i --platform linux/amd64 -v "$PWD":/w -w /w ubuntu:22.04 \
  sh -c 'echo "REDACTED" | ./mc1.elf'
# -> Enter the long flag to verify: Correct!

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

Key Takeaways / Lessons

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

Crafted by XESXOR Research • 2026-03-09 • CUSTOM • MC 1 (Dynamic Analysis) • Difficulty: Easy