$cat maybe-it-is-42.mdReversingHacknite 2.0
Maybe it is 42?
This time the flag is scrambled until you enter the right number. Decompiling the program reveals the check, and the number it wants unscrambles the flag.
$man maybe-it-is-42
What this one teaches:
- Using a decompiler to turn machine code back into readable C.
- Reading a decompiled check to find the value a program expects.
- How signed and unsigned bytes can be two readings of the same number.
$hint --one-at-a-time
Stuck? Open one hint, then go back and try again before reading the next.
Hint 1 of 2show
The flag isn't plain text any more. Decompile the program and read what main actually does.
Hint 2 of 2show
There's one comparison standing between you and the flag. What number passes it?
Task description
42 is the answer to the ultimate question of life, the universe and everything. Sadly, not in Ema’s program. 42 isn’t the right answer, but Ema’s favourite number is.
The original was in Croatian; this is my translation.
No more plain text
Unlike the previous task, opening this program in IDA doesn’t show the flag. It isn’t stored as text; it’s scrambled, and only unscrambled when you give the right input.
Reading raw machine code is hard, so we used IDA’s decompiler, which reconstructs readable C from the compiled program (in IDA, select main and press F5). It gave us this:
scanf("%hhu", &v4); // read one byte from the user into v4
if (v4 == -125) { // the check
for (i = 0; v6[i]; ++i)
s[i] = v6[i] ^ v4; // unscramble the hidden bytes with v4
puts(s); // print the result (the flag)
}
The number it wants
There’s one gate: v4 == -125. Pass it and the program unscrambles and prints the flag. So we need to enter the number that makes v4 equal -125.
There’s a subtlety worth understanding. A byte holds a value from 0 to 255, but the same byte can be read two ways. Read as a signed number (allowing negatives) it runs from -128 to 127; read as unsigned it runs from 0 to 255. The variable v4 is a signed byte, so the check wants -125, but scanf("%hhu", ...) reads an unsigned byte. The two meet at the same underlying byte: -125 signed is the same byte as 131 unsigned.
So the number to type is 131, Ema’s “favourite number”. Then the loop takes the hidden bytes (v6) and combines each with 131 using XOR, a reversible bitwise operation, which turns them back into the flag and prints it.
$cat flag.txt reveal
CTF2021[426497846330]