247CTF - The Impossible User

An encryption service encrypts plaintext, but blocks encryption of the impossible_flag_user string. Exploit the ECB mode implementation to forge an encrypted token that decrypts to this forbidden value.

Vulnerability

The service uses AES in ECB mode, which has critical weakness: identical plaintext blocks produce identical ciphertext blocks. By crafting specific payloads, we can:

  1. Encrypt the first 16 bytes of the target string
  2. Encrypt padding-aligned subsequent bytes
  3. Concatenate the cipher blocks to forge a valid token

Exploit Strategy

The target user is: impossible_flag_user (23 bytes)

  1. Block 1: Encrypt impossible_flag_ (16 bytes) → get first cipher block
  2. Block 2: Encrypt user + PKCS#7 padding → get second cipher block
  3. Combine: Concatenate blocks to form forged token → decrypt equals target

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import binascii
import requests

BASE_URL = "https://2c5a74f7cc3f1fdf.247ctf.com"

def solve():
# Block 1: First 16 bytes of target
part1_plain = b"impossible_flag_"
payload1 = binascii.hexlify(part1_plain).decode()
r1 = requests.get(f"{BASE_URL}/encrypt?user={payload1}")
cipher_part1 = r1.text[:32] # 32 hex chars = 16 bytes
print(f"[*] Block 1 Cipher: {cipher_part1}")

# Block 2: Remaining 7 bytes + PKCS#7 padding to 16 bytes
padding_len = 16 - (20 % 16)
part2_plain = b"user" + bytes([padding_len] * padding_len)
payload2 = binascii.hexlify(part2_plain).decode()
r2 = requests.get(f"{BASE_URL}/encrypt?user={payload2}")
cipher_part2 = r2.text[:32]
print(f"[*] Block 2 Cipher: {cipher_part2}")

# Forge token by concatenating blocks
final_token = cipher_part1 + cipher_part2
print(f"[*] Forged Token: {final_token}")

# Get flag
r_flag = requests.get(f"{BASE_URL}/get_flag?user={final_token}")
print(f"\n---> FLAG: {r_flag.text}")

if __name__ == "__main__":
solve()
247CTF{ddd01e396dc1965c3fcf943f3968aa39}