Statistics
| Branch: | Tag: | Revision:

root / modules / auxiliary / admin / mssql / mssql_enum.rb @ master

History | View | Annotate | Download (25.4 kB)

1
##
2
# $Id$
3
##
4

    
5
##
6
# This file is part of the Metasploit Framework and may be subject to
7
# redistribution and commercial restrictions. Please see the Metasploit
8
# Framework web site for more information on licensing and terms of use.
9
# http://metasploit.com/framework/
10
##
11

    
12
require 'msf/core'
13

    
14
class Metasploit3 < Msf::Auxiliary
15

    
16
        include Msf::Exploit::Remote::MSSQL
17
        include Msf::Auxiliary::Report
18

    
19
        def initialize(info = {})
20
                super(update_info(info,
21
                        'Name'           => 'Microsoft SQL Server Configuration Enumerator',
22
                        'Description'    => %q{
23
                                        This module will perform a series of configuration audits and
24
                                security checks against a Microsoft SQL Server database. For this
25
                                module to work, valid administrative user credentials must be
26
                                supplied.
27
                        },
28
                        'Author'         => [ 'Carlos Perez <carlos_perez [at] darkoperator.com>' ],
29
                        'License'        => MSF_LICENSE,
30
                        'Version'        => '$Revision$'
31
                ))
32
        end
33

    
34
        def run
35
                print_status("Running MS SQL Server Enumeration...")
36

    
37
                if mssql_login_datastore == false
38
                        print_error("Login was unsuccessful. Check your credentials.")
39
                        disconnect
40
                        return
41
                end
42

    
43
                # Get Version
44
                print_status("Version:")
45
                vernum =""
46
                ver = mssql_query("select @@version")
47
                sqlversion = ver[:rows].join
48
                sqlversion.each_line do |row|
49
                        print "[*]\t#{row}"
50
                end
51
                vernum = sqlversion.gsub("\n"," ").scan(/SQL Server\s*(200\d)/m)
52
                report_note(:host => datastore['RHOST'],
53
                        :proto => 'TCP',
54
                        :port => datastore['RPORT'],
55
                        :type => 'MSSQL_ENUM',
56
                        :data => "Version: #{sqlversion}")
57

    
58
                #-------------------------------------------------------
59
                #Check Configuration Parameters and check what is enabled
60
                print_status("Configuration Parameters:")
61
                if vernum.join != "2000"
62
                        query = "SELECT name, CAST(value_in_use AS INT) from sys.configurations"
63
                        ver = mssql_query(query)[:rows]
64
                        sysconfig = {}
65
                        ver.each do |l|
66
                                sysconfig[l[0].strip] = l[1].to_i
67
                        end
68
                else
69
                        #enable advanced options
70
                        mssql_query("EXEC sp_configure \'show advanced options\', 1; RECONFIGURE")[:rows]
71
                        query = "EXECUTE sp_configure"
72
                        ver = mssql_query(query)[:rows]
73
                        ver.class
74
                        sysconfig = {}
75
                        ver.each do |l|
76
                                sysconfig[l[0].strip] = l[3].to_i
77
                        end
78
                end
79

    
80
                #-------------------------------------------------------
81
                #checking for C2 Audit Mode
82
                if sysconfig['c2 audit mode'] == 1
83
                        print_status("\tC2 Audit Mode is Enabled")
84
                        report_note(:host => datastore['RHOST'],
85
                                :proto => 'TCP',
86
                                :port => datastore['RPORT'],
87
                                :type => 'MSSQL_ENUM',
88
                                :data => "C2 Audit Mode is Enabled")
89
                else
90
                        print_status("\tC2 Audit Mode is Not Enabled")
91
                        report_note(:host => datastore['RHOST'],
92
                                :proto => 'TCP',
93
                                :port => datastore['RPORT'],
94
                                :type => 'MSSQL_ENUM',
95
                                :data => "C2 Audit Mode is Not Enabled")
96
                end
97

    
98
                #-------------------------------------------------------
99
                #check if xp_cmdshell is enabled
100
                if vernum.join != "2000"
101
                        if sysconfig['xp_cmdshell'] == 1
102
                                print_status("\txp_cmdshell is Enabled")
103
                                report_note(:host => datastore['RHOST'],
104
                                        :proto => 'TCP',
105
                                        :port => datastore['RPORT'],
106
                                        :type => 'MSSQL_ENUM',
107
                                        :data => "xp_cmdshell is Enabled")
108
                        else
