Operation Oni picoCTF 2022 Solution

Published: July 20, 2023

Description

A disk image hides an SSH key in a .ssh directory. Use Sleuth Kit to find its inode, extract the key with icat, fix permissions, and use it to log into the remote box and read flag.txt.

Decompress the image and use mmls to find the partition offset for the main Linux partition.

Run fls -r -o <offset> disk.img and search recursively for .ssh to locate the private key's inode number.

Extract the key with icat -o <offset> disk.img <inode> > key_file.

Set restrictive permissions (chmod 600 key_file) and SSH in using the challenge-provided port.

bash
gunzip disk.img.gz
bash
mmls disk.img
bash
fls -r -o <offset> disk.img | grep -i ssh
bash
icat -o <offset> disk.img <inode> > key_file
bash
chmod 600 key_file
bash
ssh -i key_file -p <PORT_FROM_INSTANCE> ctf-player@saturn.picoctf.net
bash
cat flag.txt

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Locate the SSH key with Sleuth Kit
    Observation
    I noticed the challenge provided a raw disk image rather than a mounted filesystem, which suggested using Sleuth Kit tools (mmls, fls, icat) to parse the partition table, list inodes recursively, and extract the private key from the expected ~/.ssh/ directory without ever mounting the image.
    Run mmls disk.img to find the last (and largest) partition's starting offset, then use fls -r -o <offset> disk.img to list files recursively. Search the output for .ssh to find the directory and the private key's inode number.
    bash
    mmls disk.img
    bash
    fls -r -o <OFFSET> disk.img | grep -i ssh
    bash
    icat -o <OFFSET> disk.img <INODE_OF_PRIVATE_KEY> > key_file
    What didn't work first

    Tried: Run fls -r disk.img without the -o offset flag, expecting to see the .ssh directory.

    Without -o, fls starts at sector 0 where the partition table lives, not the Linux ext4 partition. It either errors out or returns garbage entries. You must first read the offset from mmls (typically the last partition's Start value) and pass it with -o so fls addresses the correct filesystem.

    Tried: Use icat with the directory's inode instead of the private key file's inode, hoping to dump the key.

    icat on a directory inode dumps the raw directory block, which is a binary blob of filenames and child inodes, not the file content. The grep output of fls shows multiple inodes under .ssh (the directory itself, authorized_keys, id_ed25519, id_ed25519.pub). You need the inode for the private key file specifically - the one without a .pub extension.

    Learn more

    The Sleuth Kit is a suite of command-line forensics tools. mmls lists partition offsets, fls lists filesystem entries (including deleted files), and icat extracts a file by its inode number - all without mounting the image. On the picoCTF web shell these tools are preinstalled.

    SSH key files in /root/.ssh/ or a user's ~/.ssh/ are some of the most sensitive files on a Linux system. The private key allows authentication as that user to any server that has the corresponding public key in its authorized_keys file.

    In real forensics investigations, recovering SSH private keys from a disk image is a significant finding - it means the attacker may have had (or still have) access to other systems. The investigation would expand to identify which servers have the corresponding public key in their authorized_keys files.

  2. Step 2
    SSH into the box
    Observation
    I noticed that the private key extracted via icat would have default world-readable permissions, which SSH rejects with a 'Permissions too open' error, so I needed to chmod 600 the key file before using it with the -i flag and the challenge-provided port.
    Fix permissions (chmod 600 key_file) and connect with the provided port. Once logged in, ls reveals flag.txt.
    Learn more

    SSH enforces strict permissions on private key files: if the key file is readable by anyone other than the owner, SSH refuses to use it and displays a "Permissions too open" error. chmod 600 sets read/write for owner only (rw-------), satisfying this requirement. This is a security measure - it prevents other local users from reading your private key.

    The -i key_file flag tells SSH to use a specific identity file instead of searching the default locations (~/.ssh/id_rsa, ~/.ssh/id_ed25519, etc.). The -p 53918 flag specifies a non-standard port - running SSH on a non-default port is a common practice to reduce automated scanning noise, though it provides minimal actual security since port scanners like nmap find it easily.

    This challenge combines two skills: disk forensics (extracting artifacts from an image) and SSH authentication (using a key to log in). Both appear together in real incident response scenarios where an attacker left behind persistence mechanisms like authorized SSH keys, and the investigator needs to understand what access was established.

Interactive tools
  • Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
  • File Magic IdentifierIdentify file types from magic numbers. Paste hex bytes or drop a file to detect PNG, JPEG, ZIP, PDF, ELF, PCAP, SQLite, and dozens of other formats.
  • Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.

Flag

Reveal flag

picoCTF{k3y_5l3u7h_3396...}

This exercise reinforces basic SSH hygiene and disk forensics simultaneously.

Key takeaway

Disk forensics tools like The Sleuth Kit operate directly on raw filesystem structures, letting investigators browse, list, and extract files by inode without ever mounting the image or running the operating system. SSH private keys recovered this way are immediately usable for lateral movement to any host that trusts the corresponding public key, which is why incident responders treat any key material found on a compromised image as a high-priority finding. The same inode-level extraction technique recovers deleted files too, because deletion on most filesystems only removes the directory entry without zeroing the data blocks.

Related reading

Want more picoCTF 2022 writeups?

Useful tools for Forensics

What to try next