En este post la solución a otro reto de UTC-CTF 2019, competición tipo 'Capture The Flag' (CTF), en formato 'Jeopardy', modalidad 'On-line' y por equipos.
En esta ocasión se trata de un desafío de la categoría 'Miscellaneous' (Misc), pero que yo catalogo en este blog como de programación, y que en mi opinión tiene un nivel de dificultad bajo (★★☆☆☆).
El título del reto es "Optics 2" y para resolverlo es importante saber que en el desafío titulado "Optics 1 (baby)" de esta misma plataforma, a mi juicio de dificultad muy baja, se ve involucrado un código QR, por lo que es muy probable que este tipo de código esté también presente en este reto.
Su enunciado es el siguiente:
Descargo el archivo asociado al reto (challenge_2.zip) y veo que contiene 441 archivos de imagen (png).
Los extraigo:
Tal y como he dicho antes, sospecho que los códigos QR están involucrados en este reto y, a simple vista, los archivos de imagen extraídos parecen contener trozos de un código de este tipo.
Suponiendo que es así, lo primero que tengo que averiguar son las dimensiones del código QR (número de archivos de ancho x número de archivos de alto).
La primer pista me la da el hecho de que los 22 primeros archivos contienen únicamente imágenes en blanco, lo que podría indicar que éstos se corresponderían con el margen superior del código QR (21 archivos, chall_0.png a chall_20.png) y con el margen lateral izquierdo de la segunda fila (1 archivo, chall_21.png).
Lo anterior se ve reforzado porque los 22 último archivos también contienen únicamente imágenes en blanco, lo que podría indicar que éstos se corresponderían con el margen lateral derecho de la anteúltima fila del código QR (1 archivo, chall_419.png) y con el margen inferior (21 archivos, chall_420.png a chall_440.png).
Es decir, parece evidente que el código QR tiene 21 archivos de ancho x 21 archivos de alto = 441 archivos, conclusión a la que podría haber llegado sin tanta complicación sin más que calcular la raíz cuadrada de 441 ;).
Ya sólo me queda ver si estoy en lo cierto montando el código QR a partir de las 441 piezas del mismo contenidas en los archivos de imagen. Aunque es perfectamente posible hacerlo a mano, lo único es que me llevaría un buen rato, como estoy un poco vago ;) creo el siguiente script en python para ello:
from PIL import Image
Optics_2 = Image.new("RGB",(1155,1155),"black")
fichero = 0
fila = 0
columna = 0
while fichero < 441:
while fila < 21:
while columna < 21:
imagen = "chall_" + str(fichero) + ".png"
image = Image.open(imagen)
Optics_2.paste(image, (columna*55,fila*55))
fichero = fichero + 1
columna = columna + 1
fila = fila + 1
columna = 0
Optics_2.save("Optics_2.png")
Optics_2.show()
Lo ejecuto, y cuando finaliza puedo ver el siguiente código QR, que también se graba en un archivo con el nombre Optics_2.png:
Y, finalmente, para ver la flag utilizo uno de los muchos lectores 'on line' de códigos QR existentes:
Flag: utc{merge_and_merge_until_you_decode_it}.
En esta ocasión se trata de un desafío de la categoría 'Miscellaneous' (Misc), pero que yo catalogo en este blog como de programación, y que en mi opinión tiene un nivel de dificultad bajo (★★☆☆☆).
El título del reto es "Optics 2" y para resolverlo es importante saber que en el desafío titulado "Optics 1 (baby)" de esta misma plataforma, a mi juicio de dificultad muy baja, se ve involucrado un código QR, por lo que es muy probable que este tipo de código esté también presente en este reto.
Su enunciado es el siguiente:
Descargo el archivo asociado al reto (challenge_2.zip) y veo que contiene 441 archivos de imagen (png).
Los extraigo:
Tal y como he dicho antes, sospecho que los códigos QR están involucrados en este reto y, a simple vista, los archivos de imagen extraídos parecen contener trozos de un código de este tipo.
Suponiendo que es así, lo primero que tengo que averiguar son las dimensiones del código QR (número de archivos de ancho x número de archivos de alto).
La primer pista me la da el hecho de que los 22 primeros archivos contienen únicamente imágenes en blanco, lo que podría indicar que éstos se corresponderían con el margen superior del código QR (21 archivos, chall_0.png a chall_20.png) y con el margen lateral izquierdo de la segunda fila (1 archivo, chall_21.png).
Lo anterior se ve reforzado porque los 22 último archivos también contienen únicamente imágenes en blanco, lo que podría indicar que éstos se corresponderían con el margen lateral derecho de la anteúltima fila del código QR (1 archivo, chall_419.png) y con el margen inferior (21 archivos, chall_420.png a chall_440.png).
Es decir, parece evidente que el código QR tiene 21 archivos de ancho x 21 archivos de alto = 441 archivos, conclusión a la que podría haber llegado sin tanta complicación sin más que calcular la raíz cuadrada de 441 ;).
Ya sólo me queda ver si estoy en lo cierto montando el código QR a partir de las 441 piezas del mismo contenidas en los archivos de imagen. Aunque es perfectamente posible hacerlo a mano, lo único es que me llevaría un buen rato, como estoy un poco vago ;) creo el siguiente script en python para ello:
from PIL import Image
Optics_2 = Image.new("RGB",(1155,1155),"black")
fichero = 0
fila = 0
columna = 0
while fichero < 441:
while fila < 21:
while columna < 21:
imagen = "chall_" + str(fichero) + ".png"
image = Image.open(imagen)
Optics_2.paste(image, (columna*55,fila*55))
fichero = fichero + 1
columna = columna + 1
fila = fila + 1
columna = 0
Optics_2.save("Optics_2.png")
Optics_2.show()
Lo ejecuto, y cuando finaliza puedo ver el siguiente código QR, que también se graba en un archivo con el nombre Optics_2.png:
Y, finalmente, para ver la flag utilizo uno de los muchos lectores 'on line' de códigos QR existentes:
Flag: utc{merge_and_merge_until_you_decode_it}.
Comentarios
Publicar un comentario