109
                                print_status("\txp_cmdshell is Not Enabled")
110
                                report_note(:host => datastore['RHOST'],
111
                                        :proto => 'TCP',
112
                                        :port => datastore['RPORT'],
113
                                        :type => 'MSSQL_ENUM',
114
                                        :data => "xp_cmdshell is Not Enabled")
115
                        end
116
                else
117
                        xpspexist = mssql_query("select sysobjects.name from sysobjects where name = \'xp_cmdshell\'")[:rows]
118
                        if xpspexist != nil
119
                                print_status("\txp_cmdshell is Enabled")
120
                                report_note(:host => datastore['RHOST'],
121
                                        :proto => 'TCP',
122
                                        :port => datastore['RPORT'],
123
                                        :type => 'MSSQL_ENUM',
124
                                        :data => "xp_cmdshell is Enabled")
125
                        else
126
                                print_status("\txp_cmdshell is Not Enabled")
127
                                report_note(:host => datastore['RHOST'],
128
                                        :proto => 'TCP',
129
                                        :port => datastore['RPORT'],
130
                                        :type => 'MSSQL_ENUM',
131
                                        :data => "xp_cmdshell is Not Enabled")
132
                        end
133
                end
134

    
135
                #-------------------------------------------------------
136
                #check if remote access is enabled
137
                if sysconfig['remote access'] == 1
138
                        print_status("\tremote access is Enabled")
139
                        report_note(:host => datastore['RHOST'],
140
                                :proto => 'TCP',
141
                                :port => datastore['RPORT'],
142
                                :type => 'MSSQL_ENUM',
143
                                :data => "remote access is Enabled")
144
                else
145
                        print_status("\tremote access is Not Enabled")
146
                        report_note(:host => datastore['RHOST'],
147
                                :proto => 'TCP',
148
                                :port => datastore['RPORT'],
149
                                :type => 'MSSQL_ENUM',
150
                                :data => "remote access is not Enabled")
151
                end
152

    
153
                #-------------------------------------------------------
154
                #check if updates are allowed
155
                if sysconfig['allow updates'] == 1
156
                        print_status("\tallow updates is Enabled")
157
                        report_note(:host => datastore['RHOST'],
158
                                :proto => 'TCP',
159
                                :port => datastore['RPORT'],
160
                                :type => 'MSSQL_ENUM',
161
                                :data => "allow updates is Enabled")
162
                else
163
                        print_status("\tallow updates is Not Enabled")
164
                        report_note(:host => datastore['RHOST'],
165
                                :proto => 'TCP',
166
                                :port => datastore['RPORT'],
167
                                :type => 'MSSQL_ENUM',
168
                                :data => "allow updates is not Enabled")
169
                end
170

    
171
                #-------------------------------------------------------
172
                #check if Mail stored procedures are enabled
173
                if vernum.join != "2000"
174
                        if sysconfig['Database Mail XPs'] == 1
175
                                print_status("\tDatabase Mail XPs is Enabled")
176
                                report_note(:host => datastore['RHOST'],
177
                                        :proto => 'TCP',
178
                                        :port => datastore['RPORT'],
179
                                        :type => 'MSSQL_ENUM',
180
                                        :data => "Database Mail XPs is Enabled")
181
                        else
182
                                print_status("\tDatabase Mail XPs is Not Enabled")
183
                                report_note(:host => datastore['RHOST'],
184
                                        :proto => 'TCP',
185
                                        :port => datastore['RPORT'],
186
                                        :type => 'MSSQL_ENUM',
187
                                        :data => "Database Mail XPs is not Enabled")
188
                        end
189
                else
190
                        mailexist = mssql_query("select sysobjects.name from sysobjects where name like \'%mail%\'")[:rows]
191
                        if mailexist != nil
192
                                print_status("\tDatabase Mail XPs is Enabled")
193
                                report_note(:host => datastore['RHOST'],
194
                                        :proto => 'TCP',
195
                                        :port => datastore['RPORT'],
196
                                        :type => 'MSSQL_ENUM',
197
                                        :data => "Database Mail XPs is Enabled")
198
                        else
199
                                print_status("\tDatabase Mail XPs is Not Enabled")
200
                                report_note(:host => datastore['RHOST'],
201
                                        :proto => 'TCP',
202
                                        :port => datastore['RPORT'],
203
                                        :type => 'MSSQL_ENUM',
204
                                        :data => "Database Mail XPs is not Enabled")
205
                        end
206
                end
207

    
208
                #-------------------------------------------------------
