En este post pongo la solución a otro de los retos de la categoría 'Old Tech' de Brixel CTF 2020, competición en modalidad 'on-line' , estilo CTF (del inglés, 'Capture the Flag') y formato 'Jeopardy'.
Como esa categoría no figura entre las de este blog yo le asigno la de "Codificación".
El reto concreto lleva por título "punchcard" y, en mi opinión, presenta un nivel de dificultad medio (★★★☆☆).
Enunciado:
Se proporciona un archivo de imagen (punchcard.png) y, además, se puede obtener una pista a cambio de 5 puntos.El archivo de imagen contiene la siguiente tarjeta perforada:
Solución: En este caso , al contrario que en el reto del post anterior, no me hizo falta descubrir ninguna pista, ya que se trata de un reto relativamente frecuente en competiciones de este tipo y que, además, se puede resolver de diferentes maneras: manualmente (ver este post) o de forma automática, bien mediante la programación de un pequeño script (ver este post) o incluso, si es el caso, mediante la página web que sirvió para su grabación o perforación (ver el final de este post).
En primer lugar lo resolví mediante el pequeño script en python que creé para solucionar el reto del último de los posts indicados y que modifiqué conveniente para que contemple la tarjeta de este reto, es decir, el siguiente script:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def leer_columna_1(perforacion_1):
"""
Devuelve la lectura que corresponde a una columna con una perforacion.
"""
columna=''
columna=[0,1,2,3,4,5,6,7,8,9,'','-','&']
if columna=='':
print('Error lectura columna')
else:
return columna[perforacion_1]
def leer_columna_2(perforacion_1,perforacion_2):
"""
Devuelve la lectura que corresponde a una columna con dos perforaciones.
"""
columna=''
if perforacion_1==12:
columna=['','A','B','C','D','E','F','G','H','I','','','']
elif perforacion_1==11:
columna=['','J','K','L','M','N','O','P','Q','R','','','']
elif perforacion_1==0:
columna=['','/','S','T','U','V','W','X','Y','Z','','','']
elif perforacion_1==2:
columna=['','','','','','','','',':','','','','']
elif perforacion_1==3:
columna=['','','','','','','','','#','','','','']
elif perforacion_1==4:
columna=['','','','','','','','','@','','','','']
elif perforacion_1==5:
columna=['','','','','','','','','','','','','']
elif perforacion_1==6:
columna=['','','','','','','','','=','','','','']
elif perforacion_1==7:
columna=['','','','','','','','','"','','','','']
else:
print('Error lectura columna')
if columna=='':
print('Error lectura columna')
else:
return columna[perforacion_2]
def leer_columna_3(perforacion_1,perforacion_2,perforacion_3):
"""
Devuelve la lectura que corresponde a una columna con tres perforaciones.
"""
columna=''
if perforacion_1==12:
if perforacion_2==3:
columna=['','','','','','','','','.','','','','']
elif perforacion_2==4:
columna=['','','','','','','','','<','','','','']
elif perforacion_2==5:
columna=['','','','','','','','','(','','','','']
elif perforacion_2==6:
columna=['','','','','','','','','+','','','','']
elif perforacion_2==7:
columna=['','','','','','','','','|','','','','']
elif perforacion_2==8:
columna=['','','','','','','','','','','','','']
else:
print('Error lectura columna')
elif perforacion_1==11:
if perforacion_2==2:
columna=['','','','','','','','','!','','','','']
elif perforacion_2==3:
columna=['','','','','','','','','$','','','','']
elif perforacion_2==4:
columna=['','','','','','','','','*','','','','']
elif perforacion_2==5:
columna=['','','','','','','','',')','','','','']
elif perforacion_2==6:
columna=['','','','','','','','',';','','','','']
elif perforacion_2==7:
columna=['','','','','','','','','','','','','']
else:
print('Error lectura columna')
elif perforacion_1==0:
if perforacion_2==3:
columna=['','','','','','','','',',','','','','']
elif perforacion_2==4:
columna=['','','','','','','','','%','','','','']
elif perforacion_2==5:
columna=['','','','','','','','','_','','','','']
elif perforacion_2==6:
columna=['','','','','','','','','>','','','','']
elif perforacion_2==7:
columna=['','','','','','','','','?','','','','']
else:
print('Error lectura columna')
else:
print('Error lectura columna')
if columna=='':
print('Error lectura columna')
else:
return columna[perforacion_3]
# Tarjeta a leer: para cada columna de la tarjeta incluir, separados por comas, numero de perforaciones y posiciones de las perforaciones.
tarjeta=[2,0,3,2,12,8,2,12,5,2,12,6,2,11,3,2,12,1,2,12,7,2,12,9,2,0,2,2,12,2,2,11,9,2,12,9,2,0,7,2,12,5,2,11,3,2,12,3,2,0,3,2,12,6,3,12,5,8,2,11,4,1,4,1,1,2,11,5,2,12,6,2,11,9,1,4,2,11,4,1,3,3,11,5,8,1,11,1,11,2,0,3,2,12,8,2,12,1,2,11,5,2,11,2,2,0,8,2,11,6,2,0,4,2,12,6,2,11,6,2,11,9,2,11,7,2,11,3,2,12,1,2,0,8,2,12,9,2,11,5,2,12,7,2,12,2,2,11,9,2,12,9,2,0,7,2,12,5,2,11,3,2,12,3,2,0,3,2,12,6,1,11,1,11]
lectura_tarjeta=""
i=0
while i < len(tarjeta):
if tarjeta[i]==0:
lectura_tarjeta=lectura_tarjeta+" "
i+=1
elif tarjeta[i]==1:
lectura_tarjeta=lectura_tarjeta+str(leer_columna_1(tarjeta[i+1]))
i+=2
elif tarjeta[i]==2:
lectura_tarjeta=lectura_tarjeta+str(leer_columna_2(tarjeta[i+1],tarjeta[i+2]))
i+=3
else:
lectura_tarjeta=lectura_tarjeta+str(leer_columna_3(tarjeta[i+1],tarjeta[i+2],tarjeta[i+3]))
i+=4
print(lectura_tarjeta)
Lo ejecuto:
Y puedo ver que la flag es: brixelCTF{M41NFR4M3}.
No obstante, tal y como digo, si no queremos resolverlo a mano o con un pequeño script y, además, esta tarjeta ha sido grabada o perforada mediante una utilidad de alguna página web y encontramos ésta, podemos ahorrarnos tiempo y esfuerzo:
Comentarios
Publicar un comentario