Reincarnation
Reincarnation
Platform: duckerz | Category: Forensics | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-01-09 | Status: Solved Techniques: file_carving, filesystem_analysis, magic_bytes_search, multi_layer_decoding
Summary
Task: recover deleted files from an ext4 filesystem image. Solution: search for gzip magic bytes in the raw image, extract and decompress hidden gzip streams, then decode a multi-layer chain (Base32, Base64, TAR, gzip) to obtain the flag.
Reincarnation (Реинкарнация) - duckerz CTF
Description
Original (Russian):
Мне посоветовали вырезать французскую локализацию, но у меня убрались все файлы! Повезло папки остались, почини пожалуйста!
Translation:
I was advised to remove the French localization, but all my files got deleted! Luckily the folders remained, please fix it!
Files: reincarnation.img (2MB ext4 filesystem image)
Analysis
Initial Reconnaissance
The task name "Реинкарнация" (Reincarnation) strongly hints at recovering deleted files - bringing them "back to life".
bash read-only • copy allowed# Identify file type file reincarnation.img # Output: Linux rev 1.0 ext4 filesystem data # Search for interesting strings strings reincarnation.img | grep -i flag # Found references: flag.txt.gz, flag.png.gz, flag.odt.gz
The filesystem contains references to deleted gzip-compressed files. The "French localization" mention is a red herring.
Finding Hidden Data
Since files were deleted but data may still exist on disk, we search for gzip magic bytes:
bash read-only • copy allowed# Gzip magic bytes: 0x1f 0x8b xxd reincarnation.img | grep "1f8b"
Found 4 gzip signatures at offsets:
0x121400- ODT document0x123400- Fake flag file0x1f0400- PNG image0x1fb000- Encoded data (contains real flag)
Solution
Step 1: Extract Gzip Streams
python read-only • copy allowed#!/usr/bin/env python3 import gzip import io # Read the filesystem image with open('reincarnation.img', 'rb') as f: data = f.read() # Gzip offsets found via magic byte search offsets = [0x121400, 0x123400, 0x1f0400, 0x1fb000] for i, offset in enumerate(offsets): chunk = data[offset:offset+100000] try: # Find end of gzip stream by trial for size in range(100, len(chunk)): try: decompressed = gzip.decompress(chunk[:size]) print(f"File {i+1} at 0x{offset:x}: {len(decompressed)} bytes") with open(f'extracted_{i+1}.bin', 'wb') as out: out.write(decompressed) break except: continue except Exception as e: print(f"Error at offset 0x{offset:x}: {e}")
Step 2: Analyze Extracted Files
| Offset | Content | Description |
|---|---|---|
| 0x121400 | ODT | OpenDocument Text file |
| 0x123400 | Text | Fake flag: "NotDUCKERZ{Is_not_valied_flag}" |
| 0x1f0400 | PNG | 233x233 image |
| 0x1fb000 | Text | Base32 encoded data |
Step 3: Decode Multi-Layer Encoding
The 4th file contains Base32 encoded data with a complex encoding chain:
python read-only • copy allowed#!/usr/bin/env python3 import gzip import base64 import tarfile import io # Read image and extract gzip at 0x1fb000 with open('reincarnation.img', 'rb') as f: data = f.read() # Extract and decompress gzip chunk = data[0x1fb000:0x1fb000+100000] decompressed = gzip.decompress(chunk[:933]) # Layer 1: Base32 decode decoded_b32 = base64.b32decode(decompressed.decode().strip().replace('\n', '')) # Layer 2: Base64 decode decoded_b64 = base64.b64decode(decoded_b32) # Layer 3: TAR archive tar = tarfile.open(fileobj=io.BytesIO(decoded_b64)) tar.extractall('.') # Layer 4: Gzip decompress flag.txt.gz with gzip.open('flag.txt.gz', 'rb') as f: flag = f.read().decode() print(f"Flag: {flag}")
Decoding Chain Visualization
reincarnation.img
|
v (extract at 0x1fb000)
[GZIP compressed]
|
v (gzip decompress)
[Base32 encoded text]
|
v (base32 decode)
[Base64 encoded data]
|
v (base64 decode)
[TAR archive]
|
v (tar extract)
flag.txt.gz
|
v (gzip decompress)
DUCKERZ{REDACTED}
Lessons Learned
- Deleted != Gone: In filesystem images, deleted files often leave data behind
- Magic bytes hunting: Searching for file signatures can recover "deleted" content
- Multi-layer encoding: CTF challenges often chain multiple encodings
- Red herrings: "French localization" was irrelevant - focus on the core task
- Fake flags: Always verify flags match the expected format (DUCKERZ{...})
Tools Reference
bash read-only • copy allowed# Identify filesystem type file image.img # Search for strings strings image.img | grep -i flag # Find gzip magic bytes xxd image.img | grep "1f8b" # Mount ext4 image (alternative approach) sudo mount -o loop,ro reincarnation.img /mnt/img