← Back to Writeups
CUSTOMEasyCrypto

Gods of XOR

XESXOR9/2/20262 min read
#crypto#custom#easy#known_plaintext_attack#repeating_key_xor#xor_key_recovery

Gods of XOR

Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: known_plaintext_attack, repeating_key_xor, xor_key_recovery

Summary

Walkthrough of the CUSTOM Crypto Gods of XOR. Task: XOR-encrypted files with known plaintext. Solution: recover repeating key via XOR of plaintext and ciphertext, then decrypt the second file.

Description

Given three files:

  • task1.jpg — known plaintext (image)
  • enc1 — encrypted file of the same size as task1.jpg
  • enc2 — encrypted file of larger size

Analysis

Classic XOR challenge with known plaintext. If enc1 = task1.jpg XOR key, then we can recover the key:

key = enc1 XOR task1.jpg

Since enc1 and task1.jpg are the same size, the key is either equal to the file length or repeats. After XOR we get a repeating pattern — this is the key. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Step 1: Key Recovery

python
#!/usr/bin/env python3

# Read known plaintext and encrypted file
with open('task1.jpg', 'rb') as f:
    plaintext = f.read()

with open('enc1', 'rb') as f:
    ciphertext1 = f.read()

# Recover key via XOR
key_stream = bytes([p ^ c for p, c in zip(plaintext, ciphertext1)])

# Find repeating pattern in the key
def find_key_length(data, max_len=256):
    for key_len in range(1, max_len):
        is_repeating = True
        for i in range(len(data)):
            if data[i] != data[i % key_len]:
                is_repeating = False
                break
        if is_repeating:
            return key_len
    return len(data)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

key_len = find_key_length(key_stream)
key = key_stream[:key_len]
print(f"Key length: {key_len}")
print(f"Key: {key}")

Step 2: Decrypting enc2

python
with open('enc2', 'rb') as f:
    ciphertext2 = f.read()

# Decrypt with repeating key
decrypted = bytes([c ^ key[i % len(key)] for i, c in enumerate(ciphertext2)])

with open('decrypted.jpg', 'wb') as f:
    f.write(decrypted)

print("Decrypted file saved as decrypted.jpg")

Step 3: Result

The decrypted file is an image with a scene from Norse mythology (Fenrir, northern chaos gods). The flag is visible in the image. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Notes

  • "Northern chaos gods" — reference to Norse mythology (Fenrir, Loki)
  • The attack works because XOR is reversible: A XOR B XOR B = A
  • With known plaintext, any XOR cipher is trivially broken ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering known_plaintext_attack, repeating_key_xor, xor_key_recovery was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-03-09 • CUSTOM • Gods of XOR • Difficulty: Easy