Hello there, over the Weekend we - Fr334aks-mini got a chance to play University of Toronto CTF and emerged at the 377th place.
UofTCTF 2025 was a jeopardy-style CTF that run from Sat, 11 Jan. 2025, 03:00 EAT — Mon, 13 Jan. 2025, 03:00 EAT. It was organized by the UofTCTF team, Dataflow security and Zellic, with classic categories like web, pwn, crypto, rev, forensics, and misc.
Let’s look at one of the challenges we solved: this was particularly in the “Miscellaneous” category.
Misc
Math Test
Looking at the given server, we are greeted with some easy math questions that I noticed I would spend the whole day solving.
Let’s find what we have in the zip. We are given a zip file that upon extracting we get this python file.
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
import random
from flag import FLAG
def genRandMath():
eqn = f'{random.randint(-1000, 1000)}'
eqn = f"{eqn} {random.choice(['+', '*', '-', '//'])} {random.randint(-1000, 1000)}"
while random.randint(0, 3) != 1:
eqn = f"{eqn} {random.choice(['+', '*', '-', '//'])} {random.randint(-1000, 1000)}"
try:
res = eval(eqn)
return eqn, res
except ZeroDivisionError:
return genRandMath()
print("Welcome to a simple math test.")
print("If you solve these basic math questions, I will give you the flag.")
print("Good Luck")
for i in range(1000):
eqn, correct = genRandMath()
print(f"Question: {eqn}")
res = int(input("Answer: "))
if res != correct:
print(f"Wrong!! Correct answer is {correct}")
exit()
print(f"Correct {i+1}/1000")
print(f"Congratz! Here is the flag {FLAG}")
Code analysis
The script presents an interesting math challenge where a user must correctly solve 1,000 randomly generated math problems to receive the flag (stored FLAG variable in another module).
- Key Features:
Each problem is randomly unique, making it difficult to predict or automate.
- The script provides instant feedback on whether the user’s answer is correct or not.
- Users must solve all 1,000 questions correctly without a single mistake to get a flag.
- The script provides instant feedback on whether the user’s answer is correct or not.
- The challenges:
There is a high likelihood of incorrectly solving over 1,000 questions with a single shot each.
- I couldn’t find a way to view the FLAG without answering all questions correctly.
Solution
The questions were easy but the only way to do it swiftly is auto-ing the process.
I made a script that read the questions, computed the answers, and send them back to the server.
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
# Author: D_C4ptain
import socket
def Mtest(ip, port):
# Connect to server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ip, port))
print(f"Connected to {ip}:{port}")
# Receive from server
while True:
data = s.recv(1024).decode()
if not data:
break
print(data)
# Check for question
if "Question:" in data:
# Extract math challenge
try:
question = data.split("Question:")[1].split("\n")[0].strip()
# Solve math
answer = eval(question)
except (ZeroDivisionError, IndexError, SyntaxError) as e:
print(f"Error processing question: {e}")
answer = 0
# Send the answer back
s.sendall(f"{answer}\n".encode())
elif "Congratz!" in data or "flag" in data:
# Print flag and exit
print(data)
break
Mtest("34.66.235.106", 5000)
Running this:
This took a few minutes but totally worth it.
1
uoftctf{7h15_15_b451c_10_7357_d16u153d_45_4_m47h_7357}
See you in another CTF!
And remember, there are many ways of killing Jerry!