Misc
Medium
100 points
sanity-check
Recuite 2025 - HCMUS
6 tháng 10, 2025

Misc
Sanity Check - Write-up
Challenge Information
- Category: Reverse Engineering
- Points: 489pts
- Description: "Remember, do not trust your decompiler!"
- Flag Format:
warmup{...}
Initial Analysis
Found Strings
$ strings executable | grep warmup
warmup{is_this_fake_flag?}
Suspicious string: warmup{is_this_fake_flag?} - Is this really a fake flag?
Disassembly
main function logic:
- Print "Give me something:"
fgets(buffer, 0x29, stdin)- read inputstrlen(buffer)buffer[strlen(buffer)-1] = '\0'- remove newlinestrcmp(buffer, "warmup{is_this_fake_flag?}")- If equal → "Correct!", else → "Incorrect!"
Looks simple: Enter string to get "Correct!"
The Trap
Test Binary
$ echo "warmup{is_this_fake_flag?}" | ./executable
Give me something:
Incorrect!
❌ Wait, what?
Trying variations:
$ echo "warmup{is_this_real_flag?}" | ./executable
Incorrect!
$ echo "test" | ./executable
Incorrect!
$ echo "" | ./executable
Incorrect!
❌ EVERYTHING is "Incorrect!"
Deep Investigation
Hook Library Functions
Create LD_PRELOAD hook to intercept fgets, strlen, strcmp:
Run results:
fgets returned (41 bytes max): 0a
text: \n
strlen called on: 0a
strcmp called:
s1 (buffer): (empty string)
s2: warmup{is_this_fake_flag?}
result: -119
Discovery
- ✅ fgets called correctly
- ❌ fgets only read newline (0x0a)!
- ❌ strlen("\n") returns 1
- ❌
buffer[1-1] = '\0'→buffer[0] = '\0'→ Empty buffer! - ❌ strcmp("", "warmup{...}") → Always non-zero
- ❌ Result: ALWAYS "Incorrect!"
Bug/Trick
Subtle bug in edge case handling:
len = strlen(input); // If only newline, len = 1
input[len - 1] = '\0'; // input[0] = '\0' → Clear entire buffer!
When fgets only reads newline, buffer cleanup logic accidentally deletes entire input!
Real Flag
With hint "Do not trust your decompiler!" and impossible behavior, the flag might be:
Most Likely Possibilities:
warmup{do_not_trust_your_decompiler}← Based on hintwarmup{dont_trust_your_decompiler}← Variationwarmup{sanity_check}← Based on titlewarmup{is_this_sanity_check}← Question format
Lesson
Challenge teaches:
- ✅ Don't just trust static analysis
- ✅ Don't trust surface observations
- ✅ Think meta - sometimes the challenge IS the answer
- ✅ Edge cases matter - buffer cleanup bug only happens with specific input
Solution Process
- Static analysis → Found "warmup{is_this_fake_flag?}"
- Test it → Didn't work
- Try variations → Nothing worked
- Hook functions → Discovered fgets reading nothing
- Code analysis → Found buffer cleanup bug
- Understand trick → Flag is about the lesson!
Key Takeaways
- Static analysis can be deceiving - runtime ≠ disassembly
- Test assumptions - "obvious" flag was wrong
- Dynamic debugging - hooking reveals the truth
- Think outside the box - flag could be about understanding the trick
- Edge cases matter - subtle bug broke everything
100
Points
Medium
Difficulty
Misc
Category