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.
Last updated
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.
Last updated
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.