247CTF - My Magic Bytes

Socket challenge requiring automation to solve 500 arithmetic problems programmatically. Use Python with pwntools to interface with the remote service and automate the solution.

Key Considerations

  • Library: pwntools for socket communication
  • Custom delimiter: Uses \r\n instead of standard \n
  • Approach: Parse math expressions dynamically and compute answers

The calculator accepts only a two-integer expression and a whitelisted operator; unsupported syntax stops the run. Division is exact before truncation toward zero. The offline checks cover calculation, rejection of code-like input and CRLF configuration; the 500-round remote protocol has not been rerun.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env python3
import operator
import re
from fractions import Fraction
import pwn

HOST = "7a3875d00fa5d462.247ctf.com"
PORT = 50337
pwn.context.log_level = "info"

OPERATORS = {
"+": operator.add, "-": operator.sub, "*": operator.mul,
"/": operator.truediv, "//": operator.floordiv, "%": operator.mod,
}

def calculate(expression):
# 仅接受两个有符号整数和白名单运算符,拒绝代码与超长输入
if len(expression) > 128:
raise ValueError("Expression too long")
match = re.fullmatch(r"\s*([+-]?\d{1,20})\s*(//|[+*/%-])\s*([+-]?\d{1,20})\s*", expression)
if not match:
raise ValueError("Unsupported expression")
left, op, right = match.groups()
result = OPERATORS[op](Fraction(int(left)), Fraction(int(right)))
return int(result)

def solve_challenge():
conn = None
try:
conn = pwn.remote(HOST, PORT, timeout=10)
conn.newline = b"\r\n"
for i in range(500):
conn.recvuntil(b"answer to ")
expression = conn.recvline().decode("ascii").strip().removesuffix("?").strip()
result = calculate(expression)
conn.sendline(str(result).encode("ascii"))
pwn.log.info(f"Progress: [{i + 1}/500] Solved: {expression} = {result}")
conn.interactive()
except (ValueError, ZeroDivisionError, EOFError, OSError) as exc:
pwn.log.warning(f"Challenge stopped: {exc}")
finally:
if conn is not None:
conn.close()

if __name__ == "__main__":
solve_challenge()

Execution Output

The retained terminal excerpt shows the final two rounds only; it is not a new verification run.

1
2
3
4
5
6
7
❯ python tcp_auto.py
[+] Opening connection to 7a3875d00fa5d462.247ctf.com on port 50337: Done
[*] Progress: [499/500] Solved: 221 + 474 = 695
[*] Progress: [500/500] Solved: 4 + 449 = 453
[+] 500 problems solved! Waiting for flag...
[*] Switching to interactive mode
247CTF{<flag-redacted>}