First Find picoGym Exclusive Solution

Published: March 5, 2024

Description

Find uber-secret.txt hidden somewhere inside the provided archive. Hidden directories (those prefixed with a dot) might conceal the answer.

Local forensicsDownload files.zip

Download the archive and extract it. Grep can inspect the expanding tree faster than manual browsing.

Hidden directories (prefixed with .) appear once the archive is unzipped, so make sure your shell shows them.

bash
wget https://artifacts.picoctf.net/c/500/files.zip
bash
unzip files.zip && rm files.zip

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 hidden folder
    Observation
    I noticed the challenge description explicitly mentioned hidden directories prefixed with a dot, which suggested that a recursive content search tool like grep would find the target file faster than manually browsing multiple levels of nested directories.
    Once unzipped, the structure includes .secret nested multiple levels deep. Rather than traversing each directory by hand, let grep reveal which file mentions picoCTF.
    bash
    grep -R pico

    Expected output

    files/adequate_books/more_books/.secret/deeper_secrets/deepest_secrets/uber-secret.txt:picoCTF{f1nd_15_f457_ab44...}
    What didn't work first

    Tried: Run ls -R to explore the directory tree manually before searching for the flag

    ls -R prints every path but does not show file contents, so you still have to open each candidate file one by one. At several levels of nesting with many directories, this becomes impractical. grep -R searches file contents in a single pass, returning the exact path and the matching line simultaneously.

    Tried: Use find . -name uber-secret.txt to locate the file without grep

    find would work here because you already know the exact filename, but in real challenges the filename is often unknown or obfuscated. grep -R pico discovers the file even if you only know a string the flag contains, making it the more general and reliable first approach.

    Learn more

    In Unix-like systems, any file or directory whose name begins with a dot (.) is treated as hidden. These entries are excluded from the default output of ls and most file browsers, but they are fully accessible if you know the name or use flags like ls -a (show all). This convention is commonly used for configuration directories (~/.ssh, ~/.config) and is a classic hiding spot in CTF challenges.

    The recursive grep approach bypasses the need to navigate the directory tree at all. grep -R pico . opens every file in every directory (including hidden ones) and prints matching lines. Because the flag starts with picoCTF, the pattern pico is broad enough to match it without needing to know the exact flag format in advance.

    In a real security context, analysts use exactly this approach to search for sensitive strings (passwords, API keys, PII) across a file system during a code audit or incident response. Tools like trufflehog, gitleaks, and semgrep automate this at scale for large repositories, but knowing the underlying grep mechanics helps you understand what those tools are doing and catch cases they miss.

  2. Step 2
    Inspect uber-secret.txt
    Observation
    I noticed the grep output included the full path to uber-secret.txt alongside the matching flag text, which suggested reading the file directly with cat to confirm the exact flag contents.
    Grep output shows that files/adequate_books/more_books/.secret/deeper_secrets/deepest_secrets/uber-secret.txt contains the flag. Read it directly to confirm.
    bash
    cat files/adequate_books/more_books/.secret/deeper_secrets/deepest_secrets/uber-secret.txt

    Expected output

    picoCTF{f1nd_15_f457_ab44...}
    Learn more

    Once grep reveals the full path, cat reads and prints the file contents. The deeply nested path (adequate_books/more_books/.secret/deeper_secrets/deepest_secrets/) demonstrates how archives can be structured to make manual browsing impractical - there are simply too many directories to check one by one.

    The hidden directory name .secret is a common CTF convention inspired by real-world hidden directories. On Linux systems, the .ssh directory stores private keys, .bash_history stores command history, and .gnupg stores GPG keys - all sensitive files that rely partially on the "hidden by convention" mechanism for obscurity. Attackers know to check these locations first.

    The takeaway is that security through obscurity alone - hiding files in unusual places or giving them inconspicuous names - is not a reliable defense. Any tool that reads the file system recursively (grep, find, Autopsy) will discover the file regardless of its depth or name. Real security requires access controls, encryption, or both.

  3. Step 3
    Trim the output
    Observation
    I noticed that the initial grep output included the file path prefix before the flag text, which suggested piping through a second grep with the -oE flag to extract only the picoCTF{...} token cleanly.
    If you only want the flag text, pipe grep through an extractor such as grep -oE, cut, or sed to strip away the path prefix.
    bash
    grep -R pico | grep -oE 'picoCTF\{.*\}' --color=none

    Expected output

    picoCTF{f1nd_15_f457_ab44...}
    What didn't work first

    Tried: Use grep -R pico | cut -d: -f2 to strip the filename prefix and print only the flag line

    cut -d: -f2 splits on the first colon and returns the second field, but the flag itself contains a colon in picoCTF{...} after extraction - more importantly, the filename path may contain colons on some systems, causing cut to split at the wrong colon. The -oE 'picoCTF\{.*\}' pattern matches exactly the flag token regardless of surrounding punctuation.

    Tried: Omit --color=none and pipe the result directly into a script or file

    Without --color=none, grep emits ANSI escape codes around the match (e.g. \e[01;31m...\e[0m) when stdout is a terminal. If you pipe the output into another command or redirect to a file, those invisible color bytes are embedded in the string, causing string comparisons or copy-paste into the flag submission form to silently fail.

    Learn more

    When grep finds a match inside a named file, it outputs the result in the format filename:matching_line. The nested grep with -o and an extended regex extracts only the portion of the line that matches picoCTF\{.*\}. The .* inside the braces is a greedy match that captures everything between the opening and closing brace.

    The --color=none flag prevents ANSI escape codes from appearing in the output, which matters if you are piping the result into another program or saving it to a file - terminal color codes are invisible on screen but would corrupt the text if processed further.

    This kind of double-grep pipeline (first to find relevant lines, then to extract exactly the right token) appears constantly in CTF automation scripts. Once you internalize it, you can adapt it to extract any structured pattern from noisy output: IP addresses, URLs, email addresses, UUIDs, and more. The same pattern is used in log parsing, threat intelligence extraction, and security automation.

Flag

Reveal flag

picoCTF{f1nd_15_f457_ab44...}

Once you know the hidden directory path, viewing uber-secret.txt prints the precise flag shown by grep.

Key takeaway

Unix dot-prefix convention hides files and directories from casual directory listings but provides no actual access control; any recursive search tool finds them immediately. Security through obscurity treats inconspicuous placement as a substitute for real protection, which fails the moment an attacker uses grep -R, find, or a forensic framework. Sensitive data at rest must be protected by filesystem permissions and encryption, not by depth or naming conventions alone.

Related reading

Want more picoGym Exclusive writeups?

Useful tools for General Skills

What to try next