Skip to content

Commit 2ac1ae6

Browse files
committed
modules/auxiliary/admin/mssql: Resolve RuboCop violations
1 parent f722f39 commit 2ac1ae6

15 files changed

+970
-875
lines changed

modules/auxiliary/admin/mssql/mssql_enum.rb

Lines changed: 328 additions & 320 deletions
Large diffs are not rendered by default.

modules/auxiliary/admin/mssql/mssql_enum_domain_accounts.rb

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,50 @@ class MetasploitModule < Msf::Auxiliary
88
include Msf::Auxiliary::Report
99

1010
def initialize(info = {})
11-
super(update_info(info,
12-
'Name' => 'Microsoft SQL Server SUSER_SNAME Windows Domain Account Enumeration',
13-
'Description' => %q{
14-
This module can be used to bruteforce RIDs associated with the domain of the SQL Server
15-
using the SUSER_SNAME function. This is similar to the smb_lookupsid module, but executed
16-
through SQL Server queries as any user with the PUBLIC role (everyone). Information that
17-
can be enumerated includes Windows domain users, groups, and computer accounts. Enumerated
18-
accounts can then be used in online dictionary attacks.
19-
},
20-
'Author' =>
21-
[
11+
super(
12+
update_info(
13+
info,
14+
'Name' => 'Microsoft SQL Server SUSER_SNAME Windows Domain Account Enumeration',
15+
'Description' => %q{
16+
This module can be used to bruteforce RIDs associated with the domain of the SQL Server
17+
using the SUSER_SNAME function. This is similar to the smb_lookupsid module, but executed
18+
through SQL Server queries as any user with the PUBLIC role (everyone). Information that
19+
can be enumerated includes Windows domain users, groups, and computer accounts. Enumerated
20+
accounts can then be used in online dictionary attacks.
21+
},
22+
'Author' => [
2223
'nullbind <scott.sutherland[at]netspi.com>',
2324
'antti <antti.rantasaari[at]netspi.com>'
2425
],
25-
'License' => MSF_LICENSE,
26-
'References' => [[ 'URL','https://docs.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql']]
27-
))
26+
'License' => MSF_LICENSE,
27+
'References' => [[ 'URL', 'https://docs.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql']],
28+
'Notes' => {
29+
'Stability' => [CRASH_SAFE],
30+
'SideEffects' => [IOC_IN_LOGS],
31+
'Reliability' => []
32+
}
33+
)
34+
)
2835

2936
register_options(
3037
[
31-
OptInt.new('FuzzNum', [true, 'Number of principal_ids to fuzz.', 10000]),
32-
])
38+
OptInt.new('FuzzNum', [true, 'Number of principal_ids to fuzz.', 10_000]),
39+
]
40+
)
3341
end
3442

3543
def run
3644
# Check connection and issue initial query
3745
print_status("Attempting to connect to the database server at #{rhost}:#{rport} as #{datastore['USERNAME']}...")
38-
if mssql_login_datastore
39-
print_good('Connected.')
40-
else
46+
47+
unless mssql_login_datastore
4148
print_error('Login was unsuccessful. Check your credentials.')
4249
disconnect
4350
return
4451
end
4552

53+
print_good('Connected.')
54+
4655
# Get the server name
4756
sql_server_name = get_sql_server_name
4857
print_status("SQL Server Name: #{sql_server_name}")
@@ -53,13 +62,13 @@ def run
5362
print_error("Could not recover the SQL Server's domain.")
5463
disconnect
5564
return
56-
else
57-
print_status("Domain Name: #{sql_server_domain}")
5865
end
5966

67+
print_status("Domain Name: #{sql_server_domain}")
68+
6069
# Check if the domain and hostname are the same
6170
if sql_server_name == sql_server_domain
62-
print_error("The SQL Server does not appear to be part of a Windows domain.")
71+
print_error('The SQL Server does not appear to be part of a Windows domain.')
6372
disconnect
6473
return
6574
end
@@ -70,10 +79,10 @@ def run
7079
print_error("Could not recover the SQL Server's domain sid.")
7180
disconnect
7281
return
73-
else
74-
print_good("Found the domain sid: #{windows_domain_sid}")
7582
end
7683

