Skip to main content

Wave a Flag picoCTF 2021 Solution

Run a provided binary and explore its command-line options to uncover the flag.

Published: April 2, 2026Updated: August 13, 2026

Description

Can you invoke help flags for this program? Download the program warm.

Download the binary named warm from the challenge page.

bash
wget <url>/warm

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1Make the binary executable
    Observation
    The challenge provides a binary named warm, and a download on Linux arrives without the execute bit set. chmod +x is needed before the kernel will load and run it.
    Downloaded files aren't executable by default on Linux. Use chmod +x to grant execute permission.
    bash
    chmod +x warm
    What didn't work first

    Tried: Run the binary directly without chmod by using 'bash warm' or 'sh warm'.

    The shell interpreter rejects ELF binaries with a syntax error because bash tries to parse machine code as shell commands. chmod +x is needed so the kernel's ELF loader handles execution instead of a shell interpreter.

    Tried: Use 'chmod 777 warm' to grant full permissions instead of 'chmod +x'.

    chmod 777 works but also grants write permission to group and others, which is unnecessarily permissive. The recommended chmod +x (or chmod 755) grants execute permission without exposing the file to modification by other users.

    Learn more

    Every file in Linux has a set of permission bits that control who can read, write, or execute it. These bits are organized into three groups: owner, group, and others - each with read (r=4), write (w=2), and execute (x=1) permissions. When you download a file over HTTP, it arrives as a data file without execute permission set, even if it's a compiled binary.

    chmod +x adds the execute bit for all three groups (owner, group, and others) without changing any other bits. A common alternative that also sets a fixed, safe permission set is chmod 755 (owner: rwx=7, group: r-x=5, others: r-x=5), which additionally ensures group and others cannot write to the file. You can inspect current permissions with ls -l warm - a file ready to run looks like -rwxr-xr-x, while a non-executable looks like -rw-r--r--.

    Security note: Adding execute permission to untrusted binaries carries real risk. In CTF environments this is expected, but in production systems, only run executables from trusted sources. The principle of least privilege suggests only granting execute permission when necessary, and only to the appropriate users.

  2. Step 2Run with the help flag
    Observation
    The challenge asks you to invoke help flags for the program. That is an explicit hint: pass -h to the binary rather than reaching for deeper analysis.
    Pass -h to the program. Many programs print usage information - and in this case, the flag - when given a help argument.
    bash
    ./warm -h

    Expected output

    Oh, help? I actually am a flag!
    picoCTF{b1scu1ts_4nd_gr4vy_...}
    What didn't work first

    Tried: Run './warm --help' instead of './warm -h' when the short flag produces no output.

    This binary only checks argv[1] against the literal string '-h'. Passing '--help' causes the program to print an error or exit silently without printing the flag, because the argument comparison is not generic help-flag detection.

    Tried: Use 'strings warm' to extract the flag without running the binary.

    strings prints every printable sequence in the binary, and the flag does appear there as a literal. But the intended move is invoking the help flag at runtime, which is the skill on offer. strings is a fine fallback and skips the lesson about CLI conventions.

    Learn more

    The help flag convention (-h or --help) is one of the most universal CLI conventions. Almost every well-written command-line program responds to these flags by printing usage information: available options, expected arguments, and brief descriptions. It's the first thing to try when encountering an unfamiliar program.

    Programs implement this using argument parsing. In C, the code checks if argv[1] equals "-h". In Python, the argparse module handles this automatically. In Rust, the clap crate provides it. When a program doesn't respond to -h, try --help, -?, or running it with no arguments - many programs print usage when called incorrectly.

    Other ways to discover flags and options when official help isn't available:

    • strings warm - look for embedded option strings like -h, --help, or usage text
    • man warm - check for a manual page (less common for custom binaries)
    • strace ./warm - trace system calls to see what the program does
    • ltrace ./warm - trace library calls to see what functions it calls
Interactive tools
  • 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.
  • Regex TesterTest regular expressions against a string with live match highlighting, flag toggles, and common CTF pattern shortcuts.

Flag

Reveal flag

picoCTF{b1scu1ts_4nd_gr4vy_...}

Many programs respond to -h or --help with usage information - and in this case, the flag.

Key takeaway

Linux file permissions are a foundational access control: the execute bit has to be set before the kernel will run a binary, and chmod sets those bits per owner, group, and others. The -h and --help conventions are near-universal, and reading a program's own help output comes before any disassembler. Both habits, checking permissions and reading the built-in documentation, carry straight into incident response and system administration.

Related reading

Useful tools for General Skills

Where to go next