Anantya ByteMe CTF Writeup Series: The Broken Throne
Welcome Back to the Official Write-Up Series of ByteMe CTF!
The OWASP PCCOE Student Chapter is leveling up! For our 5th write-up, we are diving into the world of Reverse Engineering with The Broken Throne. This challenge taught participants that "winning" the game isn't always the same as solving the challenge.
Category: Reverse Engineering
Difficulty: Easy
Author: Sarthak Warale
Theme: Game of Thrones / Binary Manipulation
1. Overview: The Illusion of Victory
The challenge provided a CLI game where you rule the Seven Kingdoms. Most players who completed the game were greeted with a triumphant message:
The realm is united. The lords bow.
However, no flag appeared. In the world of CTFs, a "victory" without a flag is a classic Fake Success Path. It strongly suggests that the real objective is buried deep within the binary code, unreachable through standard gameplay.
2. Static Analysis: Peeking Under the Hood
To find the truth, we opened the binary in Ghidra. Looking at the decompiled main function, the logic became crystal clear:
if (worthiness == 0xDEADBEEF) {
reveal_flag();
} else {
fake_victory();
}
The variable worthiness is modified during the game, but it is mathematically impossible to reach the value 0xDEADBEEF via normal inputs. This "Dead Code" branch effectively locked the flag away from the player.
3. Finding the Flag Logic
Inside the reveal_flag() function, we discovered how the flag was protected:
An encrypted byte array was stored in the data segment.
A simple loop XORed each byte with a constant: 0x5A.
This confirmed that the flag wasn't just a static string we could find with a simple strings command; it was computed at runtime.
4. Solution Methods
Method 1: Patching the Binary (The "Hacker" Way)
The most direct way to solve this is to force the program to take the "wrong" path. In the Ghidra Listing view, we located the assembly instruction:
CMP EAX, 0xDEADBEEF
JNZ <fake_victory_address> (Jump if Not Zero)
The Fix:
Patch the
JNZinstruction toJZ(Jump if Zero), orNOP (No-Operation) out the jump entirely so the program naturally flows into
reveal_flag().
After exporting and running the patched binary, the throne—and the flag—were finally ours.
Method 2: Manual Decryption (The "Math" Way)
If you didn't want to run the code, you could simply extract the encrypted bytes from the binary and XOR them with 0x5A using a Python one-liner:
encrypted = [0x10, 0x33, 0x2e, ...] # Example bytes from binary
print("".join([chr(b ^ 0x5A) for b in encrypted]))
5. Capturing the Flag
Whether through patching or scripting, the hidden logic eventually yielded the secret.
Flag:
ByteMe{w0rTh1n3ss_was_Th3_r34l_v1ct0ry_847}
Final Words
The Broken Throne illustrates a core principle of Reverse Engineering: Don't trust the UI. When a program tells you that you've won but doesn't give you the prize, it’s time to stop playing the game and start rewriting it.

Comments
Post a Comment