# -*- coding: binary -*-

# Scans a Nagios XI target and suggests exploit modules to use
module Msf::Exploit::Remote::HTTP::NagiosXi::RceCheck
  # Uses the Nagios XI version to check which CVEs and related exploit modules the target is vulnerable to, if any
  #
  # @param version [Rex::Version] Nagios XI version
  # @return [Hash], Hash mapping CVE numbers to exploit module names if the target is vulnerable, empty hash otherwise
  def nagios_xi_rce_check(version)
    matching_exploits = {}

    # Storage area for known exploits that affect versions prior to the one in the hash key
    nagios_rce_version_prior = {
      '5.2.8' => [
        ['NO CVE AVAILABLE', 'nagios_xi_chained_rce']
      ]
    }

    nagios_rce_version_prior.each do |fixed_version, info|
      if version < Rex::Version.new(fixed_version)
        matching_exploits = add_cve_module_to_hash(matching_exploits, info)
      end
    end

    # Storage area for known exploits that affect only the version in the hash key
    nagios_rce_version_equals = {}

    unless nagios_rce_version_equals.empty?
      nagios_rce_version_equals.each do |fixed_version, info|
        if version == Rex::Version.new(fixed_version)
          matching_exploits = add_cve_module_to_hash(matching_exploits, info)
        end
      end
    end

    # Storage area for known exploits that affect version ranges (inclusive).
    # Each hash key should be two versions separated by a hyphen, eg `5.6.0-5.8.5`
    nagios_rce_version_range = {
      '5.2.0-5.5.6' => [
        ['CVE-2018-15708, CVE-2018-15710', 'nagios_xi_magpie_debug']
      ],
      '5.2.0-5.6.5' => [
        ['CVE-2019-15949', 'nagios_xi_plugins_check_plugin_authenticated_rce']
      ],
      '5.2.6-5.4.12' => [
        ['CVE-2018-8733, CVE-2018-8734, CVE-2018-8735, CVE-2018-8736', 'nagios_xi_chained_rce_2_electric_boogaloo']
      ],
      '5.3.0-5.7.9' => [
        ['CVE-2020-35578', 'nagios_xi_plugins_filename_authenticated_rce']
      ],
      '5.5.0-5.7.3' => [
        ['CVE-2020-5792', 'nagios_xi_snmptrap_authenticated_rce']
      ],
      '5.6.0-5.7.3' => [
        ['CVE-2020-5791', 'nagios_xi_mibs_authenticated_rce']
      ],
      '5.2.0-5.8.4' => [
        ['CVE-2021-37343', 'nagios_xi_autodiscovery_webshell']
      ]
    }

    nagios_rce_version_range.each do |fixed_version, info|
      lower, higher = fixed_version.split('-')
      lower = Rex::Version.new(lower)
      higher = Rex::Version.new(higher)
      if version >= lower && version <= higher
        matching_exploits = add_cve_module_to_hash(matching_exploits, info)
      end
    end

    matching_exploits
  end

  # Helper function that populates the matching_exploits hash with the contents
  # of cve_module_array by setting index 0 of each array as the key and index 1 as the value.
  #
  # @param matching_exploits [Hash] maps CVE numbers to exploit module names
  # @param cve_module_array [Array] contains arrays with a CVE number at index 0 and a matching exploit at index 1
  # @return [Hash] updated list of matching exploits, mapping CVE numbers to exploit module names
  def add_cve_module_to_hash(matching_exploits, cve_module_array)
    # Account for version numbers for which we have multiple exploits
    if cve_module_array.length > 1
      cve_module_array.each do |cma|
        cve, msf_module = cma
        matching_exploits[cve] = msf_module
      end
    else
      cve, msf_module = cve_module_array.flatten
      matching_exploits[cve] = msf_module
    end
    matching_exploits
  end
end