84+
print_good("Found the domain sid: #{windows_domain_sid}")
85+
7786
# Get a list of windows users, groups, and computer accounts using SUSER_NAME()
7887
print_status("Brute forcing #{datastore['FuzzNum']} RIDs through the SQL Server, be patient...")
7988
win_domain_user_list = get_win_domain_users(windows_domain_sid)
@@ -94,8 +103,8 @@ def run
94103

95104
# Create table for report
96105
windows_domain_login_table = Rex::Text::Table.new(
97-
'Header' => 'Windows Domain Accounts',
98-
'Ident' => 1,
106+
'Header' => 'Windows Domain Accounts',
107+
'Ident' => 1,
99108
'Columns' => ['name']
100109
)
101110

@@ -106,10 +115,10 @@ def run
106115

107116
# Create output file
108117
this_service = report_service(
109-
:host => mssql_client.peerhost,
110-
:port => mssql_client.peerport,
111-
:name => 'mssql',
112-
:proto => 'tcp'
118+
host: mssql_client.peerhost,
119+
port: mssql_client.peerport,
120+
name: 'mssql',
121+
proto: 'tcp'
113122
)
114123
file_name = "#{mssql_client.peerhost}-#{mssql_client.peerport}_windows_domain_accounts.csv"
115124
path = store_loot(
@@ -119,23 +128,22 @@ def run
119128
windows_domain_login_table.to_csv,
120129
file_name,
121130
'Domain Users enumerated through SQL Server',
122-
this_service)
131+
this_service
132+
)
123133
print_status("Query results have been saved to: #{path}")
124134
end
125135

126136
# Get list of windows accounts,groups,and computer accounts
127137
def get_win_domain_users(windows_domain_sid)
128-
129138
# Create array to store the windws accounts etc
130139
windows_logins = []
131140

132141
# Fuzz the principal_id parameter passed to the SUSER_NAME function
133142
(500..datastore['FuzzNum']).each do |principal_id|
134-
135143
# Convert number to hex and fix order
136-
principal_id_hex = "%02X" % principal_id
137-
principal_id_hex_pad = (principal_id_hex.size.even? ? principal_id_hex : ("0"+ principal_id_hex))
138-
principal_id_clean = principal_id_hex_pad.scan(/(..)/).reverse.flatten.join
144+
principal_id_hex = '%02X' % principal_id
145+
principal_id_hex_pad = (principal_id_hex.size.even? ? principal_id_hex : ('0' + principal_id_hex))
146+
principal_id_clean = principal_id_hex_pad.scan(/(..)/).reverse.flatten.join
139147

140148
# Add padding
141149
principal_id_hex_padded2 = principal_id_clean.ljust(8, '0')
@@ -159,7 +167,7 @@ def get_win_domain_users(windows_domain_sid)
159167
windows_login = parse_results[0][0]
160168

161169
# Print account,group,or computer account etc
162-
if windows_login.length != 0
170+
if !windows_login.empty?
163171
print_status(" - #{windows_login}")
164172

165173
vprint_status("Test sid: #{win_sid}")
@@ -175,9 +183,8 @@ def get_win_domain_users(windows_domain_sid)
175183

176184
# Get windows domain
177185
def get_windows_domain
178-
179186
# Setup query to check the domain
180-
sql = "SELECT DEFAULT_DOMAIN() as mydomain"
187+
sql = 'SELECT DEFAULT_DOMAIN() as mydomain'
181188

182189
# Run query
183190
result = mssql_query(sql)
@@ -192,9 +199,8 @@ def get_windows_domain
192199

193200
# Get the sql server's hostname
194201
def get_sql_server_name
195-
196202
# Setup query to check the server name
197-
sql = "SELECT @@servername"
203+
sql = 'SELECT @@servername'
198204

199205
# Run query
200206
result = mssql_query(sql)
@@ -210,7 +216,6 @@ def get_sql_server_name
210216

211217
# Get windows domain
212218
def get_windows_domain_sid(sql_server_domain)
213-
214219
# Set group
215220
domain_group = "#{sql_server_domain}\\Domain Admins"
216221

@@ -226,7 +231,7 @@ def get_windows_domain_sid(sql_server_domain)
226231
domain_sid = object_sid[0..47]
227232

228233
# Return if sid does not resolve for a domain
229-
if domain_sid.length == 0
234+
if domain_sid.empty?
230235
return nil
231236
end
232237

0 commit comments

Comments
 (0)