209
                #check if OLE stored procedures are enabled
210
                if vernum.join != "2000"
211
                        if sysconfig['Ole Automation Procedures'] == 1
212
                                print_status("\tOle Automation Procedures are Enabled")
213
                                report_note(:host => datastore['RHOST'],
214
                                        :proto => 'TCP',
215
                                        :port => datastore['RPORT'],
216
                                        :type => 'MSSQL_ENUM',
217
                                        :data => "Ole Automation Procedures are Enabled")
218
                        else
219
                                print_status("\tOle Automation Procedures are Not Enabled")
220
                                report_note(:host => datastore['RHOST'],
221
                                        :proto => 'TCP',
222
                                        :port => datastore['RPORT'],
223
                                        :type => 'MSSQL_ENUM',
224
                                        :data => "Ole Automation Procedures are not Enabled")
225
                        end
226
                else
227
                        oleexist = mssql_query("select sysobjects.name from sysobjects where name like \'%sp_OA%\'")[:rows]
228
                        if oleexist != nil
229
                                print_status("\tOle Automation Procedures is Enabled")
230
                                report_note(:host => datastore['RHOST'],
231
                                        :proto => 'TCP',
232
                                        :port => datastore['RPORT'],
233
                                        :type => 'MSSQL_ENUM',
234
                                        :data => "Ole Automation Procedures are Enabled")
235
                        else
236
                                print_status("\tOle Automation Procedures are Not Enabled")
237
                                report_note(:host => datastore['RHOST'],
238
                                        :proto => 'TCP',
239
                                        :port => datastore['RPORT'],
240
                                        :type => 'MSSQL_ENUM',
241
                                        :data => "Ole Automation Procedures are not Enabled")
242
                        end
243
                end
244

    
245
                #-------------------------------------------------------
246
                # Get list of Databases on System
247
                print_status("Databases on the server:")
248
                dbs = mssql_query("select name from master..sysdatabases")[:rows].flatten
249
                if dbs != nil
250
                        dbs.each do |dbn|
251
                                print_status("\tDatabase name:#{dbn.strip}")
252
                                print_status("\tDatabase Files for #{dbn.strip}:")
253
                                if vernum.join != "2000"
254
                                        db_ind_files = mssql_query("select filename from #{dbn.strip}.sys.sysfiles")[:rows]
255
                                        if db_ind_files != nil
256
                                                db_ind_files.each do |fn|
257
                                                        print_status("\t\t#{fn.join}")
258
                                                        report_note(:host => datastore['RHOST'],
259
                                                                :proto => 'TCP',
260
                                                                :port => datastore['RPORT'],
261
                                                                :type => 'MSSQL_ENUM',
262
                                                                :data => "Database: #{dbn.strip} File: #{fn.join}")
263
                                                end
264
                                        end
265
                                else
266
                                        db_ind_files = mssql_query("select filename from #{dbn.strip}..sysfiles")[:rows]
267
                                        if db_ind_files != nil
268
                                                db_ind_files.each do |fn|
269
                                                        print_status("\t\t#{fn.join.strip}")
270
                                                        report_note(:host => datastore['RHOST'],
271
                                                                :proto => 'TCP',
272
                                                                :port => datastore['RPORT'],
273
                                                                :type => 'MSSQL_ENUM',
274
                                                                :data => "Database: #{dbn.strip} File: #{fn.join}")
275
                                                end
276
                                        end
277
                                end
278
                        end
279
                end
280

    
281
                #-------------------------------------------------------
282
                # Get list of syslogins on System
283
                print_status("System Logins on this Server:")
284
                if vernum.join != "2000"
285
                        syslogins = mssql_query("select loginname from master.sys.syslogins")[:rows]
286
                else
287
                        syslogins = mssql_query("select loginname from master..syslogins")[:rows]
288
                end
289
                if syslogins != nil
290
                        syslogins.each do |acc|
291
                                print_status("\t#{acc.join}")
292
                                report_note(:host => datastore['RHOST'],
293
                                        :proto => 'TCP',
294
                                        :port => datastore['RPORT'],
295
                                        :type => 'MSSQL_ENUM',
296
                                        :data => "Database: Master User: #{acc.join}")
297
                        end
298
                else
299
                        print_error("\tCould not enumerate System Logins!")
300
                        report_note(:host => datastore['RHOST'],
301
                                :proto => 'TCP',
302
                                :port => datastore['RPORT'],
303
                                :type => 'MSSQL_ENUM',
304
                                :data => "Could not enumerate System Logins")
