tunn3l_v1s10n — PicoCTF 2021
This challenge didn’t bore me and actually motivated me to know the ‘under the hood’ stuff. So, I’m writing this to document my thoughts during the process…
The problem statement was like:
Description
We found this file. Recover the flag.
I have downloaded the file. Running ‘file’ command gave the type ‘data’. Nothing specific.
So, I have tried ‘exiftool’ on the file.
exiftool tunn3l_v1s10n
The output gave away that the file type is ‘bmp’ i.e., a Bitmap image.
I renamed it with ‘.bmp’ as extension and tried opening it. But, it gave the error below.
So, this has something to do with the headers, which I’m not at all familiar with.
But, to take a look, I used ‘hexedit’ to view the data of the file in hex format. (hexedit displays both hex values and their ASCII representation).
hexedit tunn3l_v1s10n
So much that I don’t understand. So, I googled to make some sense about ‘bitmap’ headers and stumbled upon this website, which is great. It has all the details about bitmap headers and a newbie like me was able to understand some of it.
I took a ‘normal’ bitmap image and compared its hex with the hex of the provided file. I noticed something and then, it seemed strange.
At an offset of 14 bytes, the ‘InfoHeader’ begins, with the first 4 bytes specifying the ‘Size’ of the ‘InfoHeader’. It should generally look like “28 00 00 00”, which means 0x28=40 bytes (bytes are displayed in little-endian order — least significant bit first). But, in this file, it looked like “BA D0 00 00”, which means 0xD0BA=53434 bytes. ‘InfoHeader’ should be of 40 bytes, so I changed those bytes to “28 00 00 00” and saved it.
Now, I tried to open it and it gave me a decoy flag, “notaflag{sorry}”. Well, we’re making progress and are treading the way they paved.
I tried to convert this ‘.bmp’ image to ‘.jpg’ images online, but wasn’t making progress.
So, I got back to inspecting the hex bytes of the image again. Something else caught my eye this time.
At an offset of 10 bytes from the beginning, 4 bytes are reserved to indicate the ‘DataOffset’. In Layman terms, it tells the image parser softwares, ‘an offset’ from which the actual image data (pixels which contain different colors) begin. Those softwares parse the values from the specified offset and render the values to display the image.
For a normal bitmap image, the ‘DataOffset’ looks like “36 00 00 00”, which means 0x36=54 bytes. But, for this image, it was “ BA D0 00 00”, which means (yeah, you know it) 0xD0BA=53434 bytes. This, in general, should mean that the metadata of the image extends from the beginning of the file, upto 53434 bytes, which is ridiculously large. It might means that there is a lot more actual ‘image data’ but, the offset is preventing it from being displayed. (Meaning, the image is being displayed somewhere from the middle and not from its actual beginning. It is in some way, similar to cropping out some portion of the image).
The dimensions of the image were 1134x306. But, I think there’s more to this because of the above theory. So, I thought of messing with the width and height parameters of the image to reveal something. At an offset of 18 bytes, 4 bytes are specified for indicating the ‘Width’ of the image. I tried changing it. On changing this, the image got distorted but, nothing new was being revealed so, changed it back to the original value.
Now, its time to mess with ‘height’. At an offset of 22 bytes, 4 bytes are reserved for indicating the ‘height’ parameter of the image. It was “32 01 00 00”, which means 0x132=306 pixels.
So, I tried changing it to “32 03 00 00”, which means 0x332=818 pixels.
Opening this gave out the flag. (Check the top right corner of the image).