TU-CTF 2017 - Steganography 100
- 10 minsTU-CTF 2017: Worth A Thousand Words
3 pictures in the folder. Each has a part of the flag.
For this challenge, we are given three pictures: 1.jpg
, 2.jpg
and 3.png
.
The challenge title is already saying a lot about what we need to do but with the description it’s even more obvious: the flag is scattered through the 3 pictures.
First Picture - 1.jpg
In steganography challenges, I always start with the most simple ways to extract a flag before moving on to deeper analysis.
Since the format of the flag is TUCTF{}, we could check if any string is embedded in the file:
$ strings 1.jpg | grep TU
TUCTF{********************************************
Part 1/3 done.
Second Picture - 2.jpg
$ strings 2.jpg
...
...
...
flag.txtUT
LNUH
H-JU/V(
HU(NM
KQ(H,*Q
YIQ}
flag.txtUT
So a file named flag.txt
is embedded in the picture. All we have to do is extract it:
$ binwalk -e 2.jpg
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
1148150x1C07F Zip archive data, at least v2.0 to extract, compressed size: 53, uncompressed size: 54, name: flag.txt
1150120x1C144 End of Zip archive
$ cd _2.jpg.extracted
$ cat flag.txt
Nice find, heres the second part of the flag: Devils
Part 2/3 done. So far we have `TUCTF{Devils`
Third Picture - 3.png
This one was a bit more challenging. Let’s get to it. 💪
Using file
and exiftool
to make sure we are dealing with a PNG file since it is corrupted and won’t open in ImageViewer and GIMP:
$ file 3.png
3.png:
$ exiftool 3.png
File Name : 3.png
Directory : .
File Size : 4.2 MB
Error : File format error
Looking at the hexadecimal dump of the file points us in the right direction:
$ hexdump -C 3.png | head
00000000 89 50 4e 47 53 41 52 45 43 4f 4f 4c 49 48 44 52 |.PNGSARECOOLIHDR|
00000010 52 00 07 80 00 00 04 38 08 06 00 00 01 9f d4 f1 |R......8........|
00000020 d5 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 |.....bKGD.......|
00000030 bd a7 93 00 00 00 09 70 48 59 73 00 00 0b 13 00 |.......pHYs.....|
00000040 00 0b 13 01 00 9a 9c 18 00 00 00 07 74 49 4d 45 |............tIME|
00000050 07 e1 0b 15 16 2c 06 c9 22 e5 62 00 00 20 00 49 |.....,...b.. .I|
00000060 44 41 54 78 da 44 bb d7 ce 6c 59 62 df f7 5b 79 |DATx.D...lYb..[y|
00000070 87 da 55 f5 a5 93 ba 4f 87 e9 e9 9e 4c 0e 39 33 |..U....O....L.93|
00000080 1c ca 12 2d d1 32 20 d2 a0 2d 58 10 2c 19 06 7c |...-.2 ..-X.,..||
00000090 6b df fa 0d 1a f0 a5 1f c2 06 01 c1 12 60 5f 38 |k............`_8|
According to the PNG Specification, the first 8 bytes of a PNG file always contain the following decimal values 137 80 78 71 13 10 26 10
which is not the case for this file.
Since we will be editing the hexadecimal values of the picture, we need to convert the decimal value of the specification to its hexadecimal value:
$ printf '%x\n' 137 80 78 71 13 10 26 10
89
50
4e
47
0d
0a
1a
0a
After editing the hex values with GHEX:
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 07 80 00 00 04 38 08 06 00 00 01 9f d4 f1 |R......8........|
00000020 d5 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 |.....bKGD.......|
00000030 bd a7 93 00 00 00 09 70 48 59 73 00 00 0b 13 00 |.......pHYs.....|
00000040 00 0b 13 01 00 9a 9c 18 00 00 00 07 74 49 4d 45 |............tIME|
00000050 07 e1 0b 15 16 2c 06 c9 22 e5 62 00 00 20 00 49 |.....,..".b.. .I|
00000060 44 41 54 78 da 44 bb d7 ce 6c 59 62 df f7 5b 79 |DATx.D...lYb..[y|
00000070 87 da 55 f5 a5 93 ba 4f 87 e9 e9 9e 4c 0e 39 33 |..U....O....L.93|
00000080 1c ca 12 2d d1 32 20 d2 a0 2d 58 10 2c 19 06 7c |...-.2 ..-X.,..||
00000090 6b df fa 0d 1a f0 a5 1f c2 06 01 c1 12 60 5f 38 |k............`_8|
Opening the picture is still impossible even though the file and exiftool commands show us that it’s now a clean PNG file.
pngcheck will allow us to check if there are errors in the picture:
$ pngcheck -7tvc 3.png
File: 3.png (4410396 bytes)
chunk IHDR at offset 0x0000c, length 13
1375733632 x 1080 image, 32-bit RGB+alpha, interlaced
CRC error in chunk IHDR (computed f60273ef, expected 9fd4f1d5)
Beside the picture having a ridiculous width to height ratio, there is a CRC error in the IHDR chunk. Thanks to pngcheck’s calculations, we are able to edit the wrong value with the calculated one. We need to find the expected value (9F D4 F1 D5
) and change it for the computed one (F6 02 73 EF
).
$ pngcheck -7tvc 3.png
..
No errors detected in 3.png (543 chunks, 100.0% compression).
Opening the file with GIMP gives us the following error:
Opening '/root/thousandwords/3.png' failed: Error while reading '/root/thousandwords/3.png'. File corrupted?
Back to the challenge description, a hint was given:
Aspect ratio for pic 3 is 16:9
Great, so we have to change the picture’s resolution. After trying a few combinations (640x360, 768x432, etc) and reading about common 16:9 resolutions the right resolution was 1920x1080.
We need to change the pHYs chunk value to the following resolution: 07 80 00 00 04 38 06 00
and go through the same pngcheck CRC error correction.
Opening the file gives us the following picture:
Notice the monitor? That’s a MaxiCode and all we have to do is crop the MaxiCode and decode it with ZXing’s Decoder.
No barcode was found in this image. Either it did not contain a barcode, or did not contain one in a supported format, or the software was simply unable to find it. Go “Back” in your browser and try another image.
Looking at other MaxiCodes online, all of them have a white background while ours is brownish.
It’s finally time to put our Photoshop/GIMP skills to use!
- Open the MaxiCode image in GIMP
- Colors>Levels
- Drag the Input Levels arrow to the left until the picture’s background is white.
- Profit???
Sending the edited MaxiCode image to the decoder gives us the following result:
Flag: TUCTF{DevilsInThePixels}