name | event | category | description | layout | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Layers (2024) |
Intigriti 1337UP LIVE CTF 2024 |
Warmup |
Writeup for Layers (Warmup) - 1337UP LIVE CTF (2024) 💜 |
|
Weird way to encode your data, but OK! 🤷♂️
Players receive a ZIP archive to download, perhaps noticing the unusual order of extraction.
{% code overflow="wrap" %}
unzip layers.zip
Archive: layers.zip
extracting: 48
extracting: 45
extracting: 6
extracting: 25
extracting: 55
extracting: 39
extracting: 29
extracting: 32
extracting: 24
extracting: 12
{% endcode %}
Each file contains a single byte of data.
{% code overflow="wrap" %}
cat 0
00110010
{% endcode %}
Maybe we can concatenate them and convert from binary?
{% code overflow="wrap" %}
cat *
0011001001001101011101010100111001010110010011100100010001111010011110100110000101100011011100110011100101100111011100110101011001001000010100110101010101001110010011100011100101100100010011100101011001001010010100110100111001100010011110100011001101100110011010100101010101010010011010100100111001000010010010010110101001010101011001000110101101010011011001100111100001111010001110010110010101000100011011110101001100110101010011100101001001010110
{% endcode %}
It translates to 2MuNVNDzzacs9gsVHSUNN9dNVJSNbz3fjURjNBIjUdkSfxz9eDoS5NRV
, which although plaintext, doesn't have a recognisable encoding (and fails with magic).
Notice that if we check the timestamps of the files, they weren't created in the order you would expect (sequentially, according to their filenames).
{% code overflow="wrap" %}
ls -lart
total 224
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:09 48
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:10 45
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:10 6
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:11 25
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:11 55
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:12 39
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:12 29
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:13 32
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:13 24
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:14 12
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:14 8
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:15 31
-rw-r--r-- 1 crystal crystal 8 Aug 19 17:15 52
{% endcode %}
Let's try to concatenate in ascending order by timestamp, instead of filename. We can use a script to automate the whole process.
{% code overflow="wrap" %}
import zipfile
import os
from datetime import datetime
ARCHIVE_NAME = "layers.zip"
EXTRACT_DIR = "files"
def binary_to_char(binary_str):
return chr(int(binary_str, 2))
with zipfile.ZipFile(ARCHIVE_NAME, 'r') as zipf:
for info in zipf.infolist():
extracted_path = zipf.extract(info, EXTRACT_DIR)
date_time = datetime(*info.date_time)
mod_time = date_time.timestamp()
os.utime(extracted_path, (mod_time, mod_time))
file_data = []
for file_name in os.listdir(EXTRACT_DIR):
file_path = os.path.join(EXTRACT_DIR, file_name)
mod_time = os.path.getmtime(file_path)
with open(file_path, "r") as f:
binary_data = f.read().strip()
char = binary_to_char(binary_data)
file_data.append((mod_time, char))
file_data.sort()
reconstructed_string = ''.join([char for _, char in file_data])
print("Reconstructed String:")
print(reconstructed_string)
for file_name in os.listdir(EXTRACT_DIR):
os.remove(os.path.join(EXTRACT_DIR, file_name))
os.rmdir(EXTRACT_DIR)
{% endcode %}
{% code overflow="wrap" %}
python solve.py
Reconstructed String:
SU5USUdSSVRJezdoM3IzNV9sNHkzcjVfNzBfN2gxNV9jaDRsbDNuNjN9
{% endcode %}
What happens if we run magic on this one?
It's detected as Base64 encoding 😎
Flag: INTIGRITI{7h3r35_l4y3r5_70_7h15_ch4ll3n63}