c0rrupt picoCTF 2019 Solution

Published: April 2, 2026

Description

Fix this corrupted PNG file and read the flag: c0rrupt.png.

Download the file and inspect it with pngcheck and a hex editor.

bash
wget <url>/c0rrupt.png
bash
pngcheck c0rrupt.png
bash
xxd c0rrupt.png | head -4
  1. Step 1Identify corruption with pngcheck
    Run pngcheck on the file to see which parts are corrupt. It will report errors such as bad magic bytes, invalid chunk signatures, incorrect chunk lengths, or failed CRC checks.
    bash
    pngcheck -v c0rrupt.png
    Learn more

    A valid PNG file has a specific structure: 8 magic bytes at the start (89 50 4E 47 0D 0A 1A 0A), followed by chunks. Each chunk has a 4-byte length, a 4-byte type name (like IHDR, IDAT, IEND), the data, and a 4-byte CRC32 checksum.

    pngcheck validates all of these fields and reports exactly where the file deviates from the PNG specification.

  2. Step 2Fix the magic bytes
    Use a hex editor (ghex, hexedit, or bless) to open c0rrupt.png. Check bytes 0-7. If they do not match 89 50 4E 47 0D 0A 1A 0A, overwrite them with the correct values.
    bash
    hexedit c0rrupt.png
    Learn more

    The PNG magic number is deliberately chosen to be hard to confuse with text files: byte 0x89 is non-ASCII, the next four bytes spell PNG in ASCII, and the remaining bytes include CR, LF, and SUB control characters that behave differently across text-mode file transfers - helping detect corruption.

  3. Step 3Fix chunk signatures and CRCs
    After fixing the magic bytes, run pngcheck again. Fix any remaining chunk type name errors (e.g., a corrupted IHDR signature). Recompute and fix any CRC32 values using Python.
    python
    python3 -c "
    import struct, zlib
    # To compute correct CRC for a chunk:
    # chunk_type = b'IHDR'
    # chunk_data = b'...'  # chunk data bytes
    # crc = zlib.crc32(chunk_type + chunk_data) & 0xFFFFFFFF
    # print(hex(crc))
    "
    Learn more

    CRC32 (Cyclic Redundancy Check) is a hash function used to detect accidental changes. The PNG spec requires that each chunk's CRC be computed over the chunk type and data bytes combined. If the data is correct but the CRC is wrong, recomputing and overwriting fixes the error.

    In Python, zlib.crc32(data) computes the CRC32 value. Always AND with 0xFFFFFFFF to get an unsigned 32-bit result, then pack with struct.pack('>I', crc) for big-endian byte order.

  4. Step 4Open the repaired PNG
    Once pngcheck reports no errors, open the file in an image viewer. The flag will be visible in the image.
    bash
    xdg-open c0rrupt.png

Flag

picoCTF{...}

Fix the PNG magic bytes and repair chunk CRC values with a hex editor to restore the image.

Want more picoCTF 2019 writeups?

Tools used in this challenge

Related reading

What to try next