Table of Contents
W1seGuy #
🏴 Platform: TryHackMe
🔬 Category: Crypto (XOR)
🟢 Difficulty: Easy
📅 Date: 2026-02-12
✍️ Author: tonton
⏱️ Reading time: ~2 min
Reconnaissance #
The server sends an XOR-encrypted text in hexadecimal and asks for the encryption key.
Source code analysis (source-1705339805281.py):
- The flag is XORed with a random 5-character alphanumeric key (
ascii_letters + digits) - The key repeats cyclically over the entire flag length (
key[i % len(key)]) - The result is hex-encoded
- If you send back the correct key, the server gives you flag 2
Key insight: the flag always starts with THM{ — that's our known plaintext.
Exploitation #
Concept: Known Plaintext Attack on XOR #
The fundamental property of XOR:
plaintext XOR key = ciphertext
ciphertext XOR plaintext = key
By knowing THM{ (4 chars), we directly recover 4 out of 5 key characters. The 5th one is brute-forced over ~62 possibilities.
Exploit Script #
1import string
2
3cipher = bytes.fromhex("<hex received from server>")
4
5# Recover the first 4 key chars via known plaintext
6known = "THM{"
7key = ""
8for i in range(4):
9 key += chr(cipher[i] ^ ord(known[i]))
10
11# Brute-force the 5th character
12for c in string.ascii_letters + string.digits:
13 test_key = key + c
14 result = ""
15 for i in range(len(cipher)):
16 result += chr(cipher[i] ^ ord(test_key[i % 5]))
17 if result.endswith("}"):
18 print(f"Key: {test_key}")
19 print(f"Flag: {result}")
20 break
Execution #
Connection 1 — ciphertext: 607e3a2d3f...
- Key recovered:
46wVO - Flag 1 decrypted:
FLAG{REDACTED}
Connection 2 — ciphertext: 3a22172f33...
- Key recovered:
njZTC - Sent key to server → obtained flag 2
Flag #
- Flag 1:
FLAG{REDACTED} - Flag 2:
FLAG{REDACTED}
Tools Used #
- Python 3 (XOR script + brute-force)
- Static analysis of the provided source code
What Didn't Work #
- Nothing in particular, the known plaintext approach works on the first try once you identify the
THM{prefix
Lessons Learned #
- XOR with a short key + known plaintext = instantly broken. This is the "Known Plaintext Attack", and the challenge itself tells you in the flag (
p1alntExtAtt4ck) - Always look for known patterns in the plaintext (file headers, flag prefixes like
THM{,FLAG{,HTB{, etc.) - A cyclically repeating XOR key cannot hold up if
len(known_plaintext) >= len(key)
last updated: