# TCP1P CTF 2024 - Skibidi Format
**Title:** Skibidi Format
**Description:** So my friend just made a new image format and asked me to give him a test file, so I gave him my favorite png of all time. But the only thing I receive back is just my image with his new format and its "specification" file, don't know what that is.
Can you help me read this file?
**Files:**
- [spec.html](https://github.com/xtasy94/CTFW/blob/main/CTF_Files/TCP1PCTF/spec.html)
- [suisei.skibidi](https://github.com/xtasy94/CTFW/blob/main/CTF_Files/TCP1PCTF/suisei.skibidi)
## Solution:
I started by examining the provided "specification" file (spec.html) to understand the structure of the `.skibidi` image format, I found that the specification detailed the file format with a `58-byte` header follow by encrypted and compressed pixel data:
```bash
+----------------------+-----------------------+
| Header | Data Section |
+----------------------+-----------------------+
| Magic Number (4B) | Encrypted Data |
| Width (4B) | |
| Height (4B) | |
| Channels (1B) | |
| Compression ID (1B) | |
| AES Key (32B) | |
| AES IV (12B) | |
+----------------------+-----------------------+
Total Header Size: 58 bytes
```
We also had the process used in the `spec.html` file:
1. **Load `input.png`:**
- Image dimensions: **800x600** pixels
- Color channels: **4** (RGBA)
2. **Compress Pixel Data:**
- Compression Method: **Zstandard (`zstd`)**
- Compressed Data Size: **X** bytes
3. **Encrypt Compressed Data:**
- AES-256-GCM with randomly generated key and IV
- Encrypted Data Size: **Y** bytes
4. **Construct Header:**
- Magic Number: `"SKB1"`
- Width: **800** (`0x02000000` in little endian)
- Height: **600** (`0x25800000` in little endian)
- Channels: **4**
- Compression Method: **1** (Zstandard)
- AES Key: **32** random bytes
- AES IV: **12** random bytes
5. **Write to `output.skibidi`:**
- Header (58 bytes)
- Encrypted Data (**Y** bytes)
___
Now to decode the `.skibidi file`, I need to reverse this process:
1. Read and parse the header to extract necessary information
2. Decrypt the data section using `AES-256-GCM`
3. Decompress the decrypted data using `Zstandard`
4. Convert the resulting raw pixel data into an image
Now, based on this, I wrote a [Python script](https://github.com/xtasy94/CTFW/blob/main/CTF_Files/TCP1PCTF/decrypt.py) which would perform these for me:
```python
from Crypto.Cipher import AES
import zstandard
from PIL import Image
import io
def read_skibidi_file(file_path):
with open(file_path, "rb") as file:
magic_number = file.read(4)
if magic_number != b"SKB1":
raise ValueError("Invalid Skibidi file format")
width = int.from_bytes(file.read(4), "little")
height = int.from_bytes(file.read(4), "little")
channels = int.from_bytes(file.read(1), "little")
compression_method = int.from_bytes(file.read(1), "little")
aes_key = file.read(32)
aes_iv = file.read(12)
encrypted_data = file.read()
print(f"Image dimensions: {width}x{height}")
print(f"Channels: {channels}")
print(f"Compression method: {compression_method}")
cipher = AES.new(aes_key, AES.MODE_GCM, nonce=aes_iv)
decrypted_data = cipher.decrypt(encrypted_data)
decompression_methods = [
lambda d: zstandard.ZstdDecompressor().decompress(d),
lambda d: zstandard.ZstdDecompressor().decompress(
d, max_output_size=width * height * channels
),
lambda d: d,
]
for method in decompression_methods:
try:
decompressed_data = method(decrypted_data)
break
except Exception as e:
print(f"Decompression attempt failed: {str(e)}")
else:
raise ValueError("All decompression attempts failed")
print(f"Decompressed data size: {len(decompressed_data)} bytes")
expected_size = width * height * channels
print(f"Expected data size: {expected_size} bytes")
if len(decompressed_data) != expected_size:
print("Warning: Decompressed data size does not match expected size")
mode = {1: "L", 3: "RGB", 4: "RGBA"}.get(channels)
if not mode:
raise ValueError(f"Unsupported number of channels: {channels}")
try:
image = Image.frombytes(mode, (width, height), decompressed_data)
except Exception as e:
print(f"Error creating image: {str(e)}")
with open("raw_data.bin", "wb") as f:
f.write(decompressed_data)
print("Raw decompressed data saved to 'raw_data.bin'")
raise
return image
def main():
input_file = "suisei.skibidi"
output_file = "output.png"
try:
image = read_skibidi_file(input_file)
image.save(output_file)
print(f"Successfully decoded {input_file} and saved as {output_file}")
except Exception as e:
print(f"Error: {str(e)}")
if __name__ == "__main__":
main()
```
```bash
$ python decrypt.py
Image dimensions: 3840x2160
Channels: 4
Compression method: 1
Decompression attempt failed: could not determine content size in frame header
Decompressed data size: 33177600 bytes
Expected data size: 33177600 bytes
Successfully decoded suisei.skibidi and saved as output.png
```
The script successfully decoded the image and saved it as `decoded_image.png`. Opening this PNG file revealed the flag:

`TCPIP{S3ems_L1k3_Sk1b1dI_T0il3t_h4s_C0nsUm3d_My_fr13nD_U72Syd6}`