305
                end
306

    
307
                #-------------------------------------------------------
308
                # Get list of disabled accounts on System
309
                if vernum.join != "2000"
310
                        print_status("Disabled Accounts:")
311
                        disabledsyslogins = mssql_query("select name from master.sys.server_principals where is_disabled = 1")[:rows]
312
                        if disabledsyslogins != nil
313
                                disabledsyslogins.each do |acc|
314
                                        print_status("\t#{acc.join}")
315
                                        report_note(:host => datastore['RHOST'],
316
                                                :proto => 'TCP',
317
                                                :port => datastore['RPORT'],
318
                                                :type => 'MSSQL_ENUM',
319
                                                :data => "Disabled User: #{acc.join}")
320
                                end
321
                        else
322
                                print_status("\tNo Disabled Logins Found")
323
                                report_note(:host => datastore['RHOST'],
324
                                        :proto => 'TCP',
325
                                        :port => datastore['RPORT'],
326
                                        :type => 'MSSQL_ENUM',
327
                                        :data => "No Disabled Logins Found")
328
                        end
329
                end
330

    
331
                #-------------------------------------------------------
332
                # Get list of accounts for which password policy does not apply on System
333
                if vernum.join != "2000"
334
                        print_status("No Accounts Policy is set for:")
335
                        nopolicysyslogins = mssql_query("select name from master.sys.sql_logins where is_policy_checked = 0")[:rows]
336
                        if nopolicysyslogins != nil
337
                                nopolicysyslogins.each do |acc|
338
                                        print_status("\t#{acc.join}")
339
                                        report_note(:host => datastore['RHOST'],
340
                                                :proto => 'TCP',
341
                                                :port => datastore['RPORT'],
342
                                                :type => 'MSSQL_ENUM',
343
                                                :data => "None Policy Checked User: #{acc.join}")
344
                                end
345
                        else
346
                                print_status("\tAll System Accounts have the Windows Account Policy Applied to them.")
347
                                report_note(:host => datastore['RHOST'],
348
                                        :proto => 'TCP',
349
                                        :port => datastore['RPORT'],
350
                                        :type => 'MSSQL_ENUM',
351
                                        :data => "All System Accounts have the Windows Account Policy Applied to them")
352
                        end
353
                end
354

    
355
                #-------------------------------------------------------
356
                # Get list of accounts for which password expiration is not checked
357
                if vernum.join != "2000"
358
                        print_status("Password Expiration is not checked for:")
359
                        passexsyslogins = mssql_query("select name from master.sys.sql_logins where is_expiration_checked = 0")[:rows]
360
                        if passexsyslogins != nil
361
                                passexsyslogins.each do |acc|
362
                                        print_status("\t#{acc.join}")
363
                                        report_note(:host => datastore['RHOST'],
364
                                                :proto => 'TCP',
365
                                                :port => datastore['RPORT'],
366
                                                :type => 'MSSQL_ENUM',
367
                                                :data => "None Password Expiration User: #{acc.join}")
368
                                end
369
                        else
370
                                print_status("\tAll System Accounts are checked for Password Expiration.")
371
                                report_note(:host => datastore['RHOST'],
372
                                        :proto => 'TCP',
373
                                        :port => datastore['RPORT'],
374
                                        :type => 'MSSQL_ENUM',
375
                                        :data => "All System Accounts are checked for Password Expiration")
376
                        end
377
                end
378

    
379
                #-------------------------------------------------------
380
                # Get list of sysadmin logins on System
381
                print_status("System Admin Logins on this Server:")
382
                if vernum.join != "2000"
383
                        sysadmins = mssql_query("select name from master.sys.syslogins where sysadmin = 1")[:rows]
384
                else
385
                        sysadmins = mssql_query("select name from master..syslogins where sysadmin = 1")[:rows]
386
                end
387
                if sysadmins != nil
388
                        sysadmins.each do |acc|
389
                                print_status("\t#{acc.join}")
390
                                report_note(:host => datastore['RHOST'],
391
                                        :proto => 'TCP',
392
                                        :port => datastore['RPORT'],
393
                                        :type => 'MSSQL_ENUM',
394
                                        :data => "Sysdba: #{acc.join}")
395
                        end
396
                else
397
                        print_error("\tCould not enumerate sysadmin accounts!")
398
                        report_note(:host => datastore['RHOST'],
399
                                :proto => 'TCP',
400
                                :port => datastore['RPORT'],
401
                                :type => 'MSSQL_ENUM',
402
                                :data => "Could not enumerate sysadmin accounts")
