
DreamHack - 거북이 Web Challenge Writeup
Room / Challenge: 거북이 (Web) Metadata Author: jameskaois CTF: DreamHack Challenge: 거북이 (web) Link: https://dreamhack.io/wargame/challenges/2194 Level: 2 Date: 25-11-2025 Goal Leveraging Zip Slip vulnerability and get the flag. My Solution The app is vulnerable to Zip Slip vulnerability, the vulnerable block of code in /upload: if (f.filename or "").lower().endswith(".zip") or "zip" in (f.content_type or "").lower(): data = f.read() zf = zipfile.ZipFile(io.BytesIO(data)) names = [] for info in zf.infolist(): target = UPLOAD_DIR / info.filename # <--- VULNERABLE CODE HERE if info.is_dir(): target.mkdir(parents=True, exist_ok=True) else: target.parent.mkdir(parents=True, exist_ok=True) with zf.open(info) as src, open(target, "wb") as dst: shutil.copyfileobj(src, dst) names.append(info.filename) return jsonify(ok=True, saved=names) The app doesn’t have any filetering or sanitizing so if we upload with a file with name ../templates/test.html, it will replace the test.html in templates folder with our file, then since this is a Flask app, we can use SSTI to get the flag content. ...

