Description
Can you conjure the right bytes? Download app.py and recover the exact input the server expects.
Setup
Download and read app.py to understand what byte sequence the server expects.
Launch the challenge instance and connect via netcat.
cat app.pySolution
Walk me through it- Step 1Read the source codeOpen app.py. The check is literally
expected = 'e' * 1751, so 1751 isn't arbitrary, it's the source. ASCII 101 ='e'. See Python for CTF for payload-shaping idioms.bashcat app.pybashgrep 'expected' app.py # confirms 'e' * 1751pythonpython3 -c 'print(len("e"*1751))' # sanity: 1751Learn more
The step from 3 repetitions (bytemancy-0) to 1751 repetitions (bytemancy-1) is designed to rule out manual typing. You cannot reasonably type 1751 'e' characters by hand, so the challenge forces you to use a script or shell one-liner to generate the payload programmatically. This is a key lesson: automation is a core CTF skill.
Python string multiplication (
'e' * 1751) creates a string of exactly 1751'e'characters in a single expression. The same works for byte strings:b'e' * 1751. This technique extends to generating padding bytes (b'\x00' * 64), creating cyclic patterns, and building exploit payloads where length matters precisely.The
python3 -cflag runs a single Python expression from the command line, making it ideal for quick payload generation. Combined with shell pipes (|) and netcat, you get a complete one-liner exploit. For more complex interactions, pwntools'remote()class handles the full connection lifecycle including reading responses and sending multiple payloads. - Step 2Send the payloadGenerate 1751
es and send. Note thes.recv(512)in the Python form is not optional, it consumes the prompt banner so the next read aligns. See netcat for CTF.pythonpython3 -c "print('e' * 1751)" | nc <HOST> <PORT_FROM_INSTANCE>bash# Interactive variant - recv(512) syncs with the banner before sending:pythonpython3 -c "import socket; s=socket.create_connection(('<HOST>', <PORT_FROM_INSTANCE>)); s.recv(512); s.sendall(b'e'*1751 + b'\n'); print(s.recv(512).decode())"Learn more
The two approaches shown - piping through nc vs. using Python's
socketmodule - differ in interactivity. The pipe approach is fire-and-forget: it sends the payload and displays whatever the server returns, but cannot respond to multiple prompts. The socket approach reads the banner first, then sends the payload, then reads the response - giving full control of the conversation.The socket module is Python's low-level network interface.
socket.create_connection()is a convenience wrapper that resolves the host, creates a TCP socket, and connects - equivalent tosocket.socket(AF_INET, SOCK_STREAM)followed by.connect(). For CTF use, pwntools'remote(host, port)is even more convenient and adds methods likerecvuntil(),sendline(), andinteractive().A subtle detail: the server reads input until a newline and then compares. Adding
b'\n'(or usingprint()which adds one automatically) is important - without it, the server may block forever waiting for the line terminator. This is a common gotcha when working with line-buffered servers.
Flag
picoCTF{byt3m4ncy_1_...}
app.py asks for ASCII decimal 101 × 1751, no spaces. Send the string 'e' repeated 1751 times.