403
                end
404

    
405
                #-------------------------------------------------------
406
                # Get list of Windows logins on System
407
                print_status("Windows Logins on this Server:")
408
                if vernum.join != "2000"
409
                        winusers = mssql_query("select name from master.sys.syslogins where isntuser = 1")[:rows]
410
                else
411
                        winusers = mssql_query("select name from master..syslogins where isntuser = 1")[:rows]
412
                end
413

    
414
                if winusers != nil
415
                        winusers.each do |acc|
416
                                print_status("\t#{acc.join}")
417
                                report_note(:host => datastore['RHOST'],
418
                                        :proto => 'TCP',
419
                                        :port => datastore['RPORT'],
420
                                        :type => 'MSSQL_ENUM',
421
                                        :data => "Windows Logins: #{acc.join}")
422
                        end
423
                else
424
                        print_status("\tNo Windows logins found!")
425
                        report_note(:host => datastore['RHOST'],
426
                                :proto => 'TCP',
427
                                :port => datastore['RPORT'],
428
                                :type => 'MSSQL_ENUM',
429
                                :data => "No Windows logins found")
430
                end
431

    
432
                #-------------------------------------------------------
433
                # Get list of windows groups that can logins on the System
434
                print_status("Windows Groups that can logins on this Server:")
435
                if vernum.join != "2000"
436
                        wingroups = mssql_query("select name from master.sys.syslogins where isntgroup = 1")[:rows]
437
                else
438
                        wingroups = mssql_query("select name from master..syslogins where isntgroup = 1")[:rows]
439
                end
440

    
441
                if wingroups != nil
442
                        wingroups.each do |acc|
443
                                print_status("\t#{acc.join}")
444
                                report_note(:host => datastore['RHOST'],
445
                                        :proto => 'TCP',
446
                                        :port => datastore['RPORT'],
447
                                        :type => 'MSSQL_ENUM',
448
                                        :data => "Windows Groups: #{acc.join}")
449
                        end
450
                else
451
                        print_status("\tNo Windows Groups where found with permission to login to system.")
452
                        report_note(:host => datastore['RHOST'],
453
                                :proto => 'TCP',
454
                                :port => datastore['RPORT'],
455
                                :type => 'MSSQL_ENUM',
456
                                :data => "No Windows Groups where found with permission to login to system")
457

    
458
                end
459

    
460
                #-------------------------------------------------------
461
                #Check for local accounts with same username as password
462
                sameasuser = []
463
                if vernum.join != "2000"
464
                        sameasuser = mssql_query("SELECT name FROM sys.sql_logins WHERE PWDCOMPARE\(name, password_hash\) = 1")[:rows]
465
                else
466
                        sameasuser = mssql_query("SELECT name FROM master.dbo.syslogins WHERE PWDCOMPARE\(name, password\) = 1")[:rows]
467
                end
468

    
469
                print_status("Accounts with Username and Password being the same:")
470
                if sameasuser != nil
471
                        sameasuser.each do |up|
472
                                print_status("\t#{up.join}")
473
                                report_note(:host => datastore['RHOST'],
474
                                        :proto => 'TCP',
475
                                        :port => datastore['RPORT'],
476
                                        :type => 'MSSQL_ENUM',
477
                                        :data => "Username: #{up.join} Password: #{up.join}")
478
                        end
479
                else
480
                        print_status("\tNo Account with its password being the same as its username was found.")
481
                        report_note(:host => datastore['RHOST'],
482
                                :proto => 'TCP',
483
                                :port => datastore['RPORT'],
484
                                :type => 'MSSQL_ENUM',
485
                                :data => "No Account with its password being the same as its username was found")
486
                end
487

    
488
                #-------------------------------------------------------
489
                #Check for local accounts with empty password
490
                blankpass = []
491
                if vernum.join != "2000"
492
                        blankpass = mssql_query("SELECT name FROM sys.sql_logins WHERE PWDCOMPARE\(\'\', password_hash\) = 1")[:rows]
493
                else
494
                        blankpass = mssql_query("SELECT name FROM master.dbo.syslogins WHERE password IS NULL AND isntname = 0")[:rows]
495
                end
496

    
497
                print_status("Accounts with empty password:")
498
                if blankpass != nil
499
                        blankpass.each do |up|
500
                                print_status("\t#{up.join}")
