freopen's Blog

Super Simple Calculations 题解

考点

  • socket 自动交互
  • 使用 eval() 计算表达式

0. 思路

服务端会连续给出 10 道加减法题,并要求在 10 秒内全部答对。手算肯定来不及,因此可以编写脚本循环接收题目,用 eval() 计算表达式,再把答案发送回去。

1. 题目交互

先使用 nc 连接服务端:

$ nc zjusec.com 30027
================================================
Mom: finish these 10 super simple calculations,
     and you will get a flag
Melody: that's easy...
Mom: yep, in 10 seconds
================================================

149202459 + 1345829534 + 1579159480 + 1778080752 =

每道题都以 = 结尾,因此可以持续接收数据,直到出现 = ,再取最后一行作为算式。计算完成后,在答案末尾加上换行并发回服务端,重复 10 次即可。

2. Exp

import socket

s = socket.socket()
s.connect(("zjusec.com", 30027))

for _ in range(10):
    data = b""

    # 每道题都以 "= " 结尾,没有收完整就继续接收
    while b"= " not in data:
        data += s.recv(1024)

    question = data.decode()
    print(question, end="")

    # 取最后一行,再去掉末尾的等号
    # "12 + 34 - 5 = " -> "12 + 34 - 5 "
    exp = question.split("\n")[-1].replace("= ", "")
    answer = eval(exp)  # 计算表达式

    print(answer)

    # 服务端按行读取答案,末尾要加换行
    s.sendall(f"{answer}\n".encode())

# 答完后继续接收,打印服务端返回的 flag
while True:
    data = s.recv(1024)
    if not data:
        break
    print(data.decode(), end="")

核心是这一行:

exp = question.split("\n")[-1].replace("= ", "")

服务端发来的 question 前面可能还有 Good, next: 等提示,算式在最后一行。split("\n") 先按换行切开,[-1] 取最后一行,再用 replace("= ", "") 去掉末尾的等号和空格,就得到了可以直接计算的表达式。

例如:

question = "Good, next:\n\n12 + 34 - 5 = "
exp = question.split("\n")[-1].replace("= ", "")

print(exp)        # 12 + 34 - 5
print(eval(exp))  # 41