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
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Identify corruption with pngcheckObservationI noticed the file was described as 'corrupted', which suggested I needed a structured validator that could report exactly which chunks and fields deviate from the PNG specification before attempting any manual repairs.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.bashpngcheck -v c0rrupt.pngExpected output
c0rrupt.png CRC error in chunk hIHD (computed 6efeef73, expected 51490945) ERROR: c0rrupt.png invalid chunk name "CgBI" (43 67 42 49) FATAL: c0rrupt.png is not a PNG image
What didn't work first
Tried: Open the file directly in an image viewer to see what is broken
Most image viewers either refuse to open a corrupted PNG or silently display a partial/blank image with no diagnostic output. They do not tell you which bytes are wrong or which chunks failed. pngcheck reads the raw binary structure and reports the exact offset and field name for each violation, which you need in order to make targeted edits.
Tried: Run 'file c0rrupt.png' to diagnose what is wrong with the file
The 'file' command only checks the magic bytes to guess the file type - it reports 'PNG image data' even if the internal chunks are completely corrupted. It will not catch bad CRC values, invalid chunk type names, or a corrupted IHDR. pngcheck performs a full structural validation that 'file' is not designed to do.
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.
Step 2
Fix the magic bytesObservationI noticed pngcheck reported an invalid file type before even reaching the chunks, which pointed to the very first 8 bytes being wrong and needing to be overwritten with the canonical PNG magic number.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.bashhexedit c0rrupt.pngWhat didn't work first
Tried: Use 'strings c0rrupt.png' to find the correct magic bytes
The 'strings' command only prints printable ASCII sequences of a minimum length. The PNG magic bytes include non-printable control characters (0x89, 0x0D, 0x0A, 0x1A, 0x0A) that 'strings' will skip entirely. You must use a hex editor like hexedit or xxd to view and edit raw bytes at specific offsets.
Tried: Patch the magic bytes with sed or a text editor
Text editors and sed operate in text mode and may silently alter or strip non-printable bytes when saving. The PNG header contains bytes outside the printable ASCII range, so any text-mode tool will corrupt or drop them. Use a binary-aware tool like hexedit, ghex, or a Python script with open(filename, 'rb') to safely overwrite specific byte offsets.
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.
Step 3
Fix chunk signatures and CRCsObservationI noticed pngcheck's output listed a CRC mismatch in the hIHD chunk alongside an invalid chunk name, which suggested the chunk type bytes and their corresponding checksums had been tampered with and needed to be corrected using zlib.crc32.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.pythonpython3 -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)) "What didn't work first
Tried: Compute the CRC with zlib.crc32(chunk_data) without including the chunk type bytes
The PNG specification requires the CRC to be computed over the chunk type AND the chunk data concatenated together - not the data alone. Passing only the data bytes to zlib.crc32 produces a different checksum than what pngcheck expects. The fix is zlib.crc32(chunk_type + chunk_data) where chunk_type is the 4-byte ASCII name like b'IHDR'.
Tried: Skip fixing CRC values and just open the PNG, hoping the viewer ignores checksum errors
Lenient viewers like eog may render the image despite bad CRCs, but pngcheck still reports failures and the file is technically invalid. More importantly, if the IHDR chunk CRC is wrong, some decoders reject the file entirely before reading dimensions or color depth. Fixing CRCs is also how you confirm you have the correct chunk data - if the recomputed CRC matches nothing, the data itself is still corrupted.
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 4
Open the repaired PNGObservationI noticed pngcheck finally reported no errors after fixing the magic bytes and CRCs, which confirmed the binary structure was valid and the image could now be decoded and displayed to reveal the flag.Once pngcheck reports no errors, open the file in an image viewer. The flag will be visible in the image.bashxdg-open c0rrupt.png
Interactive tools
- File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
Flag
Reveal flag
picoCTF{c0rrupt10n_...}
Fix the PNG magic bytes and repair chunk CRC values with a hex editor to restore the image.