Description
Fix this corrupted PNG file and read the flag: c0rrupt.png.
Setup
Download the file and inspect it with pngcheck and a hex editor.
wget <url>/c0rrupt.pngpngcheck c0rrupt.pngxxd c0rrupt.png | head -4Solution
Walk me through it- Step 1Identify corruption with pngcheckRun 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.pngLearn 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.
- Step 2Fix the magic bytesUse 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.pngLearn 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.
- Step 3Fix chunk signatures and CRCsAfter 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 with0xFFFFFFFFto get an unsigned 32-bit result, then pack withstruct.pack('>I', crc)for big-endian byte order. - Step 4Open the repaired PNGOnce 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.