Wave a Flag picoCTF 2021 Solution

Published: April 2, 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 1
    Make the binary executable
    Observation
    I noticed the challenge provides a downloaded binary named warm, which on Linux arrives without the execute bit set by default, suggesting that 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 2
    Run with the help flag
    Observation
    I noticed the challenge asks to 'invoke help flags for this program', which is an explicit hint that the flag is revealed by passing -h to the warm binary rather than through any 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 all printable character sequences embedded in the binary, and the flag text does appear as a string literal. However, the expected approach is to invoke the help flag at runtime, which is the skill the challenge is teaching. strings is a useful fallback technique but bypasses the intended 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

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 mechanism: the execute bit must be explicitly set before the kernel will run a binary, and chmod controls those bits per owner, group, and others. The -h and --help conventions are near-universal in CLI software, and reading a program's own help output is always the first step before reaching for a disassembler. Both habits, checking permissions and reading built-in documentation, transfer directly to real incident response and system administration work.

Related reading

Want more picoCTF 2021 writeups?

Useful tools for General Skills

What to try next