TexSaw2025 XORer writeup - Pez1181/CTF GitHub Wiki

XORer — Binary Reversing Writeup

Challenge Type: Reverse Engineering
Vulnerability: XOR-based password obfuscation
Protection Bypassed: None — just logic, mate.
Tools Used: Ghidra, Python, xor.pw, terminal
Difficulty: Introductory


🧭 Recon

We were given a stripped 64-bit ELF binary named XORer. Running the binary prompts us to input a password. If correct, we’re rewarded with a texsaw{...} flag.

$ ./XORer
Enter password:

No output hints — so it’s time to open up the binary and see what’s under the hood.


🔬 Vulnerability Analysis

Loading the binary into Ghidra, we quickly hone in on the check_password() function. Here's the important snippet:

local_1c[0] = 0xcb;
local_1c[1] = 0x95;
local_1c[2] = 0xd1;
...
local_1c[11] = 0xc2;

if (((int)param_1[i] ^ 0xa5U) != (uint)local_1c[i]) {
    puts("Wrong password!");
    return;
}

So each input character is XORed with 0xA5, then compared to a hardcoded byte.

This is textbook reversible logic:
If a ^ k = b, then b ^ k = a.


🧨 Exploit Strategy

We simply need to reverse the XOR operation on the byte array:

decoded_char = encoded_byte ^ 0xA5

Do that for all 12 bytes and we’ve got the password.


🧑‍💻 Exploit Script

Here’s a Python script that automates the decryption:

# xor_decoder.py

def xor_decrypt(encoded_bytes, key):
    return ''.join(chr(b ^ key) for b in encoded_bytes)

if __name__ == "__main__":
    # XOR-obfuscated password bytes from the binary
    encoded = [0xcb, 0x95, 0xd1, 0xfa,
               0xd1, 0xcd, 0x96, 0xfa,
               0xc3, 0xc9, 0x91, 0xc2]
    
    key = 0xA5  # XOR key used in the binary

    password = xor_decrypt(encoded, key)

    print(f"[+] Decoded password: {password}")

🖥️ Example Output

$ python3 xor_decoder.py
[+] Decoded password: l3t_m3_1n

Using the password:

$ ./XORer
Enter password: n0t_th3_fl4g
Correct! Here's your flag: texsaw{n0t_th3_fl4g}

🧪 Final Notes

  • XOR challenges like this are common in beginner RE/CTF tasks.
  • If you're new to this, https://xor.pw is an excellent online tool to visualize XORing.
  • Always check for constants like 0xA5, 0xDEADBEEF, or even 0x1337 — they often indicate intentional obfuscation or comparisons.

Maybe move on to patching the binary to always print the flag, or try extracting the logic dynamically using angr, unicorn, or a GDB script.

Mission complete. Bytes flipped 🫡