[TUCTF 2017] Misc – Gr8 Pictures 2 (150 points)

Gr8 Pictures 2

Files: flag.png flag50As.png flag50Bs.png gr8pic2.py


Similarly to Gr8 Pictures 1 to find out how we can decrypt the hidden message from the flag.png, we will have to mess around with the service on gr8pics2.tuctf.com:5555. However, this one looks more tricky! The received pictures were different from the flag.png picture. So, for better understanding of the encryption service, we decided to receive two pictures for further analysis (one with 50A’s and one with 50B’s) :-

$ python -c "print 'A'*50" | nc gr8pics2.tuctf.com 5555 | base64 -d > flag50As.png
$ python -c "print 'B'*50" | nc gr8pics2.tuctf.com 5555 | base64 -d > flag50Bs.png

Again, by running a binary diff, but now for both of our pictures (not the flag.png) we came up with the following findings :-

We quickly notice, that the 1st CRC of IDAT png sections is the place for our hidden message. Firstly, we thought that we can create again the XOR key, by XORing the (A) 0×41 ^ 0×67 but that didn’t work. So the next try was to run pngcheck on the image as it was broken because of the CRC :-

$ pngcheck -v7f flag50As.png
File: flag50As.png (1774976 bytes)
  chunk IHDR at offset 0x0000c, length 13
    1920 x 1080 image, 24-bit RGB, non-interlaced
  chunk iCCP at offset 0x00025, length 2615
    profile name = sRGB IEC61966-2.1, compression method = 0 (deflate)
    compressed profile = 2596 bytes
  chunk pHYs at offset 0x00a68, length 9: 2834x2834 pixels/meter (72 dpi)
  chunk IDAT at offset 0x00a7d, length 8192
    zlib: deflated, 32K window, default compression
  CRC error in chunk IDAT (computed 26649350, expected 67649350)
  chunk IDAT at offset 0x02a89, length 8192
  CRC error in chunk IDAT (computed 0f95f454, expected 4e95f454)
  chunk IDAT at offset 0x04a95, length 8192
  CRC error in chunk IDAT (computed 9a20ab2c, expected db20ab2c)
  chunk IDAT at offset 0x06aa1, length 8192
  CRC error in chunk IDAT (computed 7b6b58e8, expected 3a6b58e8)
  chunk IDAT at offset 0x08aad, length 8192
  CRC error in chunk IDAT (computed 210564a1, expected 600564a1)
  chunk IDAT at offset 0x0aab9, length 8192
  CRC error in chunk IDAT (computed 24250c73, expected 65250c73)
  chunk IDAT at offset 0x0cac5, length 8192
  CRC error in chunk IDAT (computed 15085e3c, expected 54085e3c)

Let’s focus on the first CRC error “CRC error in chunk IDAT (computed 26649350, expected 67649350)”. The encryption service changed the 1st CRC byte to 0×67 when it should be 0×26. Let’s XOR those chr( 0×67 ^ 0×26 ) give us the letter ‘A’! So, we get the XOR key by correcting the CRC values. Let’s create the key and cipher with the help of pngcheck and then write some python code to XOR them :-

$ pngcheck -v7f flag.png | grep "\s*CRC" | sed 's/.*computed //g' | sed 's/,.*//g' | grep -o "^.." | tr -d "\n" > key
	# 9260d5f43aba7e95afb4c504da2eaf84155c33306c5720529b6316a6218b32b281d609123c31e23c73b36e62dcfc70e821fe

$ pngcheck -v7f flag.png | grep "\s*CRC" | sed 's/.*expected //g' | tr -d ")" | grep -o "^.." | tr -d "\n" > cipher
	# c63596a07cc14efb9ecd9a35e91d98a04a3f735e33251312ff3c7b9552f872d5e4a5567a555586591dec070c83bf22ab5283


flag = ""
for i in range(len(cipher)):
	flag += chr(ord(cipher[i]) ^ ord(key[i]))

print flag

# TUCTF{0n1y_1337$_c@n_r3@d_m3ss@ges_hidden_in_CRCs}

Leave a Reply



November 29th



© 2017 SuRGeoNix | Security Blog