Nice netcat... picoCTF 2021 Solution

Published: April 2, 2026

Description

There is a program running on a server that just outputs some numbers - figure out what they mean.

Remote

Connect via netcat.

bash
nc mercury.picoctf.net 43239

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Connect and observe the output
    Observation
    I noticed the challenge description says the server 'just outputs some numbers,' which suggested the first step was to connect with netcat and capture the raw output before attempting any interpretation.
    Connect to the server. It streams a series of space-separated decimal numbers, then exits.
    bash
    nc mercury.picoctf.net 43239
    What didn't work first

    Tried: Paste the raw number output into CyberChef's 'From Decimal' recipe expecting to get the flag directly.

    CyberChef's 'From Decimal' recipe interprets comma-separated values by default, not space-separated. The output appears garbled or empty because the entire space-delimited string is treated as one token. Switch the delimiter to 'Space' in the recipe options to get correct character conversion.

    Tried: Try reading the numbers as hexadecimal instead of decimal, suspecting the server output is in hex.

    The values the server sends are plain decimal ASCII codes (e.g., 112 for 'p', 105 for 'i'). Treating them as hex (0x112 = 274) produces values well above 127, which are not valid ASCII characters and chr() in Python raises no error but gives unexpected Unicode glyphs. The step detail explicitly states decimal, and printable ASCII decimal values cluster in the 32-126 range.

    Learn more

    netcat (nc) is a fundamental network utility sometimes called the "Swiss Army knife" of networking. It can open raw TCP or UDP connections to any host and port, and it passes data between your terminal and the remote endpoint with no protocol overhead. Security researchers use it constantly to interact with CTF challenge servers, probe open ports, and debug networked services.

    When the server streams numbers and then exits, that's a one-shot interaction - the server sends a sequence of decimal integers (each one is an ASCII code for a single character of the flag) and closes the connection. Your job is to read those integers and convert each one back to its character. The same encoding can appear as octal, hexadecimal, or binary in other challenges.

  2. Step 2
    Convert decimal values to ASCII characters
    Observation
    I noticed the numbers the server streamed all fell in the 32 to 126 range, which are the decimal ASCII codes for printable characters, and suggested using Python's chr() to map each integer back to its corresponding character.
    Each number is the decimal ASCII code of one character of the flag. Use Python to convert them all at once. Copy the numbers from the output and paste them as a space-separated string.
    python
    python3 -c "output = '<paste numbers here>'; print(''.join([chr(int(x)) for x in output.split()]))"

    Expected output

    picoCTF{g00d_k1tty!_n1c3_k1tty!_...}
    What didn't work first

    Tried: Use ord() instead of chr() in the Python one-liner, expecting it to decode numbers to characters.

    ord() is the inverse operation - it takes a character and returns its integer code. Passing an integer string like '112' to ord() raises TypeError: ord() expected a character, but string of length 3 found. The correct function is chr(int(x)), which converts the integer to its corresponding ASCII character.

    Tried: Split the pasted number string on commas instead of spaces because some Python examples use comma-separated lists.

    The server output uses spaces as delimiters, not commas. Calling output.split(',') on a space-separated string returns a single-element list containing the entire original string. chr() then receives a long multi-digit string instead of individual number tokens and raises ValueError: invalid literal for int(). Use output.split() (no argument) which splits on any whitespace including spaces and newlines.

    Learn more

    ASCII (American Standard Code for Information Interchange) is a 7-bit character encoding that maps integers 0 to 127 to characters. Printable characters occupy 32 to 126: lowercase letters are 97 to 122, uppercase 65 to 90, digits 48 to 57, and common punctuation fills the gaps. Understanding ASCII values is essential for CTF work - you'll encounter them in many forms: decimal, hexadecimal (0x70 = p), octal, and binary.

    Python's chr() function converts an integer to its corresponding Unicode character (which is identical to ASCII for values 0 to 127). The inverse is ord('p') which returns 112. The one-liner splits the space-separated number string, converts each token to an integer, maps it through chr(), and joins the results into the flag string.

    Combining with netcat in one pipeline: You can also pipe netcat's output directly into Python without copy-pasting:

    • timeout 5 nc mercury.picoctf.net 43239 | python3 -c "import sys; print(''.join(chr(int(x)) for x in sys.stdin.read().split()))"

    The timeout 5 prefix bounds the wait at 5 seconds. nc sometimes does not detect the remote close cleanly and will hang forever waiting for more input; the timeout is a defensive guardrail.

    This kind of pipeline - connecting tools with | - is a core Unix philosophy skill that makes terminal workflows far more powerful.

Interactive tools
  • Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.
  • Recipe ChainStack decoders into a pipeline: Base64, hex, ROT, XOR, Morse, URL, Atbash, Vigenère, and more. Magic mode auto-discovers the chain. Bookmark the URL to save it.
  • Number Base ConverterConvert numbers between binary, octal, decimal, and hexadecimal instantly. Enter any value and see all four bases update in real time.

Flag

Reveal flag

picoCTF{g00d_k1tty!_n1c3_k1tty!_...}

The server streams the flag as space-separated decimal ASCII values.

Key takeaway

ASCII is the foundational mapping between integers and human-readable characters that underlies all text processing in computing. Recognizing decimal, hex, octal, and binary representations of ASCII values is a core skill in CTF work and in real-world debugging, where character data shows up in many numeric disguises across network captures, binary files, and log output. The ability to quickly convert between representations using command-line tools or a one-line script separates fast solvers from slow ones.

Related reading

Want more picoCTF 2021 writeups?

Useful tools for General Skills

What to try next