Piece by Piece picoCTF 2026 Solution

Published: March 20, 2026

Description

After logging in, you will find multiple file parts in your home directory. These parts need to be combined and extracted to reveal the flag.

Launch the challenge instance and SSH in.

List files in the home directory to see the split archive parts.

bash
ls -la
bash
file *

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    SSH in and list the file parts
    Observation
    I noticed the challenge description says 'multiple file parts' live in the home directory, which suggested the first step was to SSH in and run 'ls' plus 'file *' to see exactly how many parts exist and confirm their true archive format via magic bytes.
    Log into the challenge instance via SSH. Your home directory contains multiple numbered split-archive parts (e.g. file.zip.001, file.zip.002, ... or file.aa, file.ab, ...).
    bash
    ssh ctf-player@<HOST> -p <PORT_FROM_INSTANCE>
    bash
    ls -la
    bash
    file *

    Expected output

    Archive:  combined.zip
      inflating: flag.txt
    What didn't work first

    Tried: Run 'file *' and trust the filename extension instead of the magic byte output.

    Extensions are cosmetic and can be stripped or renamed by the challenge author. 'file' reports the true type from magic bytes - if it says 'Zip archive data' on a file named 'data.bin', the extension is irrelevant and you should treat it as a ZIP. Trusting the name and trying the wrong extractor (e.g. 'tar xf data.bin') produces a 'not in gzip format' or similar error.

    Tried: Use 'ls' without '-v' or '-la' and assume the default listing order is the correct reassembly order.

    Plain 'ls' sorts alphabetically, which breaks natural numeric order when part numbers are not zero-padded (e.g. part1, part2, ..., part10 sorts as part1, part10, part2). The '-v' flag enables version/natural sort so part10 comes after part9. Concatenating in the wrong order corrupts the archive magic bytes and causes extraction to fail silently or report 'End-of-central-directory signature not found'.

    Learn more

    Split archives are a technique for dividing large files into smaller chunks for transfer over media with size limits, email attachments, or slow connections. The original file is split into numbered parts that must be reassembled in order before extraction. Common formats include .zip.001/.zip.002 (WinZip split), .part1.rar/.part2.rar (WinRAR split), or alphabetical suffixes from the Unix split command (file.aa, file.ab, ...).

    The file command reads a file's magic bytes (the first few bytes of the file) to determine its true type regardless of its extension. This is essential in CTF challenges where files may have misleading names or no extension. For example, a file named data.bin might actually be a ZIP archive (magic bytes PK\x03\x04), a gzip stream (magic bytes \x1f\x8b), or a PNG image (\x89PNG).

    Understanding file magic bytes is a foundational forensics skill. Tools like file, xxd, and binwalk all use magic byte databases to identify file types, and this knowledge lets you choose the correct extraction tool even when extensions are wrong or missing.

  2. Step 2
    Combine all parts
    Observation
    I noticed the home directory held numbered or alphabetically suffixed split-archive parts, which suggested using 'cat' with a glob ordered by 'ls -v' to concatenate them in strict sequence and produce a single valid archive file.
    Concatenate the parts in deterministic sort order. Always verify the glob expansion before piping into cat - a wrong order produces a corrupt archive that fails to extract.
    bash
    # Always check what the glob expands to first:
    bash
    ls -v *part* *.zip.* *.a? 2>/dev/null
    bash
    # Numbered .zip parts:
    bash
    cat *.zip.* > /tmp/combined.zip
    bash
    # Letter-suffixed (split default):
    bash
    cat *.a? > /tmp/combined.zip
    bash
    # RAR-style multi-part - tighten the glob to exclude unrelated files:
    bash
    cat *part*.rar > /tmp/combined.rar
    bash
    # When you really need natural sort (e.g. part1, part2, ..., part10):
    bash
    cat $(ls -v *part*) > /tmp/combined
    bash
    file /tmp/combined*
    What didn't work first

    Tried: Use 'cat *.zip' instead of 'cat *.zip.*' to concatenate the parts.

    The glob '*.zip' matches only files whose name ends exactly in '.zip', which is the final combined file if it already exists - not the numbered parts like 'file.zip.001'. The numbered parts match '*.zip.*' (with a trailing dot and suffix). Using the wrong glob either captures nothing or captures an already-combined file, producing a silently doubled or empty archive.

    Tried: Use 'zip -FF combined.zip --out fixed.zip' to repair the archive instead of reassembling from parts.

    zip -FF is a repair tool for a single corrupt ZIP, not a reassembly tool for split parts. It expects one file with a damaged internal structure, not multiple separate part files. Running it on just the first part produces 'fixing: combined.zip' followed by extraction errors because the central directory that zip uses to locate files lives in the last part, which was never concatenated.

    Learn more

    The Unix cat command (concatenate) is the correct tool for reassembling split binary files. Since binary archives have their own internal structure with an end-of-archive marker, simply concatenating the parts in sorted order produces a valid archive that extraction tools can parse. Shell glob expansion (*.zip.*) sorts alphabetically/numerically by default, which is the correct order for numbered parts.

    Sort order matters critically. If parts are concatenated out of order, the resulting file will be corrupt and unextractable. For parts with numeric suffixes, ensure the sort is numeric: 001, 002, 003, ..., 009, 010 rather than 001, 010, 002 (lexicographic order). The glob *.zip.* sorts correctly because the numeric suffix is zero-padded.

    For more complex reassembly scenarios, tools like cat $(ls -v *.part) (using ls -v for natural sort), or explicit cat part1 part2 part3 > combined, give you full control over the concatenation order.

  3. Step 3
    Extract the archive with the password
    Observation
    I noticed the combined file was a password-protected ZIP and the challenge instructions file contained the password 'supersecret', which suggested running 'unzip -P supersecret combined.zip' to extract its contents.
    The combined file is a password-protected ZIP. The instructions file says the password is 'supersecret'. Use unzip with that password.
    bash
    cat $(ls -v *) > combined.zip
    bash
    unzip -P supersecret combined.zip
    What didn't work first

    Tried: Try 'unzip combined.zip' without the -P flag and enter the password interactively when prompted.

    Interactive password entry works fine locally, but inside an SSH session without a TTY it can hang or fail silently. More importantly, if the wrong combined order produced a corrupt archive, the prompt never appears - unzip errors out before asking. Using '-P supersecret' explicitly in the command makes it scriptable and surfaces the real error (wrong password vs. corrupt archive) as a distinct exit code.

    Tried: Try 7z x combined.zip without specifying the password, hoping 7z will auto-detect or prompt.

    7z does prompt for a password on encrypted ZIPs, but it applies ZipCrypto detection differently than unzip and may report 'Wrong password' even with the correct password if the archive uses AES-256 encryption (introduced in WinZip 9). Conversely, ZipCrypto archives can be cracked with pkcrack if you know plaintext - jumping straight to cracking wastes time when the password is given in the challenge instructions file.

    Learn more

    Common archive formats and their extraction commands: unzip for ZIP files, tar xf for tar archives (which auto-detects gz/bz2/xz compression), 7z x for 7-Zip archives, unrar x for RAR files, and gunzip/bunzip2/unxz for single-stream compressed files.

    Password-protected archives are common in CTF challenges. Standard passwords to try include picoCTF, password, flag, the challenge name, and variations. If those fail, tools like john with zip2john/rar2john or hashcat can crack the password. ZIP encryption (ZipCrypto) is particularly weak and can be cracked even without a password if you know the contents of one file in the archive (known-plaintext attack).

    For layered archives (a tar inside a zip inside a gz), you may need to run multiple extraction steps. binwalk -e can automatically extract nested archives - it scans for file signatures within files and extracts everything it finds.

  4. Step 4
    Read the flag
    Observation
    I noticed extraction produced output files in /tmp, so I used 'strings' piped through 'grep' to scan all extracted content for the picoCTF flag pattern, since the flag could be embedded as text in a file with a non-obvious name or extension.
    Catalogue everything that came out before grepping. The flag may be in the filename, in binary data, or in a file that doesn't have a .txt extension.
    bash
    ls /tmp/
    bash
    # First triage what you got - types and any hints in filenames:
    bash
    file /tmp/*
    bash
    ls /tmp/ | grep -iE 'flag|pico'
    bash
    # Search across both text and binary:
    bash
    strings /tmp/* 2>/dev/null | grep -E 'picoCTF\{[^}]+\}'
    bash
    # As a fallback, the bare grep across all extracted files:
    bash
    grep -roa 'picoCTF{[^}]*}' /tmp/ 2>/dev/null
    Learn more

    After extraction, the flag is typically in a file named flag.txt, flag, or a similarly obvious name, but not always. Run file * over the extracted set first - a binary or an image among the outputs is a strong hint that the flag is embedded somewhere non-obvious. strings * | grep picoCTF handles binary data; if even that fails, walk the files with xxd and look for fragmented or encoded flags.

    CTF flags sometimes appear in unexpected places: as the filename itself, embedded in an image (check with strings), inside binary data (check with xxd | grep -a pico), or hidden behind one more decoding step (base64, hex, ROT13). For more on hex-level inspection see Hex dumps for CTF; for the general shell toolkit used here see Linux CLI for CTF.

    This challenge teaches a workflow that appears frequently in forensics and incident response: receiving a collection of file fragments, reassembling them, extracting the archive, and searching the contents. The same sequence is used to recover data from split disk dumps, fragmented network transfers, and distributed backups.

Flag

Reveal flag

picoCTF{z1p_4nd_sp11t_f1l3s_4r3_fun_...}

SSH into the server, read the instructions file for the password ('supersecret'), combine the split parts with cat, and unzip with -P supersecret.

Key takeaway

Split-archive reassembly is a fundamental file-recovery technique: binary files divided with 'split' or a zip-splitting tool must be concatenated in strict order before the archive format becomes valid again. The 'file' command identifies file types by magic bytes rather than extensions, which is essential whenever names are stripped, changed, or misleading. The same workflow appears in digital forensics when recovering fragmented disk images, carving files from raw network captures, or reconstructing data distributed across backup segments.

Related reading

Want more picoCTF 2026 writeups?

Useful tools for General Skills

What to try next