Description
We found this file. Recover the flag.
Setup
Download the file tunn3l_v1s10n.
Solution
- Step 1Identify the file formatUse xxd to inspect the first bytes of the file. The header starts with 42 4d -- the magic bytes for the BMP (bitmap) image format. Rename the file to tunn3l_v1s10n.bmp so image viewers will open it.xxd tunn3l_v1s10n | headcp tunn3l_v1s10n tunn3l_v1s10n.bmp
Learn more
Magic bytes (file signatures) are the first bytes of a file that identify its format, independent of the file extension.
42 4Dis ASCII "BM" -- the BMP signature. Other common signatures:FF D8 FF(JPEG),89 50 4E 47(PNG),25 50 44 46(%PDF). Thefilecommand uses a database of these signatures to identify files. - Step 2Open the BMP and notice the truncated imageOpen tunn3l_v1s10n.bmp in an image viewer. It shows only a small portion of the image with a decoy message at the top. The real flag is hidden in the lower portion of the image, which is not being rendered because the height field in the BMP header has been tampered with to be smaller than the actual image data.
- Step 3Fix the BMP height field in a hex editorThe BMP DIB header stores the image height as a 4-byte little-endian integer at offset 0x16 (22 decimal). The current value 32 01 00 00 decodes to 306 -- too small. Change it to 6e 04 00 00 (which decodes to 1134, the actual height). Save and reopen the image to see the full picture with the flag.xxd tunn3l_v1s10n.bmp | grep -A2 '0000010'# Use a hex editor (e.g. hexedit, ghex, or bless) to change offset 0x16 from 32 01 to 6e 04hexedit tunn3l_v1s10n.bmp
Learn more
The BMP DIB header (BITMAPINFOHEADER) starts at byte 14 and contains width at offset 4 (bytes 18–21 of the file) and height at offset 8 (bytes 22–25 of the file). Both are 32-bit little-endian signed integers. Little-endian means the least significant byte comes first:
32 01 00 00= 0x00000132 = 306 decimal.By shrinking the declared height, the image viewer only renders the first 306 rows of pixel data, hiding the bottom portion. The pixel data itself is all still present in the file -- the header is lying about the dimensions. This technique is common in CTF forensics challenges and occasionally used in real-world data hiding.
To calculate the correct height: BMP pixel data starts at the offset stored in bytes 10–13 of the file header. Total file size minus pixel data offset divided by (width * bytes-per-pixel) gives the true row count.
Flag
picoCTF{...}
BMP headers define the image dimensions -- shrinking the height field hides the bottom portion of the image that contains the real flag.