← Back to Writeups
CUSTOMEasyForensics

Reincarnation

XESXOR9/2/20263 min read
#forensics#custom#easy#file_carving#filesystem_analysis#magic_bytes_search#multi_layer_decoding#linux

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
# 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
# Gzip magic bytes: 0x1f 0x8b
xxd reincarnation.img | grep "1f8b"

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Found 4 gzip signatures at offsets:

  • 0x121400 - ODT document
  • 0x123400 - Fake flag file
  • 0x1f0400 - PNG image
  • 0x1fb000 - Encoded data (contains real flag)

Solution

Step 1: Extract Gzip Streams

python
#!/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

OffsetContentDescription
0x121400ODTOpenDocument Text file
0x123400TextFake flag: "NotDUCKERZ{Is_not_valied_flag}"
0x1f0400PNG233x233 image
0x1fb000TextBase32 encoded data

Step 3: Decode Multi-Layer Encoding

The 4th file contains Base32 encoded data with a complex encoding chain:

python
#!/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

  1. Deleted != Gone: In filesystem images, deleted files often leave data behind
  2. Magic bytes hunting: Searching for file signatures can recover "deleted" content
  3. Multi-layer encoding: CTF challenges often chain multiple encodings
  4. Red herrings: "French localization" was irrelevant - focus on the core task
  5. Fake flags: Always verify flags match the expected format (DUCKERZ{...}) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Tools Reference

bash
# 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

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