APT593

CPCTF : Dont Panic (Chile)

14/07/2020

Descripción:

Esta imagen me recuerda al número 42. No tiene nada que ver con la flag. Solo queria compartir mi opinión.

Archivo:

dont_panic.png

Resolución

La imagen, la descripción y el nombre del reto hacen referencia al universo de: “The Hitchhikers guide to the galaxy”. Pero el reto no tiene nada que ver con eso. Solo era una referencia para distraer.

Volviendo al reto. Hay que realizar las revisiones de siempre: tipo de archivo, metadata, y su contenido en raw con algún lector en hexadecimal en búsqueda de algo fuera de lo normal. Para esto último, existen programas como binwalk que nos da una revisión rápida:

└──╼ $binwalk afsdafas_dontpanic.png 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             PNG image, 869 x 560, 8-bit/color RGB, non-interlaced
84            0x54            Zlib compressed data, best compression
339153        0x52CD1         Zip archive data, at least v2.0 to extract, compressed size: 461464, uncompressed size: 462062, name: stego.png
800684        0xC37AC         Zip archive data, at least v2.0 to extract, compressed size: 461533, uncompressed size: 462060, name: stego2.png
1262257       0x1342B1        Zip archive data, at least v2.0 to extract, compressed size: 460781, uncompressed size: 461301, name: stego3.png
1723078       0x1A4AC6        Zip archive data, at least v2.0 to extract, compressed size: 461200, uncompressed size: 461689, name: stego4.png
2184318       0x21547E        Zip archive data, at least v2.0 to extract, compressed size: 460990, uncompressed size: 461520, name: stego5.png
2645348       0x285D64        Zip archive data, at least v2.0 to extract, compressed size: 461278, uncompressed size: 461789, name: stego6.png
3107205       0x2F6985        End of Zip archive, footer length: 22

Como se puede apreciar con binwalk, existe un intento pobre y burdo de esconder un zip con otras imágenes dentro de la imágen del hombre espacial (curioso nombre que le pusieron algunos participantes a la imágen).

Con el mismo binwalk o foremost se puede extraer la información y obtener el .zip con las imágenes.

└──╼ $binwalk -e afsdafas_dontpanic.png 
...
└──╼ $ls _afsdafas_dontpanic.png.extracted/
52CD1.zip  54.zlib     stego3.png  stego5.png  stego.png
54         stego2.png  stego4.png  stego6.png

No publicaré las seis imágenes porque todas a simple vista son similares:

image-20200712211815224

En esta primera parte parece ser una imagen sobrepuesta con otras imágenes. En el centro pareciera que hay letras.

Si veiamos las imagenes un poco más de cerca claramente se puede apreciar un patrón de rotación. :

Stego.png

image-20200712211943053

Stego2.png

image-20200712212028648

Stego3.png

image-20200712212128324

Es una técnica de esteganografía demasiado ingenua lo admito. Son seis imágenes y sobrepuestas y se ha tomado un pixel de cada una. Cada imágen tiene una rotación disitinta para que en su conjunto se pueda reconstruir todas las imágenes al 100%. Algunas personas sacaron sus poderes de photoshop para reconstruir la imágen en las secciones donde intuyeron que estaba el flag.

Una mejor alternativa para quienes gustan de python es hacer un pequeño script que reconstruya todas las imágenes hasta dar con la que tiene la flag. La librería Pillow nos puede ayudar a trabajar con imágenes y en mi caso utilicé también numpy array para manejar el arreglo de pixeles.

#!/usr/bin/python
from PIL import Image
import sys
import numpy

im = Image.open("stego.png")
im2 = Image.open("stego2.png")
im3 = Image.open("stego3.png")
im4 = Image.open("stego4.png")
im5 = Image.open("stego5.png")
im6 = Image.open("stego6.png")

npim = numpy.array(im)
npim2 = numpy.array(im2)
npim3 = numpy.array(im3)
npim4 = numpy.array(im4)
npim5 = numpy.array(im5)
npim6 = numpy.array(im6)

c=0
npres = numpy.empty((499,498,3),dtype=int)
for i in range(0,npim.shape[0]):
   for j in range(0,npim.shape[1]):
       if c % 6 == 0:
           npres[i][j] = npim6[i][j]
       if c % 6 == 1:
           npres[i][j] = npim5[i][j]
       if c % 6 == 2:
           npres[i][j] = npim4[i][j]
       if c % 6 == 3:
           npres[i][j] = npim3[i][j]
       if c % 6 == 4:
           npres[i][j] = npim2[i][j]
       if c % 6 == 5:
           npres[i][j] = npim[i][j]
       c = c + 1     

imres = Image.fromarray(npres.astype(numpy.uint8))
imres.save("solved.png")
imres.show()

Ejecutando el script obtenemos la imagen con el flag.

image-20200712213048580