Tools · CTF categories for beginners · 14 / 18
Scripting CTF interactions in Python: talking to netcat services and solving math prompts
Automate challenges that require answering many prompts quickly by connecting with Python sockets, reading lines, parsing questions, and sending answers, tested against your own local service.
Why script
Some challenges run a service you connect to with nc host port that asks hundreds of questions under a time limit, such as arithmetic or decoding tasks. Doing it by hand is impossible. A short script that reads a prompt, computes the answer, and sends it back is the expected solution.
Build a local practice service
Write your own small service so you can test without touching event infrastructure. This one asks 50 additions and prints a flag if all are correct within 10 seconds.
cat > server.py <<'EOF'
import socketserver, random, time
class H(socketserver.StreamRequestHandler):
def handle(self):
start = time.time()
for i in range(50):
a, b = random.randint(1, 9999), random.randint(1, 9999)
self.wfile.write(f'Q{i}: {a} + {b} = ?\n'.encode())
if self.rfile.readline().strip() != str(a + b).encode() or time.time() - start > 10:
self.wfile.write(b'wrong or too slow\n'); return
self.wfile.write(b'flag{scripted_practice}\n')
socketserver.TCPServer.allow_reuse_address = True
socketserver.TCPServer(('127.0.0.1', 9001), H).serve_forever()
EOF
python3 server.py &Lab: write the client
Connect with a socket, wrap it in a file object for line reading, parse each question with a regular expression, and send the answer. Run it against your local service and confirm you receive the flag. Then add a timeout and handle unexpected lines gracefully.
import re, socket
s = socket.create_connection(('127.0.0.1', 9001), timeout=5)
f = s.makefile('rwb', buffering=0)
while True:
line = f.readline().decode().strip()
if not line:
break
print(line)
m = re.search(r'(\d+) \+ (\d+)', line)
if m:
f.write(f'{int(m[1]) + int(m[2])}\n'.encode())
elif 'flag{' in line or 'wrong' in line:
breakLibraries
pwntools provides remote(), recvuntil(), and sendline() helpers that make these scripts shorter, and works against local processes too. Whichever you use, never evaluate server-provided text with eval, because a malicious service could send code; parse it explicitly instead.
Diagram
Scripted challenge loop
- Connect
socket.create_connection to host and port.
- Read
Read a line and print it for debugging.
- Parse and answer
Regex out the values; compute; send.
- Stop
Break on flag, error, or end of stream.
Check yourself
1. Where should you test a scripting solution first?
2. How should the client extract numbers from a prompt?
3. Why avoid eval on text received from a service?