file-run1 picoCTF 2022 Solution

Published: July 20, 2023

Description

Make the provided binary executable and run it with no arguments. It prints the flag immediately.

Grant execute permissions (chmod +x run).

Execute it: ./run.

bash
chmod +x run
bash
./run
bash
./run | cut -d ' ' -f4

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Run the binary
    Observation
    I noticed the challenge provided a downloaded ELF binary called 'run' and asked us to execute it, which suggested the first obstacle would be the missing execute bit that Linux does not set on downloaded files by default, requiring chmod +x before ./run would work.
    No tricks here; the compiled program prints picoCTF{...} on stdout.
    What didn't work first

    Tried: Type run or ./run directly without running chmod first.

    The shell returns 'Permission denied' because downloaded files have no execute bit set by default. You must run chmod +x run first to grant execute permission before the OS will allow the file to be launched as a program.

    Tried: Type run (without the ./ prefix) after chmod.

    The shell searches directories in $PATH but does not include the current directory, so it reports 'command not found' even though the file exists right there. Prefixing with ./ tells the shell to look in the current directory explicitly.

    Learn more

    On Linux, files downloaded from the web do not automatically receive execute permission. This is a security feature - it prevents accidentally running a downloaded file as a program. The chmod +x command adds the execute bit for the owner (and optionally group/others), making the file runnable as a program.

    The ./ prefix before the binary name tells the shell to look in the current directory for the file. Without it, the shell only searches the directories listed in $PATH, which typically does not include the current directory (another security measure - it prevents accidentally running a malicious file named ls dropped into the current directory).

    ELF (Executable and Linkable Format) is the standard binary format on Linux. You can inspect any ELF binary with file run to see its architecture and linking type, or with readelf -h run for detailed header information. Getting comfortable with these inspection tools is the foundation of binary analysis and reverse engineering.

    ELF binaries are split into sections: .text holds code, .rodata holds read-only data (string literals, const arrays), .data holds initialized globals, .bss holds uninitialized globals. The reason strings finds embedded flags so reliably is that strings walks all sections and prints any run of printable ASCII bytes terminated by a NUL or newline. String literals from C source compile into .rodata, which sits inside the ELF file untouched - so a flag baked in as const char* flag = "picoCTF{...}"; ends up directly readable. By default strings requires runs of length >= 4; pass -n 8 or longer to filter out noise.

    Static vs dynamic linking tradeoff. Statically linked binaries bundle every library function (libc, etc.) directly into the executable. They are self-contained and run on systems missing the shared libraries - useful for CTF authors avoiding version mismatches, but also much larger (often 1-10 MB instead of 10-100 KB) and may carry old/vulnerable library code that the host has already patched. Dynamic linking pulls libraries from .so files at runtime and benefits from system updates.

  2. Step 2
    Optional: trim the output
    Observation
    I noticed the setup commands included './run | cut -d ' ' -f4', which suggested the binary prints the flag embedded in a sentence rather than alone, making it useful to know how to isolate just the picoCTF{...} token for scripting or piping.
    Use cut -d ' ' -f4 to isolate the flag, or grep -oE to be format-independent.
    What didn't work first

    Tried: Run ./run | cut -d ' ' -f4 without first checking what the program actually prints.

    If the binary prints fewer or more words before the flag (e.g. 'Flag: picoCTF{...}' is only 2 fields), -f4 returns an empty line or the wrong token. Always run the binary once to count the fields before trusting a hardcoded field index.

    Tried: Use grep 'picoCTF' without the -o flag to extract just the flag token.

    Without -o, grep prints the entire matching line - which includes all the surrounding text. Adding -o along with -E and a pattern like 'picoCTF\{[^}]+\}' tells grep to output only the matched portion, giving a clean flag with no extra words.

    Learn more

    cut -d ' ' -f4 assumes the output is exactly four space-delimited fields with the flag in field 4 - which works only if the program prints something like The flag is: picoCTF{...} (1="The", 2="flag", 3="is:", 4=flag). Run the binary once first to confirm. If the prompt has a different number of words (e.g. it prints just picoCTF{...}, or wraps it in You found it: picoCTF{...}), the field index changes.

    This kind of output trimming is useful when scripting - for example, if you are piping the flag into another command or writing it to a file. Building the habit of cleanly extracting exactly the data you need, rather than copying and pasting from a messy terminal, will save time as CTF challenges become more complex.

    Another handy approach is grep -oE 'picoCTF\{[^}]+\}', which uses an extended regular expression to match and print only the flag-shaped token regardless of where it appears in the line. The -o flag tells grep to output only the matched portion rather than the whole line. This approach is robust even when the flag appears in the middle of a long sentence or has no predictable field position.

    Scripting these extraction patterns pays dividends during CTF competitions: if you solve ten challenges that all print flags as part of a sentence, having a reliable one-liner that extracts the token consistently avoids the error-prone process of manual copy-paste. Small investments in terminal proficiency compound into significant time savings over many challenges.

Interactive tools
  • 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{U51N6_Y0Ur_F1r57_F113_e55...}

Another quick warm-up to ensure your environment can execute ELF binaries.

Key takeaway

Linux file permissions are a first-line security control: files are not executable by default, and the shell deliberately excludes the current directory from PATH to prevent hijacking attacks with rogue binaries. ELF is the standard compiled binary format on Linux, and tools like file, readelf, and strings let you inspect any binary without running it. Understanding how the execute bit works and why ./ is required is foundational to every subsequent binary analysis and reverse engineering task.

Related reading

Want more picoCTF 2022 writeups?

Tools used in this challenge

What to try next