2022 Hack The Boo: Whole Lotta Candy
Challenge Information
| Attribute | Details |
|---|---|
| Event | 2022 Hack The Boo |
| Category | Crypto |
| Challenge | Whole Lotta Candy |
Summary
This challenge involves a TCP server that encrypts plaintexts and flags using AES in various block cipher modes (ECB, CBC, CFB, OFB, CTR). The vulnerability lies in the use of ECB mode, which deterministically encrypts identical plaintext blocks to identical ciphertext blocks. The server selects a random mode and allows users to encrypt the flag or arbitrary plaintexts, making it possible to leak the flag through plaintext pattern analysis.
Analysis
The server provides the following interface:
- Option 1: Encrypt the FLAG
- Option 2: Encrypt user-provided plaintext
- Option 3: Change encryption mode (randomly selects from: ECB, CBC, CFB, OFB, CTR)
- Option 4: Exit
The Encryptor class supports five AES block cipher modes:
def ECB(self, pt): cipher = AES.new(self.key, AES.MODE_ECB) ct = cipher.encrypt(pad(pt, 16)) return ct
def CBC(self, pt): iv = os.urandom(16) cipher = AES.new(self.key, AES.MODE_CBC, iv) ct = cipher.encrypt(pad(pt, 16)) return ct
def CFB(self, pt): iv = os.urandom(16) cipher = AES.new(self.key, AES.MODE_CFB, iv) ct = cipher.encrypt(pad(pt, 16)) return ct
def OFB(self, pt): iv = os.urandom(16) cipher = AES.new(self.key, AES.MODE_OFB, iv) ct = cipher.encrypt(pad(pt, 16)) return ct
def CTR(self, pt): counter = Counter.new(128) cipher = AES.new(self.key, AES.MODE_CTR, counter=counter) ct = cipher.encrypt(pad(pt, 16)) return ctKey Vulnerability: ECB (Electronic Codebook) mode is deterministic - the same plaintext block always encrypts to the same ciphertext block with a given key. This allows attackers to detect patterns in the flag by crafting known plaintexts and comparing ciphertext patterns.
Solution
Approach: ECB Mode Byte-by-Byte Decryption
-
Ensure ECB Mode: Try changing modes until ECB is selected (or brute force with other modes). In ECB mode, identical plaintext blocks produce identical ciphertext blocks.
-
Padding Structure: The server pads plaintexts to 16-byte blocks using PKCS#7. A plaintext of length < 16 gets padded to exactly 16 bytes.
-
Exploit Pattern:
- Craft plaintext of length 15:
AAAAAAAAAAAAA??(where ?? is unknown flag byte) - Request encryption of flag
- The first block of the flag ciphertext contains the unknown flag byte
- Encrypt
AAAAAAAAAAAAAAA<known_char>where<known_char>is each byte from 0-255 - When your ciphertext matches the flag’s first block, you’ve found the byte
- Craft plaintext of length 15:
-
Scale to Full Flag: Repeat for each byte position, adjusting the padding offset.
Practical Implementation Notes
- The server returns ciphertext in hex format
- Flag format follows HTB convention:
HTB{...} - With proper ECB exploitation, each byte can be recovered in at most 256 encryption requests
- The padding oracle attack combined with ECB mode’s determinism is the key to this challenge
Key Takeaways
- ECB mode is insecure for encrypting patterned data; identical plaintext blocks leak information
- Never use ECB mode in production - use CBC, CTR, or authenticated encryption modes instead
- AES CFB, OFB, and CTR modes are more resistant to pattern analysis due to randomized IVs or counters
- Padding oracle attacks and pattern matching can efficiently recover plaintexts from ECB-encrypted data
- Knowledge of plaintext structure (CTF flag format) combined with ECB’s determinism enables efficient attacks