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:

C - 
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 JNZ instruction to JZ (Jump if Zero), or

  • NOP (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:

Python-
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

Popular posts from this blog

CyberKavach QuestCon Series: Upside-Down Vault

From Open Networks to Safe Systems: How Firewalls Block the Hacker’s Doorway

CyberKavach QuestCon Series: VecNet