Закодированный дед
Закодированный дед
Platform: bug-makers | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-27 | Status: Solved Techniques: bmp_header_analysis, known_plaintext_attack, xor_key_recovery
Summary
Task: XOR-encrypted BMP image with encryption script provided but key lost; key is 10 bytes. Solution: known-plaintext attack using predictable BMP header bytes to recover the XOR key 'deadencode', then decrypt the entire file.
Закодированный дед — Bug Makers CTF
Description
У меня есть картинка в старом формате BMP и код, которым ее закодировали. Но ключ от шифра уже утерян. Помогите расшифровать картинку.
English summary: We are given an XOR-encrypted BMP image (encrypted.bmp, 3,072,138 bytes) and the Python encryption script (encrypt.py). The encryption key has been lost and must be recovered to decrypt the image.
Analysis
The encryption script performs simple repeating-key XOR on the entire BMP file starting from byte 0 (including the header). Key observations:
-
Key length is 10 bytes — confirmed by the default placeholder
'xxxxxxxxxx'(10 x's) and the comment"ключ-длиной-10-байт"("key of 10 bytes length"). -
Entire file is XOR'd —
start_index = 0, so the BMP header is encrypted too. This is the critical weakness: BMP headers have a well-known, predictable structure. -
BMP header provides known plaintext — the first 10 bytes of any BMP file are deterministic:
- Bytes 0–1: Magic signature
BM→0x42 0x4D - Bytes 2–5: File size in little-endian → 3,072,138 =
0x002EE08A→8A E0 2E 00 - Bytes 6–9: Reserved fields, always zero →
00 00 00 00
- Bytes 0–1: Magic signature
Since the key is exactly 10 bytes and we know 10 bytes of plaintext at offset 0, we can recover the entire key with a single XOR operation.
Solution
Step 1: Extract known plaintext from BMP header
The first 10 bytes of the original (unencrypted) BMP must be:
Known plaintext: 42 4D 8A E0 2E 00 00 00 00 00
Step 2: Read encrypted header bytes
bash read-only • copy allowedxxd -l 10 encrypted.bmp # Output: 26 28 EB 84 4B 6E 63 6F 64 65
Step 3: Recover the XOR key
Encrypted: 26 28 EB 84 4B 6E 63 6F 64 65
Plaintext: 42 4D 8A E0 2E 00 00 00 00 00
XOR result: 64 65 61 64 65 6E 63 6F 64 65
Converting to ASCII: deadencode — the key is a readable English word, a play on "dead" + "encode".
Step 4: Decrypt the file
python read-only • copy allowed#!/usr/bin/env python3 key = b'deadencode' with open('encrypted.bmp', 'rb') as f: data = bytearray(f.read()) for i in range(len(data)): data[i] ^= key[i % len(key)] with open('decrypted.bmp', 'wb') as f: f.write(data) print("Decrypted successfully!")
Step 5: View the result
The decrypted BMP (1280×800, 24-bit color) shows a Zoolander meme with Russian text "У нас в семье нет программистов" / "Закодированный дед" and the flag at the bottom.