InfoSec Blog
  • 🏠Home
  • 🪪Trainings & Certification
    • APISec University
      • ASCP Review
    • OffSec
      • OSCP Review
  • 🚩CTFs
    • HackTheBox
      • Windows Machines
        • Visual
      • Web Challenges
        • Neonify
    • ROOTCON 18 PRE QUALIFIERS
      • Rock Paper Scissors Sh**t
      • Zippy
      • Super Secure Static Website
Powered by GitBook
On this page
  1. CTFs
  2. ROOTCON 18 PRE QUALIFIERS

Zippy

The goal of the challenge is to recursively unzip all the files, concatenate their file names, and then reverse the data to get its readable version.

PreviousRock Paper Scissors Sh**tNextSuper Secure Static Website

Last updated 9 months ago

We are given a challenge.zip with the password of r00tc0nqu4ls!. Unzipping it provides us an a.zip. Further unzipping it leads to multiple more zip files. This can be likened to the Matryoshka doll.

Continuing this, it resembles hex data so the goal of the challenge may be to recursively unzip these files, and then do concatenation of all the data.

Using ChatGPT, a Python script was made for this. Initially, I tried with both saving to the disk or employing unique file names but instead opted for in-memory extraction as it was the most consistent out of the three approaches.

The script recursively unzips all of the files, checks if there were multiple files extracted, then if we hit the final zip file, save it to disk. Afterwards, concatenate all the zip file names to get the hex data.

import zipfile
import os
import io

def unzip_file_in_memory(zip_data, current_zip_name):
    """Extracts a zip file from in-memory data and returns extracted files."""
    extracted_files = []
    print(f"Extracting {current_zip_name}...")  # Print the name of the current zip being extracted
    
    with zipfile.ZipFile(io.BytesIO(zip_data), 'r') as zip_ref:
        for file_info in zip_ref.infolist():
            # Extract all files in memory
            extracted_files.append((file_info.filename, zip_ref.read(file_info.filename)))
    
    # Check if more than one file was extracted
    if len(extracted_files) > 1:
        print("Unexpected additional files extracted:")
        for file_info in extracted_files:
            print(f"Extracted file: {file_info[0]}")
    
    return extracted_files

def save_zip_file(file_data, filename, output_dir):
    """Saves a zip file to disk."""
    output_path = os.path.join(output_dir, filename)
    with open(output_path, 'wb') as f:
        f.write(file_data)
    print(f"Saved zip file as {output_path}")

def collect_zip_names(input_zip_path, output_dir):
    """Collects names of all zip files and saves the final zip file."""
    zip_names = []
    queue = []

    # Read the initial zip file into memory
    with open(input_zip_path, 'rb') as f:
        input_zip_data = f.read()
        queue.append((input_zip_data, os.path.basename(input_zip_path)))  # Add zip name for printing

    while queue:
        current_zip_data, current_zip_name = queue.pop(0)

        # Extract the current zip file in memory
        extracted_files = unzip_file_in_memory(current_zip_data, current_zip_name)

        # Check if there are no more zip files to extract
        has_zip = False
        for filename, file_data in extracted_files:
            if filename.endswith('.zip'):
                zip_name = filename[:-4]
                zip_names.append(zip_name)
                has_zip = True
                # Continue processing zip files
                queue.append((file_data, filename))
        
        if not has_zip:
            # If no more zip files, save the final one
            final_filename = "final.zip"
            save_zip_file(current_zip_data, final_filename, output_dir)
    
    return zip_names

def save_concatenated_zip_names(zip_names, output_dir):
    """Saves the concatenated zip names to a file."""
    concatenated_names = ''.join(zip_names)
    output_file = os.path.join(output_dir, "concatenated_zip_names.txt")
    
    with open(output_file, 'w') as f:
        f.write(concatenated_names)

    print(f"Concatenated zip names saved to {output_file}")

if __name__ == "__main__":
    # Replace this with your path
    input_zip = './a.zip'
    output_dir = './output'

    # Ensure the output directory exists
    os.makedirs(output_dir, exist_ok=True)
    
    # Collect zip names and concatenate them
    zip_names = collect_zip_names(input_zip, output_dir)
    
    # Save concatenated zip names
    save_concatenated_zip_names(zip_names, output_dir)

After running this, we get the final zip file names and the final zip file.

Checking if the final.zip contained a flag, it did not.

Checking for how long the hex data was, we see it was around 20309 + 1 since we started with a.zip which was already unzipped.

Checking the concatenated file names, we only get gibberish data. I initially tried saving it to disk to see if it related to another file but it did not.

What did the trick was reversing the initial hex data. This gave us then the proper ASCII output. We also find the flag.

🚩