## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # web site for more information on licensing and terms of use. # http://metasploit.com/ ## require 'msf/core' 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', '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'], 'License' => MSF_LICENSE ) register_options([Opt::RPORT(443), OptString.new('URI', [false, 'The uri path to test against' , '/sdk']) ], self.class) register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),]) end def run_host(ip) soap_data = %Q| <_this type="ServiceInstance">ServiceInstance | begin res = send_request_cgi({ 'uri' => normalize_uri(datastore['URI']), 'method' => 'POST', 'agent' => 'VMware VI Client', 'data' => soap_data, 'headers' => { 'SOAPAction' => @soap_action} }, 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?('VMware, Inc.') os_match = res.body.match(/([\w\s]+)<\/name>/) ver_match = res.body.match(/([\w\s\.]+)<\/version>/) build_match = res.body.match(/([\w\s\.\-]+)<\/build>/) full_match = res.body.match(/([\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