cryptofreeeasy

xorxorxor

hackthebox

Task: XOR encryption with 4-byte repeating key and encrypted flag. Solution: Known plaintext attack using flag format HTB{ to recover the full key.

$ ls tags/ techniques/
known_plaintext_attackkey_recovery

$ cat /etc/rate-limit

Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.

xorxorxor — HackTheBox

Description

"Who needs AES when you have XOR?"

Given an encryption program in Python and an encrypted flag.

Analysis

Encryption Source Code

#!/usr/bin/python3 import os flag = open('flag.txt', 'r').read().strip().encode() class XOR: def __init__(self): self.key = os.urandom(4) def encrypt(self, data: bytes) -> bytes: xored = b'' for i in range(len(data)): xored += bytes([data[i] ^ self.key[i % len(self.key)]]) return xored def decrypt(self, data: bytes) -> bytes: return self.encrypt(data) def main(): global flag crypto = XOR() print ('Flag:', crypto.encrypt(flag).hex()) if __name__ == '__main__': main()

Encrypted Flag

Flag: 134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9

Vulnerabilities

  1. Short key (4 bytes) — the key repeats cyclically
  2. Known flag format — the flag starts with HTB{ (exactly 4 bytes)
  3. XOR propertyA ⊕ B ⊕ B = A (self-inverse)

Since the length of known plaintext (4 bytes) equals the key length, we can fully recover the key!

Solution

Attack Mathematics

ciphertext = plaintext ⊕ key
key = ciphertext ⊕ plaintext

Knowing the first 4 bytes of plaintext (HTB{) and the first 4 bytes of ciphertext, we compute the key:

Ciphertext (hex): 13 4a f6 e1
Plaintext (hex):  48 54 42 7b  (HTB{)
Key (hex):        5b 1e b4 9a

Solution Script

#!/usr/bin/env python3 """ HackTheBox: xorxorxor Known Plaintext Attack on repeating-key XOR """ encrypted_hex = "134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9" encrypted = bytes.fromhex(encrypted_hex) # Known plaintext: HTB{ (first 4 bytes = key length) known_plaintext = b"HTB{" # Recover key: key = encrypted XOR plaintext key = bytes([encrypted[i] ^ known_plaintext[i] for i in range(4)]) print(f"Recovered key: {key.hex()}") # Decrypt the entire flag decrypted = b'' for i in range(len(encrypted)): decrypted += bytes([encrypted[i] ^ key[i % 4]]) print(f"Flag: {decrypted.decode()}")

Output

Recovered key: 5b1eb49a
Flag: HTB{rep34t3d_x0r_n0t_s0_s3cur3}

Key Indicators

...

$ grep --similar

Similar writeups