Description
RU: Внедрение новейшей системы шифрования информации как всегда приносило множество проблем одной из известных служб fsi: они потеряли модуль, отвечающий за дешифрование информации. А информация уже была зашифрована! Ваша задача на сегодня: определить способ шифрования алгоритма и декодировать сообщение.
EN: We have received pictures from the enemy companion of the unknown before planet. And we haven’t thought up anything better, than to construct DeathStarV3 (the general was a fan of “Star Wars”) and to absorb energy of the whole planet! And again we are pursued by problems: that we don’t know coordinate! Your task is to determine coordinates of this unique planet (which according to our spy are ciphered in the image). Also he could steal one of the scripts intended for embedding of coordinates. All hope only for you!
h4ck1t{flag}
Solution
After downloading and extracting the challenge file, we are presented two files:
1 2 |
root@kali:~/h4ck1tctf/Algeria/CryptoPixels/solve# ls encrypted.png SECRET_TOOL.py |
encrypted.png is the following image:
The other file, SECRET_TOOL.py contains code that seems to have been used to create encrypted.png:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from PIL import Image import random FLAG = '^__^' img = Image.open('original.png') img_pix = img.convert('RGB') x = random.randint(1,255) y = random.randint(1,255) img_pix.putpixel((0,0),(len(FLAG),x,y)) for l in FLAG: x1 = random.randint(1,255) y1 = random.randint(1,255) img_pix.putpixel((x,y),(ord(l),x1,y1)) x = x1 y = y1 img_pix.save('encrypted.png') |
As it seems, it created the image pixel by pixel using the putpixel function from the PIL module for Python. This means that, for each pixel, an X and Y coordinate for the pixel must be given, as well as a RGB value for its color.
The first pixel is located at X = 0 and Y = 0, with the first value of the RGB triple indicating the length of the flag. So, if we read the first pixel of the output image (encrypted.png) at location (0,0) and take the first value of the RGB triple, we can see the length of the flag.
Then, the next pixel will be located at the location specified in the second and third value of the RGB triple. After the first pixel, also, the first value in the RGB triple will contain a letter of the flag, encoded using the ord() value in Python. We can reverse ord() using chr().
Shortly, the flag can be obtained by reading the X and Y coordinates from the first pixel (indicated by its green and blue values), and by putting the red value through the chr() function. I used the following code to get the flag:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from PIL import Image import random # Start with an empty flag flag = '' # Open the encrypted image and convert to RGB img = Image.open('encrypted.png') img_pix = img.convert('RGB') # Read the first pixel, which will be the starting point pixel = img_pix.getpixel((0,0)) # Get the length of the flag by looking at the first value of the RGB triple flag_length = pixel[0] print "Flag length:",flag_length # Get the coordinates for the next pixel by looking at the second and third value of the RGB triple new_x = pixel[1] new_y = pixel[2] # Repeat the following for the length of the flag: for i in range(0,flag_length): # Get the pixel using the coordinates pixel = img_pix.getpixel((new_x,new_y)) # Get the first value from the RGB triple, apply the 'chr()' function and append to the flag flag = flag + chr(pixel[0]) # Get the second and third value from the RGB triple, and use as coordinates for the next pixel new_x = pixel[1] new_y = pixel[2] print "Retrieved flag:",flag |
Let’s try the script above:
1 2 3 |
root@kali:~/h4ck1tctf/Algeria/CryptoPixels/solve# python solver.py Flag length: 33 Retrieved flag: 1NF0RM$T10N_1$_N0T_$3CUR3_4NYM0R3 |
So, the flag is h4ck1t{1NF0RM$T10N_1$_N0T_$3CUR3_4NYM0R3}