M0rsarchive
2 minutos de lectura
Se nos proporcionan estos archivos:
$ file *
flag_999.zip: Zip archive data, at least v1.0 to extract, compression method=store
pwd.png: PNG image data, 25 x 3, 8-bit/color RGB, non-interlaced
Pruebas
El archivo ZIP está protegido con contraseña, y esta es pwd.png
:
Es bastante difícil distinguir lo que está codificado en la imagen, pero en realidad es código Morse. Esta vez, contiene “9”. Podemos suponer que es la contraseña para el archivo ZIP:
$ unzip -P 9 flag_999.zip
Archive: flag_999.zip
extracting: flag/flag_998.zip
inflating: flag/pwd.png
Entonces, tenemos otro archivo ZIP protegido con contraseña y otra imagen pwd.png
:
Esta vez, la palabra codificada es “08”:
$ unzip -P 08 flag_998.zip
Archive: flag_998.zip
extracting: flag/flag_997.zip
inflating: flag/pwd.png
Automatización
Muy bien, entonces ya sabemos cómo funciona. Podemos suponer que necesitamos hacer esta tarea hasta llegar a flag_1.zip
o flag_0.zip
. Por lo tanto, necesitaremos automatizarlo. Por ejemplo, podemos usar Python y OpenCV para analizar las imágenes.
El procedimiento general será:
- Analizar la imagen para extraer el código Morse
- Traducir el código Morse
- Extraer el archivo ZIP
Implementación
Esta es la función relevante:
def translate_to_morse(number: int) -> str:
dictionary = {1: '.', 3: '-'}
return dictionary.get(number, '')
def next_image(path: str) -> str:
img = cv2.imread(path)
dummy_pixel = img[0][0]
morse_code = []
for row in img:
morse_row_code = [0]
for pixel in row:
if (pixel == dummy_pixel).all():
if morse_row_code[-1] != 0:
morse_row_code.append(0)
else:
morse_row_code[-1] += 1
morse_row_code = [code for code in morse_row_code if code != 0]
if len(morse_row_code):
morse_code.append(''.join(map(translate_to_morse, morse_row_code)))
return ''.join(morse_alphabet.get(code, '') for code in morse_code).lower()
Y esto es main
, que se ejecuta hasta llegar al último archivo, que contiene la flag:
def main():
path = './'
prog = log.progress('Depth')
for i in range(999, -1, -1):
prog.status(str(i))
password = next_image(f'{path}pwd.png')
os.system(f'unzip -P {password} -d flag{i} {path}flag_{i}.zip &>/dev/null')
path = f'flag{i}/flag/'
prog.success(str(i))
with open(f'{path}flag') as f:
log.success(f.read().strip())
os.system('rm -r flag[0-9]*')
También realiza algunas tareas de limpieza para eliminar todos los archivos ZIP y directorios.
Flag
Si ejecutamos el script, obtendremos la flag:
$ python3 solve.py
[+] Depth: 0
[+] HTB{D0_y0u_L1k3_m0r53??}
El script completo se puede encontrar aquí: solve.py
.