TLDR: Novice learn about magic bytes for the first time and learn about the importance of understanding the mechanism behind implementations
Thursday Night, an image file upload vulnerability in an attack box.
I had a linear plan. Fuzz the file extension and use whatever got through for command injection. Reality hit me as I soon found out it was not so simple. My SVG XXE payload got through, but I could not say the same for my PHP payload. So, I use XXE to peek into the file type mechanism.
Aha. A MIME type test. I have seen that in the books.
I immediately turned to my only trick in the book - adding the GIF8 prefix before the payload.
The trick would’ve worked if the application allowed GIFs as well. However, this specific application logic did not consider GIF as a valid upload.
If you are familiar with Magic Byte you probably already know where the story will go – The Magic Bytes.
Before today, I thought nothing more of the GIF8 prefix since I thought applications would read and check the exact string in the first line of the file. Turns out I had a complete misunderstanding about how it was operating.
Applications mostly still check the file content; they read the first few (magic) bytes instead of the raw string I had assumed. In their eyes, they see the HEX signatures of the file.
The GIF8 trick worked as “GIF8” just happens to be the signature for GIF files. For the same reason, the SVG XXE worked as I was hiding the payload inside a standard SVG element to bypass the test.
Knowing this, it became obvious what I had to do. I first tried to capture the POST request of a legitimate image file, remove all lines except the first line in the image file and place my payload below. The payload got through!
To ensure that I know how to do it through the console, I used xxd to transform the string signature of the JPG file on Wiki into hex values. I then combine the hex code and payload content into the same file with an appropriate extension. Upload the file directly to the upload and voilà! it worked like a charm.
Afterword: I wrote this post as it amazed me when I first found out the missing piece in my exploit. This had taken me longer than I want to admit to solve. I learnt deeply that it is important to understand how an application works when you are crafting a payload against it. When in doubt, one should always remain calm and walkthrough your logic again to see if anything was missed.