501
                                report_note(:host => datastore['RHOST'],
502
                                        :proto => 'TCP',
503
                                        :port => datastore['RPORT'],
504
                                        :type => 'MSSQL_ENUM',
505
                                        :data => "Username: #{up.join} Password: EMPTY ")
506
                        end
507
                else
508
                        print_status("\tNo Accounts with empty passwords where found.")
509
                        report_note(:host => datastore['RHOST'],
510
                                :proto => 'TCP',
511
                                :port => datastore['RPORT'],
512
                                :type => 'MSSQL_ENUM',
513
                                :data => "No Accounts with empty passwords where found")
514
                end
515

    
516
                #-------------------------------------------------------
517
                #Check for dangerous stored procedures
518
                fountsp = []
519
                dangeroussp = [
520
                        'sp_createorphan',
521
                        'sp_droporphans',
522
                        'sp_getschemalock',
523
                        'sp_prepexec',
524
                        'sp_prepexecrpc',
525
                        'sp_refreshview',
526
                        'sp_releaseschemalock',
527
                        'sp_replpostschema',
528
                        'sp_replsendtoqueue',
529
                        'sp_replsetsyncstatus',
530
                        'sp_replwritetovarbin',
531
                        'sp_resyncexecute',
532
                        'sp_resyncexecutesql',
533
                        'sp_resyncprepare',
534
                        'sp_resyncuniquetable',
535
                        'sp_unprepare',
536
                        'sp_xml_preparedocument',
537
                        'sp_xml_removedocument',
538
                        'sp_fulltext_getdata',
539
                        'sp_getbindtoken',
540
                        'sp_replcmds',
541
                        'sp_replcounters',
542
                        'sp_repldone',
543
                        'sp_replflush',
544
                        'sp_replincrementlsn',
545
                        'sp_replpostcmd',
546
                        'sp_replsetoriginator',
547
                        'sp_replstatus',
548
                        'sp_repltrans',
549
                        'sp_replupdateschema',
550
                        'sp_reset_connection',
551
                        'sp_sdidebug',
552
                        'xp_availablemedia',
553
                        'xp_check_query_results',
554
                        'xp_cleanupwebtask',
555
                        'xp_cmdshell',
556
                        'xp_convertwebtask',
557
                        'xp_deletemail',
558
                        'xp_dirtree',
559
                        'xp_displayparamstmt',
560
                        'xp_dropwebtask',
561
                        'xp_dsninfo',
562
                        'xp_enum_activescriptengines',
563
                        'xp_enum_oledb_providers',
564
                        'xp_enumcodepages',
565
                        'xp_enumdsn',
566
                        'xp_enumerrorlogs',
567
                        'xp_enumgroups',
568
                        'xp_enumqueuedtasks',
569
                        'xp_eventlog',
570
                        'xp_execresultset',
571
                        'xp_fileexist',
572
                        'xp_findnextmsg',
573
                        'xp_fixeddrives',
574
                        'xp_get_mapi_default_profile',
575
                        'xp_get_mapi_profiles',
576
                        'xp_get_tape_devices',
577
                        'xp_getfiledetails',
578
                        'xp_getnetname',
579
                        'xp_grantlogin',
580
                        'xp_initcolvs',
581
                        'xp_intersectbitmaps',
582
                        'xp_logevent',
583
                        'xp_loginconfig',
584
                        'xp_logininfo',
585
                        'xp_makewebtask',
586
                        'xp_mergexpusage',
587
                        'xp_monitorsignal',
588
                        'xp_msver any user',
589
                        'xp_msx_enlist',
590
                        'xp_ntsec_enumdomains',
591
                        'xp_ntsec_enumgroups',
592
                        'xp_ntsec_enumusers',
593
                        'xp_oledbinfo',
594
                        'xp_perfend',
595
                        'xp_perfmonitor',
596
                        'xp_perfsample',
597
                        'xp_perfstart',
598
                        'xp_printstatements',
599
                        'xp_prop_oledb_provider',
600
                        'xp_proxiedmetadata',
601
                        'xp_qv',
602
                        'xp_readerrorlog',
603
                        'xp_readmail',
604
                        'xp_readwebtask',
605
                        'xp_regaddmultistring',
606
                        'xp_regdeletekey',
607
                        'xp_regdeletevalue',
608
                        'xp_regenumvalues',
609
                        'xp_regread',
610
                        'xp_regremovemultistring',
611
                        'xp_regwrite',
612
                        'xp_repl_encrypt',
613
                        'xp_revokelogin',
614
                        'xp_runwebtask',
615
                        'xp_schedulersignal',
616
                        'xp_sendmail',
617
                        'xp_servicecontrol',
618
                        'xp_showcolv',
619
                        'xp_showlineage',
620
                        'xp_snmp_getstate',
621
                        'xp_snmp_raisetrap',
622
                        'xp_sprintf any user', # huh?
623
                        'xp_sqlagent_enum_jobs',
624
                        'xp_sqlagent_is_starting',
625
                        'xp_sqlagent_monitor',
626
                        'xp_sqlagent_notify',
627
                        'xp_sqlinventory',
628
                        'xp_sqlmaint',
629
                        'xp_sqlregister',
630
                        'xp_sqltrace',
631
                        'xp_startmail',
632
                        'xp_stopmail',
633
                        'xp_subdirs',
634
                        'xp_terminate_process',
635
                        'xp_test_mapi_profile',
636
                        'xp_trace_addnewqueue',
637
                        'xp_trace_deletequeuedefinition',
638
                        'xp_trace_destroyqueue',
639
                        'xp_trace_enumqueuedefname',
640
                        'xp_trace_enumqueuehandles',
641
                        'xp_trace_eventclassrequired',
642
                        'xp_trace_flushqueryhistory',
643
                        'xp_trace_generate_event',
644
                        'xp_trace_getappfilter',
645
                        'xp_trace_getconnectionidfilter',
646
                        'xp_trace_getcpufilter',
647
                        'xp_trace_getdbidfilter',
648
                        'xp_trace_getdurationfilter',
649
                        'xp_trace_geteventfilter',
650
                        'xp_trace_geteventnames',
651
                        'xp_trace_getevents',
652
                        'xp_trace_gethostfilter',
653
                        'xp_trace_gethpidfilter',
654
                        'xp_trace_getindidfilter',
655
                        'xp_trace_getntdmfilter',
656
                        'xp_trace_getntnmfilter',
657
                        'xp_trace_getobjidfilter',
658
                        'xp_trace_getqueueautostart',
659
                        'xp_trace_getqueuecreateinfo',
660
                        'xp_trace_getqueuedestination',
661
                        'xp_trace_getqueueproperties',
662
                        'xp_trace_getreadfilter',
663
                        'xp_trace_getserverfilter',
664
                        'xp_trace_getseverityfilter',
665
                        'xp_trace_getspidfilter',
666
                        'xp_trace_getsysobjectsfilter',
667
                        'xp_trace_gettextfilter',
668
                        'xp_trace_getuserfilter',
669
                        'xp_trace_getwritefilter',
670
                        'xp_trace_loadqueuedefinition',
671
                        'xp_trace_opentracefile',
672
                        'xp_trace_pausequeue',
673
                        'xp_trace_restartqueue',
674
                        'xp_trace_savequeuedefinition',
675
                        'xp_trace_setappfilter',
676
                        'xp_trace_setconnectionidfilter',
677
                        'xp_trace_setcpufilter',
678
                        'xp_trace_setdbidfilter',
679
                        'xp_trace_setdurationfilter',
680
                        'xp_trace_seteventclassrequired',
681
                        'xp_trace_seteventfilter',
682
                        'xp_trace_sethostfilter',
683
                        'xp_trace_sethpidfilter',
684
                        'xp_trace_setindidfilter',
685
                        'xp_trace_setntdmfilter',
686
                        'xp_trace_setntnmfilter',
687
                        'xp_trace_setobjidfilter',
688
                        'xp_trace_setqueryhistory',
689
                        'xp_trace_setqueueautostart',
690
                        'xp_trace_setqueuecreateinfo',
691
                        'xp_trace_setqueuedestination',
692
                        'xp_trace_setreadfilter',
693
                        'xp_trace_setserverfilter',
694
                        'xp_trace_setseverityfilter',
695
                        'xp_trace_setspidfilter',
696
                        'xp_trace_setsysobjectsfilter',
697
                        'xp_trace_settextfilter',
698
                        'xp_trace_setuserfilter',
699
                        'xp_trace_setwritefilter',
700
                        'xp_trace_startconsumer',
701
                        'xp_unc_to_drive',
702
                        'xp_updatecolvbm',
703
                        'xp_updateFTSSQLAccount',
704
                        'xp_updatelineage',
705
                        'xp_varbintohexstr',
706
                        'xp_writesqlinfo',
707
                        'xp_MSplatform',
708
                        'xp_MSnt2000',
709
                        'xp_MSLocalSystem',
710
                        'xp_IsNTAdmin',
711
                        'xp_mapdown_bitmap'
712
                ]
