bytemancy 0 picoCTF 2026 Solution

Published: March 20, 2026

Description

Can you conjure the right bytes? Download app.py and recover the exact input the server expects.

Download and read app.py to understand what byte sequence the server expects.

Launch the challenge instance and connect via netcat.

bash
cat app.py

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Read the source code
    Observation
    I noticed the challenge provides a downloadable app.py and describes a byte sequence the server expects, which suggested reading the source first to understand the exact comparison logic before attempting any connection.
    Download app.py. It prints a banner telling you exactly what to send: ASCII DECIMAL 101, three times, side-by-side, no space. ASCII 101 is the letter 'e'.
    bash
    cat app.py
    What didn't work first

    Tried: Send the literal string '101101101' to the server because the banner says 'ASCII DECIMAL 101' three times.

    The server compares the raw bytes received against b'\x65\x65\x65', which is the byte for the character 'e' repeated three times. Sending '101101101' sends nine digit characters (bytes 49,48,49,...) instead of three 'e' bytes (101,101,101), so the comparison fails immediately. The correct step is to convert the decimal code point 101 to its ASCII character using chr(101) = 'e', then send that character three times.

    Tried: Use hexadecimal notation and send '\x65\x65\x65' as a shell argument with echo.

    Running echo '\x65\x65\x65' in most shells prints the literal backslash-x string rather than the bytes, because single quotes prevent escape interpretation. The server receives nine bytes instead of three. To emit actual hex bytes from the shell use printf '\x65\x65\x65', or use Python: python3 -c "import sys; sys.stdout.buffer.write(b'\x65\x65\x65')".

    Learn more

    The ASCII (American Standard Code for Information Interchange) table maps integers 0-127 to characters. Decimal 101 is the lowercase letter 'e'. The full printable ASCII range spans 32 (space) through 126 (~). Knowing ASCII values by heart speeds up CTF challenges significantly - the most useful anchors are: 48='0', 65='A', 97='a'.

    The challenge description's phrasing "ASCII DECIMAL 101, three times" is intentionally explicit about the encoding layer: the number 101 is in decimal notation, it refers to the ASCII standard, and the character it represents is 'e' (0x65 in hex, 01100101 in binary). A beginner mistake is sending the string "101101101" (the digits) instead of "eee" (the characters).

    Netcat (nc) is a raw TCP/UDP socket tool. Piping output into nc HOST PORT sends it over the network as-is. The pipe sends the stdout of the left command to the stdin of nc, which forwards it to the server. This is the simplest way to interact with a challenge server for text-based challenges.

  2. Step 2
    Send the payload
    Observation
    I noticed that app.py compares raw input against b'\x65\x65\x65', which is ASCII 101 ('e') repeated three times, so I needed to pipe exactly those three bytes to the server using netcat.
    The server checks input equals b'\x65\x65\x65' (i.e. eee). HOST and the <PORT_FROM_INSTANCE> come from the instance launch page. echo appends \n; if the server bytes-compares strictly (no strip()), use echo -n or printf 'eee'. See netcat for CTF.
    bash
    echo 'eee' | nc <HOST> <PORT_FROM_INSTANCE>
    bash
    # If the server rejects the trailing newline:
    bash
    printf 'eee' | nc <HOST> <PORT_FROM_INSTANCE>
    python
    python3 -c "print('eee')" | nc <HOST> <PORT_FROM_INSTANCE>
    bash
    # Quick sanity check that 101 maps to 'e':
    python
    python3 -c 'print(chr(101))'

    Expected output

    e
    What didn't work first

    Tried: Use 'echo' without -n and get no flag back, then assume the host or port is wrong.

    echo appends a newline byte (0x0a) after 'eee', sending four bytes total instead of three. Some servers call strip() before comparing and accept this, but a strict bytes-equal check will fail silently or print an error. Switching to 'printf' or 'echo -n' removes the trailing newline and sends exactly the three bytes the server expects.

    Tried: Send the payload before reading app.py and guess the input is '101' (the decimal number as a string).

    Without reading app.py first it is easy to assume the server wants the decimal digits. The string '101' is three bytes (0x31, 0x30, 0x31) while the server expects three copies of byte 0x65. The source is explicit: the comparison is against b'\x65\x65\x65', so the only correct payload is 'eee'.

    Learn more

    The hex representation \x65\x65\x65 and the character string 'eee' are identical at the byte level. Decompose: 101 = 0x65 = 0b01100101 = 'e'. In Python, b'\x65' == b'e' evaluates to True. Hex escape sequences in byte strings are just an alternative notation for the same bytes, useful when the byte value does not correspond to a printable character.

    echo adds a trailing newline (\n, byte 10) to its output by default. Most challenge servers read input line-by-line and strip the newline before comparing, so this is usually fine. If a server requires no trailing newline, use echo -n or Python's sys.stdout.buffer.write(b'eee') without the newline.

    These bytemancy challenges form a series that progressively increases difficulty: from simple text to large repetitions to raw non-printable bytes to address-lookup challenges. They teach the distinction between character encodings, byte values, and how terminals and shells handle binary data - skills that are foundational for binary exploitation and network protocol work.

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{byt3m4ncy_0_...}

app.py asks for ASCII decimal 101 × 3, no spaces. ASCII 101 = 'e', so send the three-character string 'eee'.

Key takeaway

Every character a computer stores is ultimately a number; the ASCII standard defines the mapping between integers 0-127 and printable characters. Confusing a decimal code point like 101 with the literal digit sequence '101' is a classic mistake that appears whenever data crosses an encoding boundary, whether in protocol parsers, web forms, or embedded firmware. Recognizing encoding layers, and knowing tools like Python's chr() and ord() to convert between them, is foundational for both exploitation and defensive code review.

Related reading

Want more picoCTF 2026 writeups?

Useful tools for General Skills

What to try next