[Misc] TUCTF - Gr8 Pictures


Gr8 Pictures
50

The mysterious hacker 4chan is believed to be passing secret messages hidden in a picture. We know that he connects to gr8pics.tuctf.com:4444 to hide his message in the picture. Your mission, should you choose to accept it, is to find out what message he is trying to hide.

nc gr8pics.tuctf.com 4444
If you get connection refused, use nc gr8pics.tuctf.com 41234
NOTE: the server does not show a prompt, but if the connection is successful, you are at the correct starting point.
NOTE: without connecting to the server, the flag is theoretically cryptographically impossible to get
NOTE: If you’re getting a bunch of data that doesn’t seem to stop - it stops after ~3MB of data

sha1
9044fe96a50ecb831fe451f13c24cc96b0a9e24d flag.png

This was a simple misc, we were told in the challenge description that a hacker from 4chan was using this service to hide messages within images, if we sent a message with a length >= 50 the service would return an image with the message hidden within in the image, after receiving it I noticed that the only difference between the image given from the challenge and the one generated in the service was 50 bytes (which makes sense since I sent a message with 50 length), I was suspicious that the server were encrypting the message using a simple xor so to test this I sent 50 null bytes to the service:

1
$ python -c "print '\x00'*50" | nc gr8pics.tuctf.com 4444 | base64 -d > flag2.png

But why send only null bytes? If they are using xor we can retrieve the key completely! xoring any number by zero will return always the number! You could easily get the 50 new bytes by comparing all non equal bytes between flag.png flag2.png:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *

file2 = open('flag2.png', 'rb')
file = open('flag.png', 'rb')
s = bytearray(file.read())
s2 = bytearray(file2.read())

k = 0
key = ''
flag = ''
for i in range(len(s)):
if s[i] != s2[i]:
key += chr(s2[i])

print key

By running it we could easily get the key!

1
2
$ python misc50.py
Isnt_x0r_such_@_c00l_function?Im_such_a_1337_hax0r

Having the key is easy to decrypt the original flag we just need to adapt our script to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *

file2 = open('test.png', 'rb')
file = open('flag.png', 'rb')
s = bytearray(file.read())
s2 = bytearray(file2.read())

k = 0
key = ''
flag = ''
for i in range(len(s)):
if s[i] != s2[i]:
key += chr(s2[i])
flag += chr(s[i] ^ s2[i])
print key
print flag

And finally the flag:

1
2
3
$ python misc50.py
Isnt_x0r_such_@_c00l_function?Im_such_a_1337_hax0r
TUCTF{st3g@n0gr@phy's_so_c00l,No0ne_steals_my_msg}