plumbing picoCTF 2019 Solution

Published: April 2, 2026

Description

Connect to a program that outputs data faster than you can read it. Use pipes to filter the output.

Remote

Connect to the server at 2019shell1.picoctf.com port 4427.

The server outputs a large stream of data.

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Pipe netcat output through grep
    Observation
    I noticed the challenge description said the server outputs data faster than you can read it, which suggested the terminal scrollback would be overwhelmed and the only practical approach was to filter nc's stdout in real time using a Unix pipe into grep to isolate the flag line.
    The server floods the terminal with data. By piping nc's stdout directly into grep, only lines containing 'picoCTF' are printed - the rest is silently discarded.
    bash
    nc 2019shell1.picoctf.com 4427 | grep picoCTF

    Expected output

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

    Tried: Scroll through the terminal output manually to find the flag

    The server emits thousands of lines faster than any human can read, causing the terminal scrollback buffer to overflow and the flag line to be lost before you can spot it. A pipe to grep filters the stream at the OS level so only the matching line reaches your terminal.

    Tried: Save the full output first with nc 2019shell1.picoctf.com 4427 > output.txt and then grep the file afterward

    This works but stalls - nc keeps the connection open until the server closes it, so the file is not written until the stream ends (which may never happen or take a very long time). Piping directly with | grep picoCTF lets grep print the flag the instant that line arrives, without waiting for the connection to close.

    Learn more

    The Unix pipe (|) is one of the most powerful ideas in operating system design. It connects the standard output (stdout) of one process directly to the standard input (stdin) of another, allowing programs to be composed like building blocks without either program knowing about the other.

    In this challenge, nc (netcat) sends everything from the server to its own stdout. Without a pipe, all of that data would scroll past in the terminal. By piping into grep picoCTF, only lines matching the pattern are forwarded to your terminal - grep reads stdin line by line and writes only matching lines to its own stdout.

    This pattern appears constantly in real-world Linux work:

    • ps aux | grep nginx - find running nginx processes
    • dmesg | grep -i error - find kernel errors in boot log
    • cat /etc/passwd | grep bash - find users with bash shells
    • journalctl | grep "Failed password" - find SSH brute-force attempts

    The philosophy behind Unix pipes - "do one thing well, and compose programs together" - is described in the original Unix philosophy by Doug McIlroy. It means that grep, sort, awk, sed, and dozens of other tools can be combined in arbitrary ways without modifying any of them.

    Redirecting output with > and >>: Beyond pipes, Unix also supports file redirection. nc host port > output.txt saves all output to a file instead of the terminal. >> appends rather than overwrites. 2>errors.txt redirects standard error (stderr) separately from stdout. And &> redirects both stdout and stderr to the same destination. These are essential when capturing large output for later analysis - for example, saving a full server response and then grepping it offline with multiple different patterns.

    Named pipes (FIFOs) are a more advanced form that creates a pipe as a file in the filesystem using mkfifo. This allows two separate processes that cannot be composed with | to communicate. Process substitution (<(command) in bash) is a related feature that lets you pass the output of a command as if it were a file: diff <(cat file1) <(sort file2) compares file1 content against the sorted version of file2 without creating temporary files.

    In exploit development, piping is a critical technique. A typical pattern is python3 exploit.py | nc target 1337 - the exploit script generates binary payload bytes on stdout, and nc sends them to the server. For interactive sessions where you need both to send data and read responses, pwntools (a Python CTF framework) provides a higher-level abstraction with process() and remote() objects that manage bidirectional communication, timeouts, and binary I/O transparently. But understanding pipes and redirects is the prerequisite foundation for using those tools effectively.

Flag

Reveal flag

picoCTF{digital_plumb3r_...}

Unix pipes (|) connect stdout of one command to stdin of another - essential for filtering large output streams.

Key takeaway

The Unix pipe operator connects the stdout of one process directly to the stdin of another, enabling arbitrary composition of single-purpose tools without modifying any of them. This design principle, articulated in the original Unix philosophy, means grep, sort, awk, sed, and netcat can be chained to process data streams of any size or complexity. In security work, the same pattern drives exploit delivery (python3 exploit.py | nc target port), log triage (journalctl | grep 'Failed password'), and network forensics (tcpdump | strings).

Related reading

Want more picoCTF 2019 writeups?

Useful tools for General Skills

What to try next