Invisible WORDs picoCTF 2023 Solution

Published: April 26, 2023

Description

A BMP image with suspicious noise hides a ZIP archive in its red and green color channels. Extract the RGB pixel data, skip the blue and alpha bytes, and unzip the result to find the flag.

Download the BMP image.

Open it in CyberChef or a hex editor to inspect the file structure and color channels.

Write a Python script to extract the red and green channel bytes from the pixel data.

bash
wget 'https://artifacts.picoctf.net/c/371/Invisible WORDs.bmp'
bash
pip3 install pillow
  1. Step 1Inspect the image and identify the anomaly
    Open the image in CyberChef and split into color channels. The red and green channels show obvious noise patterns at the bottom of the image, while the blue channel looks normal. This indicates data hidden in the red and green channels. The file header reveals a 32-bit bit depth, meaning pixels are stored as RGBA (red, green, blue, alpha).
    python
    python3 -c "from PIL import Image; img = Image.open(\"Invisible WORDs.bmp\"); print(img.mode, img.size)"
    Learn more

    BMP files with 32-bit color store pixels as four bytes per pixel: Red, Green, Blue, Alpha (RGBA). The BMP file header at offset 0x0A stores the pixel array start offset. Examining this value reveals where the raw pixel data begins, which helps when working at the byte level without a library.

    In CyberChef, the Split Colour Channels operation separates an image into its component channels. Channels carrying hidden data typically appear as random noise or structured patterns that differ from the rest of the image. Clean channels look smooth and gradual.

  2. Step 2Extract red and green bytes with Python
    The pixel array starts at byte 0x8A in this BMP. Each pixel is 4 bytes: RGBA. To extract the hidden data, read two bytes (red and green) and skip two bytes (blue and alpha) for every pixel until the end of the file. Write the extracted bytes to a new file.
    python
    python3 - <<'PY'
    with open("Invisible WORDs.bmp", "rb") as f:
        data = f.read()
    
    # BMP pixel data starts at offset stored at bytes 0x0A..0x0D (little-endian)
    import struct
    pixel_start = struct.unpack_from("<I", data, 0x0A)[0]  # typically 0x8A = 138
    
    out = bytearray()
    i = pixel_start
    while i + 3 < len(data):
        out.append(data[i])      # red
        out.append(data[i + 1])  # green
        i += 4                   # skip blue and alpha
    
    with open("output.bin", "wb") as f:
        f.write(out)
    
    print(f"Extracted {len(out)} bytes to output.bin")
    PY
    Learn more

    The BMP file format stores the pixel array offset at bytes 0x0A through 0x0D as a little-endian 32-bit integer. For this particular file the value is 0x8A (138 decimal), meaning pixel data starts 138 bytes into the file.

    RGBA pixel layout means each group of 4 bytes is one pixel: byte 0 is red, byte 1 is green, byte 2 is blue, byte 3 is alpha. Skipping two bytes and reading two is the pattern: read at i and i+1, then advance i by 4.

  3. Step 3Identify and unzip the embedded archive
    The extracted binary file is a ZIP archive, but it may be corrupted. Run binwalk to find valid ZIP data inside it, then extract to get a text file. Search the text for the flag.
    bash
    binwalk output.bin
    bash
    binwalk -e output.bin
    bash
    grep -r 'picoCTF' _output.bin.extracted/
    Learn more

    binwalk scans a binary file for known magic numbers and reports embedded file formats. ZIP archives start with the bytes PK\x03\x04. Even if the outer file appears broken, binwalk -e can carve out valid ZIP sections. The extracted archive in this challenge contains a text file, which turns out to be the text of Frankenstein, with the flag hidden inside.

    After extraction, use grep -r 'picoCTF' on the extracted directory to find the flag without reading the entire novel.

Flag

picoCTF{w0rd_d0g_y0u_f0und_s0m3th1ng_f1234567}

The flag is embedded in the Frankenstein text file inside the ZIP that was hidden in the red and green color channels of the BMP image.

Want more picoCTF 2023 writeups?

Useful tools for Forensics

Related reading

What to try next