Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/mssql/mssql_enum.rb
19715 views
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::OptionalSession::MSSQL
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Microsoft SQL Server Configuration Enumerator',
16
'Description' => %q{
17
This module will perform a series of configuration audits and
18
security checks against a Microsoft SQL Server database. For this
19
module to work, valid administrative user credentials must be
20
supplied.
21
},
22
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
23
'License' => MSF_LICENSE,
24
'Notes' => {
25
'Stability' => [CRASH_SAFE],
26
'SideEffects' => [IOC_IN_LOGS],
27
'Reliability' => []
28
}
29
)
30
)
31
end
32
33
# rubocop:disable Metrics/MethodLength
34
def run
35
print_status('Running MS SQL Server Enumeration...')
36
if session
37
set_mssql_session(session.client)
38
else
39
unless mssql_login_datastore
40
print_error('Login was unsuccessful. Check your credentials.')
41
disconnect
42
return
43
end
44
end
45
46
# Get Version
47
print_status('Version:')
48
ver = mssql_query('select @@version')
49
sqlversion = ver[:rows].join
50
sqlversion.each_line do |row|
51
print "[*]\t#{row}"
52
end
53
vernum = sqlversion.gsub("\n", ' ').scan(/SQL Server\s*(200\d)/m)
54
report_note(
55
host: mssql_client.peerhost,
56
proto: 'TCP',
57
port: mssql_client.peerport,
58
type: 'MSSQL_ENUM',
59
data: { version: sqlversion }
60
)
61
62
#---------------------------------------------------------
63
# Check Configuration Parameters and check what is enabled
64
print_status('Configuration Parameters:')
65
if vernum.join != '2000'
66
query = 'SELECT name, CAST(value_in_use AS INT) from sys.configurations'
67
ver = mssql_query(query)[:rows]
68
sysconfig = {}
69
ver.each do |l|
70
sysconfig[l[0].strip] = l[1].to_i
71
end
72
else
73
# enable advanced options
74
mssql_query("EXEC sp_configure \'show advanced options\', 1; RECONFIGURE")[:rows]
75
query = 'EXECUTE sp_configure'
76
ver = mssql_query(query)[:rows]
77
ver.class
78
sysconfig = {}
79
ver.each do |l|
80
sysconfig[l[0].strip] = l[3].to_i
81
end
82
end
83
84
#-------------------------------------------------------
85
# checking for C2 Audit Mode
86
if sysconfig['c2 audit mode'] == 1
87
print_status("\tC2 Audit Mode is Enabled")
88
report_note(
89
host: mssql_client.peerhost,
90
proto: 'TCP',
91
port: mssql_client.peerport,
92
type: 'MSSQL_ENUM',
93
data: { c2_audit_mode: 'Enabled' }
94
)
95
else
96
print_status("\tC2 Audit Mode is Not Enabled")
97
report_note(
98
host: mssql_client.peerhost,
99
proto: 'TCP',
100
port: mssql_client.peerport,
101
type: 'MSSQL_ENUM',
102
data: { c2_audit_mode: 'Disabled' }
103
)
104
end
105
106
#-------------------------------------------------------
107
# check if xp_cmdshell is enabled
108
if vernum.join != '2000'
109
if sysconfig['xp_cmdshell'] == 1
110
print_status("\txp_cmdshell is Enabled")
111
report_note(
112
host: mssql_client.peerhost,
113
proto: 'TCP',
114
port: mssql_client.peerport,
115
type: 'MSSQL_ENUM',
116
data: { xp_cmdshell: 'Enabled' }
117
)
118
else
119
print_status("\txp_cmdshell is Not Enabled")
120
report_note(
121
host: mssql_client.peerhost,
122
proto: 'TCP',
123
port: mssql_client.peerport,
124
type: 'MSSQL_ENUM',
125
data: { xp_cmdshell: 'Disabled' }
126
)
127
end
128
else
129
xpspexist = mssql_query("select sysobjects.name from sysobjects where name = \'xp_cmdshell\'")[:rows]
130
if !xpspexist.nil?
131
print_status("\txp_cmdshell is Enabled")
132
report_note(
133
host: mssql_client.peerhost,
134
proto: 'TCP',
135
port: mssql_client.peerport,
136
type: 'MSSQL_ENUM',
137
data: { xp_cmdshell: 'Enabled' }
138
)
139
else
140
print_status("\txp_cmdshell is Not Enabled")
141
report_note(
142
host: mssql_client.peerhost,
143
proto: 'TCP',
144
port: mssql_client.peerport,
145
type: 'MSSQL_ENUM',
146
data: { xp_cmdshell: 'Disabled' }
147
)
148
end
149
end
150
151
#-------------------------------------------------------
152
# check if remote access is enabled
153
if sysconfig['remote access'] == 1
154
print_status("\tremote access is Enabled")
155
else
156
print_status("\tremote access is Not Enabled")
157
end
158
report_note(
159
host: mssql_client.peerhost,
160
proto: 'TCP',
161
port: mssql_client.peerport,
162
type: 'MSSQL_ENUM',
163
data: { remote_access: 'Enabled' }
164
)
165
166
#-------------------------------------------------------
167
# check if updates are allowed
168
if sysconfig['allow updates'] == 1
169
print_status("\tallow updates is Enabled")
170
report_note(
171
host: mssql_client.peerhost,
172
proto: 'TCP',
173
port: mssql_client.peerport,
174
type: 'MSSQL_ENUM',
175
data: { allow_updates: 'Enabled' }
176
)
177
else
178
print_status("\tallow updates is Not Enabled")
179
report_note(
180
host: mssql_client.peerhost,
181
proto: 'TCP',
182
port: mssql_client.peerport,
183
type: 'MSSQL_ENUM',
184
data: { allow_updates: 'Disabled' }
185
)
186
end
187
188
#-------------------------------------------------------
189
# check if Mail stored procedures are enabled
190
if vernum.join != '2000'
191
if sysconfig['Database Mail XPs'] == 1
192
print_status("\tDatabase Mail XPs is Enabled")
193
report_note(
194
host: mssql_client.peerhost,
195
proto: 'TCP',
196
port: mssql_client.peerport,
197
type: 'MSSQL_ENUM',
198
data: { database_mail_xps: 'Enabled' }
199
)
200
else
201
print_status("\tDatabase Mail XPs is Not Enabled")
202
report_note(
203
host: mssql_client.peerhost,
204
proto: 'TCP',
205
port: mssql_client.peerport,
206
type: 'MSSQL_ENUM',
207
data: { database_mail_xps: 'Disabled' }
208
)
209
end
210
else
211
mailexist = mssql_query("select sysobjects.name from sysobjects where name like \'%mail%\'")[:rows]
212
if !mailexist.nil?
213
print_status("\tDatabase Mail XPs is Enabled")
214
report_note(
215
host: mssql_client.peerhost,
216
proto: 'TCP',
217
port: mssql_client.peerport,
218
type: 'MSSQL_ENUM',
219
data: { database_mail_xps: 'Enabled' }
220
)
221
else
222
print_status("\tDatabase Mail XPs is Not Enabled")
223
report_note(
224
host: mssql_client.peerhost,
225
proto: 'TCP',
226
port: mssql_client.peerport,
227
type: 'MSSQL_ENUM',
228
data: { database_mail_xps: 'Disabled' }
229
)
230
end
231
end
232
233
#-------------------------------------------------------
234
# check if OLE stored procedures are enabled
235
if vernum.join != '2000'
236
if sysconfig['Ole Automation Procedures'] == 1
237
print_status("\tOle Automation Procedures are Enabled")
238
report_note(
239
host: mssql_client.peerhost,
240
proto: 'TCP',
241
port: mssql_client.peerport,
242
type: 'MSSQL_ENUM',
243
data: { ole_automation_procedures: 'Enabled' }
244
)
245
else
246
print_status("\tOle Automation Procedures are Not Enabled")
247
report_note(
248
host: mssql_client.peerhost,
249
proto: 'TCP',
250
port: mssql_client.peerport,
251
type: 'MSSQL_ENUM',
252
data: { ole_automation_procedures: 'Disabled' }
253
)
254
end
255
else
256
oleexist = mssql_query("select sysobjects.name from sysobjects where name like \'%sp_OA%\'")[:rows]
257
if !oleexist.nil?
258
print_status("\tOle Automation Procedures is Enabled")
259
report_note(
260
host: mssql_client.peerhost,
261
proto: 'TCP',
262
port: mssql_client.peerport,
263
type: 'MSSQL_ENUM',
264
data: { ole_automation_procedures: 'Enabled' }
265
)
266
else
267
print_status("\tOle Automation Procedures are Not Enabled")
268
report_note(
269
host: mssql_client.peerhost,
270
proto: 'TCP',
271
port: mssql_client.peerport,
272
type: 'MSSQL_ENUM',
273
data: { ole_automation_procedures: 'Disabled' }
274
)
275
end
276
end
277
278
#-------------------------------------------------------
279
# Get list of Databases on System
280
print_status('Databases on the server:')
281
dbs = mssql_query('select name from master..sysdatabases')[:rows].flatten
282
if !dbs.nil?
283
dbs.each do |dbn|
284
print_status("\tDatabase name:#{dbn.strip}")
285
print_status("\tDatabase Files for #{dbn.strip}:")
286
if vernum.join != '2000'
287
db_ind_files = mssql_query("select filename from #{dbn.strip}.sys.sysfiles")[:rows]
288
if !db_ind_files.nil?
289
db_ind_files.each do |fn|
290
print_status("\t\t#{fn.join}")
291
report_note(
292
host: mssql_client.peerhost,
293
proto: 'TCP',
294
port: mssql_client.peerport,
295
type: 'MSSQL_ENUM',
296
data: {
297
database: dbn.strip, file: fn.join
298
}
299
)
300
end
301
end
302
else
303
db_ind_files = mssql_query("select filename from #{dbn.strip}..sysfiles")[:rows]
304
if !db_ind_files.nil?
305
db_ind_files.each do |fn|
306
print_status("\t\t#{fn.join.strip}")
307
report_note(
308
host: mssql_client.peerhost,
309
proto: 'TCP',
310
port: mssql_client.peerport,
311
type: 'MSSQL_ENUM',
312
data: {
313
database: dbn.strip,
314
file: fn.join
315
}
316
)
317
end
318
end
319
end
320
end
321
end
322
323
#-------------------------------------------------------
324
# Get list of syslogins on System
325
print_status('System Logins on this Server:')
326
if vernum.join != '2000'
327
syslogins = mssql_query('select loginname from master.sys.syslogins')[:rows]
328
else
329
syslogins = mssql_query('select loginname from master..syslogins')[:rows]
330
end
331
if !syslogins.nil?
332
syslogins.each do |acc|
333
print_status("\t#{acc.join}")
334
report_note(
335
host: mssql_client.peerhost,
336
proto: 'TCP',
337
port: mssql_client.peerport,
338
type: 'MSSQL_ENUM',
339
data: { database_master_user: acc.join }
340
)
341
end
342
else
343
print_error("\tCould not enumerate System Logins!")
344
report_note(
345
host: mssql_client.peerhost,
346
proto: 'TCP',
347
port: mssql_client.peerport,
348
type: 'MSSQL_ENUM',
349
data: { logons: 'Could not enumerate System Logins' }
350
)
351
end
352
353
#-------------------------------------------------------
354
# Get list of disabled accounts on System
355
if vernum.join != '2000'
356
print_status('Disabled Accounts:')
357
disabledsyslogins = mssql_query('select name from master.sys.server_principals where is_disabled = 1')[:rows]
358
if !disabledsyslogins.nil?
359
disabledsyslogins.each do |acc|
360
print_status("\t#{acc.join}")
361
report_note(
362
host: mssql_client.peerhost,
363
proto: 'TCP',
364
port: mssql_client.peerport,
365
type: 'MSSQL_ENUM',
366
data: { disabled_user: acc.join }
367
)
368
end
369
else
370
print_status("\tNo Disabled Logins Found")
371
report_note(
372
host: mssql_client.peerhost,
373
proto: 'TCP',
374
port: mssql_client.peerport,
375
type: 'MSSQL_ENUM',
376
data: { disabled_user: 'No Disabled Logins Found' }
377
)
378
end
379
end
380
381
#-------------------------------------------------------
382
# Get list of accounts for which password policy does not apply on System
383
if vernum.join != '2000'
384
print_status('No Accounts Policy is set for:')
385
nopolicysyslogins = mssql_query('select name from master.sys.sql_logins where is_policy_checked = 0')[:rows]
386
if !nopolicysyslogins.nil?
387
nopolicysyslogins.each do |acc|
388
print_status("\t#{acc.join}")
389
report_note(
390
host: mssql_client.peerhost,
391
proto: 'TCP',
392
port: mssql_client.peerport,
393
type: 'MSSQL_ENUM',
394
data: { none_policy_checked_user: acc.join }
395
)
396
end
397
else
398
print_status("\tAll System Accounts have the Windows Account Policy Applied to them.")
399
report_note(
400
host: mssql_client.peerhost,
401
proto: 'TCP',
402
port: mssql_client.peerport,
403
type: 'MSSQL_ENUM',
404
data: { none_policy_checked_user: 'All System Accounts have the Windows Account Policy Applied to them' }
405
)
406
end
407
end
408
409
#-------------------------------------------------------
410
# Get list of accounts for which password expiration is not checked
411
if vernum.join != '2000'
412
print_status('Password Expiration is not checked for:')
413
passexsyslogins = mssql_query('select name from master.sys.sql_logins where is_expiration_checked = 0')[:rows]
414
if !passexsyslogins.nil?
415
passexsyslogins.each do |acc|
416
print_status("\t#{acc.join}")
417
report_note(
418
host: mssql_client.peerhost,
419
proto: 'TCP',
420
port: mssql_client.peerport,
421
type: 'MSSQL_ENUM',
422
data: { none_password_expiration_user: acc.join }
423
)
424
end
425
else
426
print_status("\tAll System Accounts are checked for Password Expiration.")
427
report_note(
428
host: mssql_client.peerhost,
429
proto: 'TCP',
430
port: mssql_client.peerport,
431
type: 'MSSQL_ENUM',
432
data: { none_password_expiration_user: 'All System Accounts are checked for Password Expiration' }
433
)
434
end
435
end
436
437
#-------------------------------------------------------
438
# Get list of sysadmin logins on System
439
print_status('System Admin Logins on this Server:')
440
if vernum.join != '2000'
441
sysadmins = mssql_query('select name from master.sys.syslogins where sysadmin = 1')[:rows]
442
else
443
sysadmins = mssql_query('select name from master..syslogins where sysadmin = 1')[:rows]
444
end
445
if !sysadmins.nil?
446
sysadmins.each do |acc|
447
print_status("\t#{acc.join}")
448
report_note(
449
host: mssql_client.peerhost,
450
proto: 'TCP',
451
port: mssql_client.peerport,
452
type: 'MSSQL_ENUM',
453
data: { sysdba: acc.join }
454
)
455
end
456
else
457
print_error("\tCould not enumerate sysadmin accounts!")
458
report_note(
459
host: mssql_client.peerhost,
460
proto: 'TCP',
461
port: mssql_client.peerport,
462
type: 'MSSQL_ENUM',
463
data: { sysdba: 'Could not enumerate sysadmin accounts' }
464
)
465
end
466
467
#-------------------------------------------------------
468
# Get list of Windows logins on System
469
print_status('Windows Logins on this Server:')
470
if vernum.join != '2000'
471
winusers = mssql_query('select name from master.sys.syslogins where isntuser = 1')[:rows]
472
else
473
winusers = mssql_query('select name from master..syslogins where isntuser = 1')[:rows]
474
end
475
476
if !winusers.nil?
477
winusers.each do |acc|
478
print_status("\t#{acc.join}")
479
report_note(
480
host: mssql_client.peerhost,
481
proto: 'TCP',
482
port: mssql_client.peerport,
483
type: 'MSSQL_ENUM',
484
data: { windows_logins: acc.join }
485
)
486
end
487
else
488
print_status("\tNo Windows logins found!")
489
report_note(
490
host: mssql_client.peerhost,
491
proto: 'TCP',
492
port: mssql_client.peerport,
493
type: 'MSSQL_ENUM',
494
data: { windows_logins: 'No Windows logins found' }
495
)
496
end
497
498
#-------------------------------------------------------
499
# Get list of windows groups that can logins on the System
500
print_status('Windows Groups that can logins on this Server:')
501
if vernum.join != '2000'
502
wingroups = mssql_query('select name from master.sys.syslogins where isntgroup = 1')[:rows]
503
else
504
wingroups = mssql_query('select name from master..syslogins where isntgroup = 1')[:rows]
505
end
506
507
if !wingroups.nil?
508
wingroups.each do |acc|
509
print_status("\t#{acc.join}")
510
report_note(
511
host: mssql_client.peerhost,
512
proto: 'TCP',
513
port: mssql_client.peerport,
514
type: 'MSSQL_ENUM',
515
data: { windows_groups: acc.join }
516
)
517
end
518
else
519
print_status("\tNo Windows Groups where found with permission to login to system.")
520
report_note(
521
host: mssql_client.peerhost,
522
proto: 'TCP',
523
port: mssql_client.peerport,
524
type: 'MSSQL_ENUM',
525
data: { windows_groups: 'No Windows Groups where found with permission to login to system' }
526
)
527
528
end
529
530
#-------------------------------------------------------
531
# Check for local accounts with same username as password
532
sameasuser = []
533
if vernum.join != '2000'
534
sameasuser = mssql_query("SELECT name FROM sys.sql_logins WHERE PWDCOMPARE\(name, password_hash\) = 1")[:rows]
535
else
536
sameasuser = mssql_query("SELECT name FROM master.dbo.syslogins WHERE PWDCOMPARE\(name, password\) = 1")[:rows]
537
end
538
539
print_status('Accounts with Username and Password being the same:')
540
if !sameasuser.nil?
541
sameasuser.each do |up|
542
print_status("\t#{up.join}")
543
report_note(
544
host: mssql_client.peerhost,
545
proto: 'TCP',
546
port: mssql_client.peerport,
547
type: 'MSSQL_ENUM',
548
data: {
549
username: up.join,
550
password: up.join
551
}
552
)
553
end
554
else
555
print_status("\tNo Account with its password being the same as its username was found.")
556
report_note(
557
host: mssql_client.peerhost,
558
proto: 'TCP',
559
port: mssql_client.peerport,
560
type: 'MSSQL_ENUM',
561
data: { credentials: 'No Account with its password being the same as its username was found' }
562
)
563
end
564
565
#-------------------------------------------------------
566
# Check for local accounts with empty password
567
blankpass = []
568
if vernum.join != '2000'
569
blankpass = mssql_query("SELECT name FROM sys.sql_logins WHERE PWDCOMPARE\(\'\', password_hash\) = 1")[:rows]
570
else
571
blankpass = mssql_query('SELECT name FROM master.dbo.syslogins WHERE password IS NULL AND isntname = 0')[:rows]
572
end
573
574
print_status('Accounts with empty password:')
575
if !blankpass.nil?
576
blankpass.each do |up|
577
print_status("\t#{up.join}")
578
report_note(
579
host: mssql_client.peerhost,
580
proto: 'TCP',
581
port: mssql_client.peerport,
582
type: 'MSSQL_ENUM',
583
data: {
584
username: up.join,
585
password: 'EMPTY'
586
}
587
)
588
end
589
else
590
print_status("\tNo Accounts with empty passwords where found.")
591
report_note(
592
host: mssql_client.peerhost,
593
proto: 'TCP',
594
port: mssql_client.peerport,
595
type: 'MSSQL_ENUM',
596
data: { credentials: 'No Accounts with empty passwords where found' }
597
)
598
end
599
600
#-------------------------------------------------------
601
# Check for dangerous stored procedures
602
dangeroussp = [
603
'sp_createorphan',
604
'sp_droporphans',
605
'sp_execute_external_script',
606
'sp_getschemalock',
607
'sp_prepexec',
608
'sp_prepexecrpc',
609
'sp_refreshview',
610
'sp_releaseschemalock',
611
'sp_replpostschema',
612
'sp_replsendtoqueue',
613
'sp_replsetsyncstatus',
614
'sp_replwritetovarbin',
615
'sp_resyncexecute',
616
'sp_resyncexecutesql',
617
'sp_resyncprepare',
618
'sp_resyncuniquetable',
619
'sp_unprepare',
620
'sp_xml_preparedocument',
621
'sp_xml_removedocument',
622
'sp_fulltext_getdata',
623
'sp_getbindtoken',
624
'sp_replcmds',
625
'sp_replcounters',
626
'sp_repldone',
627
'sp_replflush',
628
'sp_replincrementlsn',
629
'sp_replpostcmd',
630
'sp_replsetoriginator',
631
'sp_replstatus',
632
'sp_repltrans',
633
'sp_replupdateschema',
634
'sp_reset_connection',
635
'sp_sdidebug',
636
'xp_availablemedia',
637
'xp_check_query_results',
638
'xp_cleanupwebtask',
639
'xp_cmdshell',
640
'xp_convertwebtask',
641
'xp_deletemail',
642
'xp_dirtree',
643
'xp_displayparamstmt',
644
'xp_dropwebtask',
645
'xp_dsninfo',
646
'xp_enum_activescriptengines',
647
'xp_enum_oledb_providers',
648
'xp_enumcodepages',
649
'xp_enumdsn',
650
'xp_enumerrorlogs',
651
'xp_enumgroups',
652
'xp_enumqueuedtasks',
653
'xp_eventlog',
654
'xp_execresultset',
655
'xp_fileexist',
656
'xp_findnextmsg',
657
'xp_fixeddrives',
658
'xp_get_mapi_default_profile',
659
'xp_get_mapi_profiles',
660
'xp_get_tape_devices',
661
'xp_getfiledetails',
662
'xp_getnetname',
663
'xp_grantlogin',
664
'xp_initcolvs',
665
'xp_intersectbitmaps',
666
'xp_logevent',
667
'xp_loginconfig',
668
'xp_logininfo',
669
'xp_makewebtask',
670
'xp_mergexpusage',
671
'xp_monitorsignal',
672
'xp_msver any user',
673
'xp_msx_enlist',
674
'xp_ntsec_enumdomains',
675
'xp_ntsec_enumgroups',
676
'xp_ntsec_enumusers',
677
'xp_oledbinfo',
678
'xp_perfend',
679
'xp_perfmonitor',
680
'xp_perfsample',
681
'xp_perfstart',
682
'xp_printstatements',
683
'xp_prop_oledb_provider',
684
'xp_proxiedmetadata',
685
'xp_qv',
686
'xp_readerrorlog',
687
'xp_readmail',
688
'xp_readwebtask',
689
'xp_regaddmultistring',
690
'xp_regdeletekey',
691
'xp_regdeletevalue',
692
'xp_regenumvalues',
693
'xp_regread',
694
'xp_regremovemultistring',
695
'xp_regwrite',
696
'xp_repl_encrypt',
697
'xp_revokelogin',
698
'xp_runwebtask',
699
'xp_schedulersignal',
700
'xp_sendmail',
701
'xp_servicecontrol',
702
'xp_showcolv',
703
'xp_showlineage',
704
'xp_snmp_getstate',
705
'xp_snmp_raisetrap',
706
'xp_sprintf any user', # huh?
707
'xp_sqlagent_enum_jobs',
708
'xp_sqlagent_is_starting',
709
'xp_sqlagent_monitor',
710
'xp_sqlagent_notify',
711
'xp_sqlinventory',
712
'xp_sqlmaint',
713
'xp_sqlregister',
714
'xp_sqltrace',
715
'xp_startmail',
716
'xp_stopmail',
717
'xp_subdirs',
718
'xp_terminate_process',
719
'xp_test_mapi_profile',
720
'xp_trace_addnewqueue',
721
'xp_trace_deletequeuedefinition',
722
'xp_trace_destroyqueue',
723
'xp_trace_enumqueuedefname',
724
'xp_trace_enumqueuehandles',
725
'xp_trace_eventclassrequired',
726
'xp_trace_flushqueryhistory',
727
'xp_trace_generate_event',
728
'xp_trace_getappfilter',
729
'xp_trace_getconnectionidfilter',
730
'xp_trace_getcpufilter',
731
'xp_trace_getdbidfilter',
732
'xp_trace_getdurationfilter',
733
'xp_trace_geteventfilter',
734
'xp_trace_geteventnames',
735
'xp_trace_getevents',
736
'xp_trace_gethostfilter',
737
'xp_trace_gethpidfilter',
738
'xp_trace_getindidfilter',
739
'xp_trace_getntdmfilter',
740
'xp_trace_getntnmfilter',
741
'xp_trace_getobjidfilter',
742
'xp_trace_getqueueautostart',
743
'xp_trace_getqueuecreateinfo',
744
'xp_trace_getqueuedestination',
745
'xp_trace_getqueueproperties',
746
'xp_trace_getreadfilter',
747
'xp_trace_getserverfilter',
748
'xp_trace_getseverityfilter',
749
'xp_trace_getspidfilter',
750
'xp_trace_getsysobjectsfilter',
751
'xp_trace_gettextfilter',
752
'xp_trace_getuserfilter',
753
'xp_trace_getwritefilter',
754
'xp_trace_loadqueuedefinition',
755
'xp_trace_opentracefile',
756
'xp_trace_pausequeue',
757
'xp_trace_restartqueue',
758
'xp_trace_savequeuedefinition',
759
'xp_trace_setappfilter',
760
'xp_trace_setconnectionidfilter',
761
'xp_trace_setcpufilter',
762
'xp_trace_setdbidfilter',
763
'xp_trace_setdurationfilter',
764
'xp_trace_seteventclassrequired',
765
'xp_trace_seteventfilter',
766
'xp_trace_sethostfilter',
767
'xp_trace_sethpidfilter',
768
'xp_trace_setindidfilter',
769
'xp_trace_setntdmfilter',
770
'xp_trace_setntnmfilter',
771
'xp_trace_setobjidfilter',
772
'xp_trace_setqueryhistory',
773
'xp_trace_setqueueautostart',
774
'xp_trace_setqueuecreateinfo',
775
'xp_trace_setqueuedestination',
776
'xp_trace_setreadfilter',
777
'xp_trace_setserverfilter',
778
'xp_trace_setseverityfilter',
779
'xp_trace_setspidfilter',
780
'xp_trace_setsysobjectsfilter',
781
'xp_trace_settextfilter',
782
'xp_trace_setuserfilter',
783
'xp_trace_setwritefilter',
784
'xp_trace_startconsumer',
785
'xp_unc_to_drive',
786
'xp_updatecolvbm',
787
'xp_updateFTSSQLAccount',
788
'xp_updatelineage',
789
'xp_varbintohexstr',
790
'xp_writesqlinfo',
791
'xp_MSplatform',
792
'xp_MSnt2000',
793
'xp_MSLocalSystem',
794
'xp_IsNTAdmin',
795
'xp_mapdown_bitmap'
796
]
797
798
query = <<~EOS
799
SELECT CAST(SYSOBJECTS.NAME AS CHAR) FROM SYSOBJECTS, SYSPROTECTS WHERE SYSPROTECTS.UID = 0 AND XTYPE IN ('X','P')
800
AND SYSOBJECTS.ID = SYSPROTECTS.ID
801
EOS
802
fountsp = mssql_query(query)[:rows]
803
if !fountsp.nil?
804
fountsp.flatten!
805
print_status('Stored Procedures with Public Execute Permission found:')
806
fountsp.each do |strp|
807
next unless dangeroussp.include?(strp.strip)
808
809
print_status("\t#{strp.strip}")
810
report_note(
811
host: mssql_client.peerhost,
812
proto: 'TCP',
813
port: mssql_client.peerport,
814
type: 'MSSQL_ENUM',
815
data: { stored_procedures_with_public_execute_permission: strp.strip }
816
)
817
end
818
else
819
print_status("\tNo Dangerous Stored Procedure found with Public Execute.")
820
report_note(
821
host: mssql_client.peerhost,
822
proto: 'TCP',
823
port: mssql_client.peerport,
824
type: 'MSSQL_ENUM',
825
data: { stored_procedures_with_public_execute_permission: 'No Dangerous Stored Procedure found with Public Execute' }
826
)
827
end
828
829
#-------------------------------------------------------
830
# Enumerate Instances
831
instances = []
832
if vernum.join != '2000'
833
querykey = "EXEC master..xp_regenumvalues \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL\'"
834
instance_res = mssql_query(querykey)[:rows]
835
if !instance_res.nil?
836
instance_res.each do |i|
837
instances << i[0]
838
end
839
end
840
else
841
querykey = "exec xp_regread \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\', \'InstalledInstances\'"
842
instance_res = mssql_query(querykey)[:rows]
843
if !instance_res.nil?
844
instance_res.each do |i|
845
instances << i[1]
846
end
847
end
848
end
849
850
print_status('Instances found on this server:')
851
instancenames = []
852
if !instances.nil?
853
instances.each do |i|
854
print_status("\t#{i}")
855
instancenames << i.strip
856
report_note(
857
host: mssql_client.peerhost,
858
proto: 'TCP',
859
port: mssql_client.peerport,
860
type: 'MSSQL_ENUM',
861
data: { instance_name: i }
862
)
863
end
864
else
865
print_status('No instances found, possible permission problem')
866
end
867
868
#---------------------------------------------------------
869
# Enumerate under what accounts the instance services are running under
870
print_status('Default Server Instance SQL Server Service is running under the privilege of:')
871
privdflt = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQLSERVER\',\'ObjectName\'")[:rows]
872
if !privdflt.nil?
873
privdflt.each do |priv|
874
print_status("\t#{priv[1]}")
875
report_note(
876
host: mssql_client.peerhost,
877
proto: 'TCP',
878
port: mssql_client.peerport,
879
type: 'MSSQL_ENUM',
880
data: { default_instance_sql_server: priv[1] }
881
)
882
end
883
else
884
print_status("\txp_regread might be disabled in this system")
885
end
886
887
#------------------------------------------------------------
888
if instancenames.length > 1
889
instancenames.each do |i|
890
next unless i.strip != 'MSSQLSERVER'
891
892
privinst = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQL$#{i.strip}\',\'ObjectName\'")[:rows]
893
if !privinst.nil?
894
print_status("Instance #{i} SQL Server Service is running under the privilege of:")
895
privinst.each do |p|
896
print_status("\t#{p[1]}")
897
report_note(
898
host: mssql_client.peerhost,
899
proto: 'TCP',
900
port: mssql_client.peerport,
901
type: 'MSSQL_ENUM',
902
data: {
903
instance_sql_server: i,
904
port: p[1]
905
}
906
)
907
end
908
else
909
print_status("\tCould not enumerate credentials for Instance.")
910
end
911
end
912
end
913
914
disconnect
915
end
916
# rubocop:enable Metrics/MethodLength
917
end
918
919