PICOCTF 2019 • FORENSICS • ARCHIVE AUTOMATION

like1000: Automated Recursive TAR Decompression

By AbdoAug 31, 2026
like1000 Archive Unpacking
Official Challenge Prompt

“This .tar file got tarred a lot. Also available at /problems/like1000_0_369bbdea2672ad260f212633f7368499 on the shell server.”

Category: Forensics / ScriptingPoints: 250 PTSFlag Format: picoCTF{...}
Provided File & Solver⬇️ Download solve.pySize: 10 MB initial archiveType: 1,000 Nested POSIX TARs
Dissector: Python tarfile / Shell Loop

💡 THE INTUITIVE ANALOGY (The Matryoshka Trap)

This challenge is the digital equivalent of a Russian Nesting Doll (Matryoshka). You open box #1000, and inside you find box #999 and packing peanuts (filler.txt). You open #999, and inside is #998. Doing this by hand in 7-Zip or Finder would require clicking 1,000 times, taking over 3 hours and cluttering your storage drive with gigabytes of redundant archives. In DFIR and CTFs, the golden rule is: if a task repeats more than 3 times, automate it immediately!

1. Anatomy of a POSIX TAR Archive

Unlike ZIP or RAR archives which compress data, a standard .tar (Tape Archive) file simply packages multiple files sequentially in 512-byte blocks with a header block preceding each file:

┌──────────────────────────────┬──────────────────────────────┬──────────────────────────────┐
│ Header Block (512 Bytes)     │ File Data Blocks (N x 512 B) │ Next File Header / End (Null)│
│ Filename: "999.tar"          │ Raw bytes of 999.tar archive │ Filename: "filler.txt"       │
│ Mode, UID, GID, Size, UStar  │                              │                              │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
METHOD A: SHELL ONELINER & LOOPING

2. Command-Line Batch Loops (Bash & PowerShell)

If you don't want to write a full Python script, you can run a one-line terminal loop that unpacks and deletes in real-time.

Linux / macOS (Bash)

A simple while loop that extracts the current tar, immediately removes the unpacked archive to conserve disk space, and continues until reaching layer 1:

while [ -f [0-9]*.tar ]; do
    tar -xvf *.tar
    rm -f [0-9]*.tar
done
rm -f filler.txt
echo "Done! flag.png extracted."
Windows 10/11 (PowerShell)

Native Windows PowerShell script using built-in tar.exe and Remove-Item:

while (Get-ChildItem -Filter "[0-9]*.tar") {
    $tar = (Get-ChildItem -Filter "[0-9]*.tar")[0]
    tar -xf $tar.Name
    Remove-Item $tar.FullName -Force
}
Remove-Item filler.txt -Force -ErrorAction SilentlyContinue
Write-Host "Done! flag.png extracted."
METHOD B: HIGH-SPEED PYTHON AUTOMATION & ONELINER

3. The 3-Second Python Solver (`solve.py`)

Python's standard library includes the tarfile module, which allows in-memory extraction and fast file deletion. It counts backwards from 1000 down to 1 and unpacks the entire sequence in under 4 seconds:

import tarfile
import os

# Unpack from layer 1000 down to layer 1
for i in range(1000, 0, -1):
    tar_name = f"{i}.tar"
    if os.path.exists(tar_name):
        print(f"Extracting {tar_name}...")
        try:
            with tarfile.open(tar_name, "r") as tar:
                tar.extractall()
            # Clean up old tar file to save disk space
            os.remove(tar_name)
        except Exception as e:
            print(f"Error on {tar_name}: {e}")

# Clean up filler dummy file
if os.path.exists("filler.txt"):
    os.remove("filler.txt")

print("\n🎉 Finished! Extracted flag.png.")
⚡ Terminal One-Liner (PowerShell / Bash):
python -c "import tarfile,os; [([tarfile.open(f'{i}.tar').extractall(), os.remove(f'{i}.tar')] if os.path.exists(f'{i}.tar') else None) for i in range(1000,0,-1)]; os.remove('filler.txt') if os.path.exists('filler.txt') else None; print('Done! flag.png extracted.')"

4. Recovered Flag Image

Extracted Image Artifact (flag.png):

like1000 Flag Image
picoCTF{l0t5_0f_tar5}

5. Key Takeaways for Archive Forensics

PrincipleBest PracticeWhy It Matters
In-Flight Garbage Collectionos.remove(tar_name) inside loopPrevents filling up disk storage when dealing with recursive archives or zip-bombs.
Python tarfile Moduletarfile.open(path, 'r')Cross-platform, standard library with 0 third-party dependencies required.
Pattern RecognitionNesting: 1000.tar → 999.tarStop doing manual unzipping as soon as a decremental index pattern is spotted.

6. The Complete Investigation Path & Mental Roadmap

Here is the step-by-step roadmap from initial archive inspection to extracting the final PNG flag:

STEP 1
Archive Inspection & Pattern Identification

Downloaded 1000.tar. Extracted it once to reveal 999.tar and filler.txt. Recognized the recursive nested pattern ($1000 \rightarrow 1$).

STEP 2
Storage Strategy (Avoiding Disk Overflow)

Realized that extracting 1,000 archives simultaneously would consume gigabytes of storage. Formulated the rule: immediately delete the parent archive as soon as its child is unpacked.

STEP 3
Scripted Decompression Loop

Wrote a Python script using tarfile.open() with a decremental loop range(1000, 0, -1) and os.remove() in-flight garbage collection.

STEP 4
Execution & Core Artifact Recovery

Ran solve.py. Script unnested all 1,000 layers in 3.2 seconds, reaching layer 1.tar and dropping flag.png.

STEP 5
Flag Extraction

Rendered flag.png to submit the flag: picoCTF{l0t5_0f_tar5}.

Cyber Amber
#f59e0b
PresetsClick to lock