713

    
714
                query = <<-EOS
715
SELECT CAST(SYSOBJECTS.NAME AS CHAR) FROM SYSOBJECTS, SYSPROTECTS WHERE SYSPROTECTS.UID = 0 AND XTYPE IN ('X','P')
716
AND SYSOBJECTS.ID = SYSPROTECTS.ID
717
EOS
718
                fountsp = mssql_query(query)[:rows]
719
                if fountsp != nil
720
                        fountsp.flatten!
721
                        print_status("Stored Procedures with Public Execute Permission found:")
722
                        fountsp.each do |strp|
723
                                if dangeroussp.include?(strp.strip)
724
                                        print_status("\t#{strp.strip}")
725
                                        report_note(:host => datastore['RHOST'],
726
                                                :proto => 'TCP',
727
                                                :port => datastore['RPORT'],
728
                                                :type => 'MSSQL_ENUM',
729
                                                :data => "Stored Procedures with Public Execute Permission #{strp.strip}")
730
                                end
731
                        end
732
                else
733
                        print_status("\tNo Dangerous Stored Procedure found with Public Execute.")
734
                        report_note(:host => datastore['RHOST'],
735
                                :proto => 'TCP',
736
                                :port => datastore['RPORT'],
737
                                :type => 'MSSQL_ENUM',
738
                                :data => "No Dangerous Stored Procedure found with Public Execute")
