← Back to Writeups
CUSTOMEasyCrypto

SLA

XESXOR9/10/20261 min read
#crypto#custom#easy#known_plaintext_attack#xor_key_recovery

SLA

Platform: spbctf | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-03-09 | Status: Solved Techniques: known_plaintext_attack, xor_key_recovery

Summary

Task: XOR stream cipher with ciphertext provided. Solution: Recover key using known plaintext attack with flag prefix matching key length.

SLA — CryptoKids 2.0

Description

Stream cipher task with XOR encryption. Ciphertext provided, need to recover the flag.

Analysis

  • XOR encryption with 7-character key "locator"
  • Plaintext is doubled: flag + flag (concatenated with itself)
  • Known prefix "spbctf{" is exactly 7 characters = key length
  • This allows direct key recovery via XOR with known plaintext

Solution

Since we know the first 7 bytes of plaintext ("spbctf{") and the key is 7 bytes long, we can recover the entire key by XORing the known plaintext with the first 7 bytes of ciphertext. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

python
#!/usr/bin/env python3
# XOR key recovery with known plaintext prefix

def xor_bytes(a, b):
    return bytes([x ^ y for x, y in zip(a, b)])

# Read ciphertext
with open('ciphertext.bin', 'rb') as f:
    ct = f.read()

# Known prefix = key length
known_prefix = b'spbctf{'
key_len = len(known_prefix)  # 7

# Recover key: key = ct[:7] XOR known_prefix
key = xor_bytes(ct[:key_len], known_prefix)
print(f"Recovered key: {key}")  # b'locator'

# Decrypt full ciphertext
plaintext = b''
for i, c in enumerate(ct):
    plaintext += bytes([c ^ key[i % key_len]])
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Plaintext is flag+flag, take first half
flag = plaintext[:len(plaintext)//2].decode()
print(f"Flag: {flag}")

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