Block Cipher Buccaneers

BearcatCTFby smothy

Block Cipher Buccaneers - Crypto

Points: 421 | Flag: BCCTF{BLoCk_c1pH3r_Mod3} | Solved by: Smothy @ 0xN1umb

ecb penguin energy

what we got

zip with 3 files:

  • left.bmp - unencrypted, shows BCCTF{BL
  • middle.bin - openssl encrypted, the mystery meat
  • right.bmp - unencrypted, shows 3r_Mod3}

challenge says "our best cryptanalysts don't think it's possible to crack the password" which is basically them telling us nah don't even try bruteforcing lol

the solve

the challenge name literally screams ECB mode. classic ECB penguin attack fr

in ECB mode every 16-byte block gets encrypted independently - same plaintext block = same ciphertext block every time. so the image "structure" is preserved even tho the colors are scrambled

python
from PIL import Image
from collections import Counter

# strip the 16-byte openssl header (Salted__ + salt)
with open('images/middle.bin', 'rb') as f:
    f.read(16)
    ct = f.read()

# bmp header is 138 bytes, pixel data starts after that
pixel_ct = ct[138:]

# split into 16-byte blocks (4 pixels each in RGBA)
blocks = [pixel_ct[i:i+16] for i in range(0, len(pixel_ct)-15, 16)]

# most common block = white background
block_counts = Counter(bytes(b) for b in blocks)
white_block = block_counts.most_common(1)[0][0]

# map: white block -> white, everything else -> black
# boom, ecb penguin
img = Image.new('L', (1024, 1024), 255)
pixels = img.load()

for idx in range(min(len(blocks), 256 * 1024)):
    file_row = idx // 256
    img_row = 1023 - file_row  # bmp is bottom-to-top
    col = (idx % 256) * 4
    color = 255 if bytes(blocks[idx]) == white_block else 0
    for px in range(4):
        if col + px < 1024:
            pixels[col + px, img_row] = color

img.save('middle_revealed.png')

and just like that the encrypted image reveals: oCk_c1pH

flag

left + middle + right = BCCTF{BL + oCk_c1pH + 3r_Mod3}

BCCTF{BLoCk_c1pH3r_Mod3}

ngl this is the textbook example of why you never use ECB mode. the penguin lives on


smothy out ✌️