Автор: @FaLLenSkiLL

Ссылка на таск Codeby

https://codeby.games/categories/misc/4ed82185-29dc-4508-a863-eb1d81da9fb3

Описание задания

Архивы имеют случайные названия. Паролем к каждому архиву является строка, которая выводится при попытке его разархививации. Она закодирована в ROT13→Base64. Раскодируйте её и укажите в качестве пароля

Решение

Итак, нам дали зипку

Из описания мы знаем, что в зипках есть комменты, посмотрим на них с помощью exiftool

apt install exiftool

Каждый коммент зипки - пароль для следующей зипке. Стандартная матрешка. Но комменты зашифрованы ROT13→Base64. Значит для расшифровки нам нужно проделать обратную операцию.

Судя по размеру файла, матрешка довольно большая

По этому целесообразней будет автоматизировать весь процесс. Я буду использовать python. (кодик конечно костыльненький, но главное - работает)

Описание кода

Импортируем необходимые модули Python для работы с файловой системой, выполнения внешних команд, декодирования строк, и работы с zip-архивами.

import os
import subprocess
import base64
import codecs
import zipfile

Напишем функцию, которая принимает закодированную строку в формате base64, декодирует её, а затем применяет ROT13 шифрование к результату. После чего, возвращает декодированную строку.

def decode_rot13_base64(encoded_str):
    decoded_bytes = base64.b64decode(encoded_str)
    decoded_str = decoded_bytes.decode('utf-8')
    return codecs.decode(decoded_str, 'rot_13')

Теперь используем утилиту exiftool, которую скачали ранее, для извлечения комментария из метаданных zip-архива. После запуска exiftool, вывод разбивается на строки, ищется строка, начинающаяся с Comment, и извлекается сам комментарий.

def extract_comment_from_zip(zip_file):
    try:
        exiftool_output = subprocess.check_output(['exiftool', zip_file])
        lines = exiftool_output.decode('utf-8').split('\n')
        for line in lines:
            if line.startswith('Comment'):
                comment = line.split(': ')[1]
                return comment
    except subprocess.CalledProcessError:
        print("Error: exiftool command failed.")
        return None

Извлекаем содержимое zip-архива, с использованием заданного пароля. Функция открывает zip-архив, итерируется по всем файлам внутри, и извлекает их с помощью заданного пароля. После успешной распаковки архива, он удаляется (чтобы не заполнить папку кучей зипок).

def extract_zip_with_password(zip_file, password):
    try:
        with zipfile.ZipFile(zip_file, 'r') as zip_ref:
            for info in zip_ref.infolist():
                zip_ref.extract(info, pwd=password.encode())
        os.remove(zip_file)  # Удаление архива после распаковки
    except zipfile.BadZipFile:
        print("Error: Invalid zip file.")
    except RuntimeError:
        print("Error: Password incorrect.")
    except Exception as e:
        print(f"An error occurred: {e}")

И последняя функция. Она ищет zip-файл в текущем рабочем каталоге, извлекает комментарий из метаданных этого архива, декодирует комментарий, а затем использует полученный пароль для извлечения содержимого архива. После этого она запускается 1001 раз (именно столько нужно для решения таска).

def main():
    current_dir = os.getcwd()
    zip_files = [f for f in os.listdir(current_dir) if f.endswith('.zip')]
    if len(zip_files) != 1:
        print("Error: There should be exactly one zip file in the directory.")
        return
 
    zip_file = zip_files[0]
    comment = extract_comment_from_zip(zip_file)
    if comment:
        zip_password = decode_rot13_base64(comment)
        print(f"Archive {zip_file}: Password - {zip_password}")
        extract_zip_with_password(zip_file, zip_password)
 
if __name__ == "__main__":
    for _ in range(1001):
        main()

В итоге получаем что-то такое:

import os
import subprocess
import base64
import codecs
import zipfile
 
def decode_rot13_base64(encoded_str):
    decoded_bytes = base64.b64decode(encoded_str)
    decoded_str = decoded_bytes.decode('utf-8')
    return codecs.decode(decoded_str, 'rot_13')
 
def extract_comment_from_zip(zip_file):
    try:
        exiftool_output = subprocess.check_output(['exiftool', zip_file])
        lines = exiftool_output.decode('utf-8').split('\n')
        for line in lines:
            if line.startswith('Comment'):
                comment = line.split(': ')[1]
                return comment
    except subprocess.CalledProcessError:
        print("Error: exiftool command failed.")
        return None
 
def extract_zip_with_password(zip_file, password):
    try:
        with zipfile.ZipFile(zip_file, 'r') as zip_ref:
            for info in zip_ref.infolist():
                zip_ref.extract(info, pwd=password.encode())
        os.remove(zip_file)  # Удаление архива после распаковки
    except zipfile.BadZipFile:
        print("Error: Invalid zip file.")
    except RuntimeError:
        print("Error: Password incorrect.")
    except Exception as e:
        print(f"An error occurred: {e}")
 
def main():
    current_dir = os.getcwd()
    zip_files = [f for f in os.listdir(current_dir) if f.endswith('.zip')]
    if len(zip_files) != 1:
        print("Error: There should be exactly one zip file in the directory.")
        return
 
    zip_file = zip_files[0]
    comment = extract_comment_from_zip(zip_file)
    if comment:
        zip_password = decode_rot13_base64(comment)
        print(f"Archive {zip_file}: Password - {zip_password}")
        extract_zip_with_password(zip_file, zip_password)
 
if __name__ == "__main__":
    for _ in range(1001):
        main()

Запускаем код

Последнюю зипку также смотрим с помощью exiftool и получаем флаг

Флаг Флаг

Tags:

#codeby#writeup#misc #easy