739
                end
740

    
741
                #-------------------------------------------------------
742
                #Enumerate Instances
743
                instances =[]
744
                if vernum.join != "2000"
745
                        querykey = "EXEC master..xp_regenumvalues \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL\'"
746
                        instance_res = mssql_query(querykey)[:rows]
747
                        if instance_res != nil
748
                                instance_res.each do |i|
749
                                        instances << i[0]
750
                                end
751
                        end
752
                else
753
                        querykey = "exec xp_regread \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\', \'InstalledInstances\'"
754
                        instance_res = mssql_query(querykey)[:rows]
755
                        if instance_res != nil
756
                                instance_res.each do |i|
757
                                        instances << i[1]
758
                                end
759
                        end
760
                end
761

    
762
                print_status("Instances found on this server:")
763
                instancenames = []
764
                if instances != nil
765
                        instances.each do |i|
766
                                print_status("\t#{i}")
767
                                instancenames << i.strip
768
                                report_note(:host => datastore['RHOST'],
769
                                        :proto => 'TCP',
770
                                        :port => datastore['RPORT'],
771
                                        :type => 'MSSQL_ENUM',
772
                                        :data => "Instance Name: #{i}")
773
                        end
774
                else
775
                        print_status("No instances found, possible permission problem")
776
                end
777

    
778
                #---------------------------------------------------------
779
                #Enumerate under what accounts the instance services are running under
780
                print_status("Default Server Instance SQL Server Service is running under the privilege of:")
781
                privdflt = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQLSERVER\',\'ObjectName\'")[:rows]
782
                if privdflt != nil
783
                        privdflt.each do |priv|
784
                                print_status("\t#{priv[1]}")
785
                                report_note(:host => datastore['RHOST'],
786
                                        :proto => 'TCP',
787
                                        :port => datastore['RPORT'],
788
                                        :type => 'MSSQL_ENUM',
789
                                        :data => "Default Instance SQL Server running as: #{priv[1]}")
790
                        end
791
                else
792
                        print_status("\txp_regread might be disabled in this system")
793
                end
794

    
795
                #------------------------------------------------------------
796
                if instancenames.length > 1
797
                        instancenames.each do |i|
798
                                if i.strip != "MSSQLSERVER"
799
                                        privinst = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQL$#{i.strip}\',\'ObjectName\'")[:rows]
800
                                        if privinst != nil
801
                                                print_status("Instance #{i} SQL Server Service is running under the privilege of:")
802
                                                privinst.each do |p|
803
                                                        print_status("\t#{p[1]}")
804
                                                        report_note(:host => datastore['RHOST'],
805
                                                                :proto => 'TCP',
806
                                                                :port => datastore['RPORT'],
807
                                                                :type => 'MSSQL_ENUM',
808
                                                                :data => "#{i} Instance SQL Server running as: #{p[1]}")
809
                                                end
810
                                        else
811
                                                print_status("\tCould not enumerate credentials for Instance.")
812
                                        end
813
                                end
814
                        end
815
                end
816

    
817
                disconnect
818
        end
819
end