Description
There is a program running on a server that just outputs some numbers - figure out what they mean.
Setup
Connect via netcat.
nc mercury.picoctf.net 43239Solution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Connect and observe the outputObservationI 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.bashnc mercury.picoctf.net 43239What 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.
Step 2
Convert decimal values to ASCII charactersObservationI 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.pythonpython3 -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 isord('p')which returns 112. The one-liner splits the space-separated number string, converts each token to an integer, maps it throughchr(), 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 5prefix bounds the wait at 5 seconds.ncsometimes 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.