This is a walkthrough for InfoSec Institute’s CTF Challenge, Level 11.
The only immediate difference between this and level 10 is the addition of a grainy PHP logo.
Grainy images are one indicator of steganography, so I proceeded along the route of checking for readable strings. Using the strings command again revealed the flag instantly (but read on!). However, opening it in emacs revealed that it was in the header of the image file.
This is hardly the same as steganography, which hides the message in the image data. This flag is hidden in the image’s EXIF (Exchangable Image Format) data, which provides metadata about the image. If you have exiftool installed (apt-get install exiftool, IIRC), you can get the same information:
exiftool php-logo-virus.jpg | grep -i infosec
The “document name” field contains the string, plus two additional bytes. If you had trouble viewing the image properties, it was likely because the viewer wasn’t prepared for the extra bytes at the end of the string. Remember, the “strings” command only reveals printable characters.
Depending on whether or not the flag includes the extra bytes, there are two options:
Bytes 240 and 206 are outside of the printable range, and not valid Unicode, as they’re missing the BOM. The control characters correspond to the end of the field, which is NUL-terminated. These characters are present because of the way emacs is forced to display something, but you can see the true value with a hex editor. I used hexedit in the following screenshot:
The additional unprintable characters are in red and NUL bytes in yellow. Since the bytes are part of the field (as far as any EXIF parser is concerned), these bytes are part of the field. That leaves us with bytes A0 86 01 unaccounted for.
Note: Your raw data may differ from mine, due to endianness. If your hex editor displayed this, it’s correct, but you’ll notice each pair is switched.
6e69 6f66 6573 5f63 6c66 6761
7369 615f 5248 6330 6f44 4c76 6433 6433
3579 6279 7832 5a73 4a58 617a 6b32 5975
3832 6475 7357 6176 3157 5a68 5632 597a
3969 6277 6433 636c 4e6e 6173 5257 586c
7832 5a76 3932 6266 4647 5a79 5532 5a75
6c32 a06d 0186 0000 0100
Before we cross over the threshold into text-encoding hell, extended ASCII sets, control characters, and all the levels dedicated specifically to Unicode, let’s take a step back. (Sorry guys, I only led you down this road to take a look at the actual contents of the field!)
Occam’s razor says the field was obfuscated to prevent what I’ll dub a “View Properties Attack”, and we’re dealing with a printable-characters-only string. This is a n00bs challenge, afterall.
Although it lacks the characteristic ending equals signs of a base64-encoded string, the flag we have does contain a valid base64 string. (The ending == signs are for padding, and not always present.)
Decoding that string yields the following URL:
Which links to the following image: