Lucene search
K

Microsoft SQL Server Configuration Enumerator

🗓️ 19 Oct 2009 04:58:50Reported by Carlos Perez <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 48 Views

This module performs configuration audits and security checks against Microsoft SQL Server database by enumerating configuration parameters and checking for the presence of certain features to ensure the server is secure against common threats

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::MSSQL
  include Msf::Auxiliary::Report
  include Msf::OptionalSession::MSSQL

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Microsoft SQL Server Configuration Enumerator',
      'Description'    => %q{
          This module will perform a series of configuration audits and
        security checks against a Microsoft SQL Server database. For this
        module to work, valid administrative user credentials must be
        supplied.
      },
      'Author'         => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>' ],
      'License'        => MSF_LICENSE
    ))
  end

  def run
    print_status("Running MS SQL Server Enumeration...")
    if session
      set_mssql_session(session.client)
    else
      unless mssql_login_datastore
        print_error("Login was unsuccessful. Check your credentials.")
        disconnect
        return
      end
    end

    # Get Version
    print_status("Version:")
    vernum =""
    ver = mssql_query("select @@version")
    sqlversion = ver[:rows].join
    sqlversion.each_line do |row|
      print "[*]\t#{row}"
    end
    vernum = sqlversion.gsub("\n"," ").scan(/SQL Server\s*(200\d)/m)
    report_note(:host => mssql_client.peerhost,
      :proto => 'TCP',
      :port => mssql_client.peerport,
      :type => 'MSSQL_ENUM',
      :data => "Version: #{sqlversion}")

    #---------------------------------------------------------
    # Check Configuration Parameters and check what is enabled
    print_status("Configuration Parameters:")
    if vernum.join != "2000"
      query = "SELECT name, CAST(value_in_use AS INT) from sys.configurations"
      ver = mssql_query(query)[:rows]
      sysconfig = {}
      ver.each do |l|
        sysconfig[l[0].strip] = l[1].to_i
      end
    else
      # enable advanced options
      mssql_query("EXEC sp_configure \'show advanced options\', 1; RECONFIGURE")[:rows]
      query = "EXECUTE sp_configure"
      ver = mssql_query(query)[:rows]
      ver.class
      sysconfig = {}
      ver.each do |l|
        sysconfig[l[0].strip] = l[3].to_i
      end
    end

    #-------------------------------------------------------
    # checking for C2 Audit Mode
    if sysconfig['c2 audit mode'] == 1
      print_status("\tC2 Audit Mode is Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "C2 Audit Mode is Enabled")
    else
      print_status("\tC2 Audit Mode is Not Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "C2 Audit Mode is Not Enabled")
    end

    #-------------------------------------------------------
    # check if xp_cmdshell is enabled
    if vernum.join != "2000"
      if sysconfig['xp_cmdshell'] == 1
        print_status("\txp_cmdshell is Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "xp_cmdshell is Enabled")
      else
        print_status("\txp_cmdshell is Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "xp_cmdshell is Not Enabled")
      end
    else
      xpspexist = mssql_query("select sysobjects.name from sysobjects where name = \'xp_cmdshell\'")[:rows]
      if xpspexist != nil
        print_status("\txp_cmdshell is Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "xp_cmdshell is Enabled")
      else
        print_status("\txp_cmdshell is Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "xp_cmdshell is Not Enabled")
      end
    end

    #-------------------------------------------------------
    # check if remote access is enabled
    if sysconfig['remote access'] == 1
      print_status("\tremote access is Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "remote access is Enabled")
    else
      print_status("\tremote access is Not Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "remote access is not Enabled")
    end

    #-------------------------------------------------------
    #check if updates are allowed
    if sysconfig['allow updates'] == 1
      print_status("\tallow updates is Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "allow updates is Enabled")
    else
      print_status("\tallow updates is Not Enabled")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "allow updates is not Enabled")
    end

    #-------------------------------------------------------
    # check if Mail stored procedures are enabled
    if vernum.join != "2000"
      if sysconfig['Database Mail XPs'] == 1
        print_status("\tDatabase Mail XPs is Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Database Mail XPs is Enabled")
      else
        print_status("\tDatabase Mail XPs is Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Database Mail XPs is not Enabled")
      end
    else
      mailexist = mssql_query("select sysobjects.name from sysobjects where name like \'%mail%\'")[:rows]
      if mailexist != nil
        print_status("\tDatabase Mail XPs is Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Database Mail XPs is Enabled")
      else
        print_status("\tDatabase Mail XPs is Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Database Mail XPs is not Enabled")
      end
    end

    #-------------------------------------------------------
    # check if OLE stored procedures are enabled
    if vernum.join != "2000"
      if sysconfig['Ole Automation Procedures'] == 1
        print_status("\tOle Automation Procedures are Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Ole Automation Procedures are Enabled")
      else
        print_status("\tOle Automation Procedures are Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Ole Automation Procedures are not Enabled")
      end
    else
      oleexist = mssql_query("select sysobjects.name from sysobjects where name like \'%sp_OA%\'")[:rows]
      if oleexist != nil
        print_status("\tOle Automation Procedures is Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Ole Automation Procedures are Enabled")
      else
        print_status("\tOle Automation Procedures are Not Enabled")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Ole Automation Procedures are not Enabled")
      end
    end

    #-------------------------------------------------------
    # Get list of Databases on System
    print_status("Databases on the server:")
    dbs = mssql_query("select name from master..sysdatabases")[:rows].flatten
    if dbs != nil
      dbs.each do |dbn|
        print_status("\tDatabase name:#{dbn.strip}")
        print_status("\tDatabase Files for #{dbn.strip}:")
        if vernum.join != "2000"
          db_ind_files = mssql_query("select filename from #{dbn.strip}.sys.sysfiles")[:rows]
          if db_ind_files != nil
            db_ind_files.each do |fn|
              print_status("\t\t#{fn.join}")
              report_note(:host => mssql_client.peerhost,
                :proto => 'TCP',
                :port => mssql_client.peerport,
                :type => 'MSSQL_ENUM',
                :data => "Database: #{dbn.strip} File: #{fn.join}")
            end
          end
        else
          db_ind_files = mssql_query("select filename from #{dbn.strip}..sysfiles")[:rows]
          if db_ind_files != nil
            db_ind_files.each do |fn|
              print_status("\t\t#{fn.join.strip}")
              report_note(:host => mssql_client.peerhost,
                :proto => 'TCP',
                :port => mssql_client.peerport,
                :type => 'MSSQL_ENUM',
                :data => "Database: #{dbn.strip} File: #{fn.join}")
            end
          end
        end
      end
    end

    #-------------------------------------------------------
    # Get list of syslogins on System
    print_status("System Logins on this Server:")
    if vernum.join != "2000"
      syslogins = mssql_query("select loginname from master.sys.syslogins")[:rows]
    else
      syslogins = mssql_query("select loginname from master..syslogins")[:rows]
    end
    if syslogins != nil
      syslogins.each do |acc|
        print_status("\t#{acc.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Database: Master User: #{acc.join}")
      end
    else
      print_error("\tCould not enumerate System Logins!")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "Could not enumerate System Logins")
    end

    #-------------------------------------------------------
    # Get list of disabled accounts on System
    if vernum.join != "2000"
      print_status("Disabled Accounts:")
      disabledsyslogins = mssql_query("select name from master.sys.server_principals where is_disabled = 1")[:rows]
      if disabledsyslogins != nil
        disabledsyslogins.each do |acc|
          print_status("\t#{acc.join}")
          report_note(:host => mssql_client.peerhost,
            :proto => 'TCP',
            :port => mssql_client.peerport,
            :type => 'MSSQL_ENUM',
            :data => "Disabled User: #{acc.join}")
        end
      else
        print_status("\tNo Disabled Logins Found")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "No Disabled Logins Found")
      end
    end

    #-------------------------------------------------------
    # Get list of accounts for which password policy does not apply on System
    if vernum.join != "2000"
      print_status("No Accounts Policy is set for:")
      nopolicysyslogins = mssql_query("select name from master.sys.sql_logins where is_policy_checked = 0")[:rows]
      if nopolicysyslogins != nil
        nopolicysyslogins.each do |acc|
          print_status("\t#{acc.join}")
          report_note(:host => mssql_client.peerhost,
            :proto => 'TCP',
            :port => mssql_client.peerport,
            :type => 'MSSQL_ENUM',
            :data => "None Policy Checked User: #{acc.join}")
        end
      else
        print_status("\tAll System Accounts have the Windows Account Policy Applied to them.")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "All System Accounts have the Windows Account Policy Applied to them")
      end
    end

    #-------------------------------------------------------
    # Get list of accounts for which password expiration is not checked
    if vernum.join != "2000"
      print_status("Password Expiration is not checked for:")
      passexsyslogins = mssql_query("select name from master.sys.sql_logins where is_expiration_checked = 0")[:rows]
      if passexsyslogins != nil
        passexsyslogins.each do |acc|
          print_status("\t#{acc.join}")
          report_note(:host => mssql_client.peerhost,
            :proto => 'TCP',
            :port => mssql_client.peerport,
            :type => 'MSSQL_ENUM',
            :data => "None Password Expiration User: #{acc.join}")
        end
      else
        print_status("\tAll System Accounts are checked for Password Expiration.")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "All System Accounts are checked for Password Expiration")
      end
    end

    #-------------------------------------------------------
    # Get list of sysadmin logins on System
    print_status("System Admin Logins on this Server:")
    if vernum.join != "2000"
      sysadmins = mssql_query("select name from master.sys.syslogins where sysadmin = 1")[:rows]
    else
      sysadmins = mssql_query("select name from master..syslogins where sysadmin = 1")[:rows]
    end
    if sysadmins != nil
      sysadmins.each do |acc|
        print_status("\t#{acc.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Sysdba: #{acc.join}")
      end
    else
      print_error("\tCould not enumerate sysadmin accounts!")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "Could not enumerate sysadmin accounts")
    end

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

    if winusers != nil
      winusers.each do |acc|
        print_status("\t#{acc.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Windows Logins: #{acc.join}")
      end
    else
      print_status("\tNo Windows logins found!")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "No Windows logins found")
    end

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

    if wingroups != nil
      wingroups.each do |acc|
        print_status("\t#{acc.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Windows Groups: #{acc.join}")
      end
    else
      print_status("\tNo Windows Groups where found with permission to login to system.")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "No Windows Groups where found with permission to login to system")

    end

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

    print_status("Accounts with Username and Password being the same:")
    if sameasuser != nil
      sameasuser.each do |up|
        print_status("\t#{up.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Username: #{up.join} Password: #{up.join}")
      end
    else
      print_status("\tNo Account with its password being the same as its username was found.")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "No Account with its password being the same as its username was found")
    end

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

    print_status("Accounts with empty password:")
    if blankpass != nil
      blankpass.each do |up|
        print_status("\t#{up.join}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Username: #{up.join} Password: EMPTY ")
      end
    else
      print_status("\tNo Accounts with empty passwords where found.")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "No Accounts with empty passwords where found")
    end

    #-------------------------------------------------------
    # Check for dangerous stored procedures
    fountsp = []
    dangeroussp = [
      'sp_createorphan',
      'sp_droporphans',
      'sp_execute_external_script',
      'sp_getschemalock',
      'sp_prepexec',
      'sp_prepexecrpc',
      'sp_refreshview',
      'sp_releaseschemalock',
      'sp_replpostschema',
      'sp_replsendtoqueue',
      'sp_replsetsyncstatus',
      'sp_replwritetovarbin',
      'sp_resyncexecute',
      'sp_resyncexecutesql',
      'sp_resyncprepare',
      'sp_resyncuniquetable',
      'sp_unprepare',
      'sp_xml_preparedocument',
      'sp_xml_removedocument',
      'sp_fulltext_getdata',
      'sp_getbindtoken',
      'sp_replcmds',
      'sp_replcounters',
      'sp_repldone',
      'sp_replflush',
      'sp_replincrementlsn',
      'sp_replpostcmd',
      'sp_replsetoriginator',
      'sp_replstatus',
      'sp_repltrans',
      'sp_replupdateschema',
      'sp_reset_connection',
      'sp_sdidebug',
      'xp_availablemedia',
      'xp_check_query_results',
      'xp_cleanupwebtask',
      'xp_cmdshell',
      'xp_convertwebtask',
      'xp_deletemail',
      'xp_dirtree',
      'xp_displayparamstmt',
      'xp_dropwebtask',
      'xp_dsninfo',
      'xp_enum_activescriptengines',
      'xp_enum_oledb_providers',
      'xp_enumcodepages',
      'xp_enumdsn',
      'xp_enumerrorlogs',
      'xp_enumgroups',
      'xp_enumqueuedtasks',
      'xp_eventlog',
      'xp_execresultset',
      'xp_fileexist',
      'xp_findnextmsg',
      'xp_fixeddrives',
      'xp_get_mapi_default_profile',
      'xp_get_mapi_profiles',
      'xp_get_tape_devices',
      'xp_getfiledetails',
      'xp_getnetname',
      'xp_grantlogin',
      'xp_initcolvs',
      'xp_intersectbitmaps',
      'xp_logevent',
      'xp_loginconfig',
      'xp_logininfo',
      'xp_makewebtask',
      'xp_mergexpusage',
      'xp_monitorsignal',
      'xp_msver any user',
      'xp_msx_enlist',
      'xp_ntsec_enumdomains',
      'xp_ntsec_enumgroups',
      'xp_ntsec_enumusers',
      'xp_oledbinfo',
      'xp_perfend',
      'xp_perfmonitor',
      'xp_perfsample',
      'xp_perfstart',
      'xp_printstatements',
      'xp_prop_oledb_provider',
      'xp_proxiedmetadata',
      'xp_qv',
      'xp_readerrorlog',
      'xp_readmail',
      'xp_readwebtask',
      'xp_regaddmultistring',
      'xp_regdeletekey',
      'xp_regdeletevalue',
      'xp_regenumvalues',
      'xp_regread',
      'xp_regremovemultistring',
      'xp_regwrite',
      'xp_repl_encrypt',
      'xp_revokelogin',
      'xp_runwebtask',
      'xp_schedulersignal',
      'xp_sendmail',
      'xp_servicecontrol',
      'xp_showcolv',
      'xp_showlineage',
      'xp_snmp_getstate',
      'xp_snmp_raisetrap',
      'xp_sprintf any user', # huh?
      'xp_sqlagent_enum_jobs',
      'xp_sqlagent_is_starting',
      'xp_sqlagent_monitor',
      'xp_sqlagent_notify',
      'xp_sqlinventory',
      'xp_sqlmaint',
      'xp_sqlregister',
      'xp_sqltrace',
      'xp_startmail',
      'xp_stopmail',
      'xp_subdirs',
      'xp_terminate_process',
      'xp_test_mapi_profile',
      'xp_trace_addnewqueue',
      'xp_trace_deletequeuedefinition',
      'xp_trace_destroyqueue',
      'xp_trace_enumqueuedefname',
      'xp_trace_enumqueuehandles',
      'xp_trace_eventclassrequired',
      'xp_trace_flushqueryhistory',
      'xp_trace_generate_event',
      'xp_trace_getappfilter',
      'xp_trace_getconnectionidfilter',
      'xp_trace_getcpufilter',
      'xp_trace_getdbidfilter',
      'xp_trace_getdurationfilter',
      'xp_trace_geteventfilter',
      'xp_trace_geteventnames',
      'xp_trace_getevents',
      'xp_trace_gethostfilter',
      'xp_trace_gethpidfilter',
      'xp_trace_getindidfilter',
      'xp_trace_getntdmfilter',
      'xp_trace_getntnmfilter',
      'xp_trace_getobjidfilter',
      'xp_trace_getqueueautostart',
      'xp_trace_getqueuecreateinfo',
      'xp_trace_getqueuedestination',
      'xp_trace_getqueueproperties',
      'xp_trace_getreadfilter',
      'xp_trace_getserverfilter',
      'xp_trace_getseverityfilter',
      'xp_trace_getspidfilter',
      'xp_trace_getsysobjectsfilter',
      'xp_trace_gettextfilter',
      'xp_trace_getuserfilter',
      'xp_trace_getwritefilter',
      'xp_trace_loadqueuedefinition',
      'xp_trace_opentracefile',
      'xp_trace_pausequeue',
      'xp_trace_restartqueue',
      'xp_trace_savequeuedefinition',
      'xp_trace_setappfilter',
      'xp_trace_setconnectionidfilter',
      'xp_trace_setcpufilter',
      'xp_trace_setdbidfilter',
      'xp_trace_setdurationfilter',
      'xp_trace_seteventclassrequired',
      'xp_trace_seteventfilter',
      'xp_trace_sethostfilter',
      'xp_trace_sethpidfilter',
      'xp_trace_setindidfilter',
      'xp_trace_setntdmfilter',
      'xp_trace_setntnmfilter',
      'xp_trace_setobjidfilter',
      'xp_trace_setqueryhistory',
      'xp_trace_setqueueautostart',
      'xp_trace_setqueuecreateinfo',
      'xp_trace_setqueuedestination',
      'xp_trace_setreadfilter',
      'xp_trace_setserverfilter',
      'xp_trace_setseverityfilter',
      'xp_trace_setspidfilter',
      'xp_trace_setsysobjectsfilter',
      'xp_trace_settextfilter',
      'xp_trace_setuserfilter',
      'xp_trace_setwritefilter',
      'xp_trace_startconsumer',
      'xp_unc_to_drive',
      'xp_updatecolvbm',
      'xp_updateFTSSQLAccount',
      'xp_updatelineage',
      'xp_varbintohexstr',
      'xp_writesqlinfo',
      'xp_MSplatform',
      'xp_MSnt2000',
      'xp_MSLocalSystem',
      'xp_IsNTAdmin',
      'xp_mapdown_bitmap'
    ]

    query = <<-EOS
SELECT CAST(SYSOBJECTS.NAME AS CHAR) FROM SYSOBJECTS, SYSPROTECTS WHERE SYSPROTECTS.UID = 0 AND XTYPE IN ('X','P')
AND SYSOBJECTS.ID = SYSPROTECTS.ID
EOS
    fountsp = mssql_query(query)[:rows]
    if fountsp != nil
      fountsp.flatten!
      print_status("Stored Procedures with Public Execute Permission found:")
      fountsp.each do |strp|
        if dangeroussp.include?(strp.strip)
          print_status("\t#{strp.strip}")
          report_note(:host => mssql_client.peerhost,
            :proto => 'TCP',
            :port => mssql_client.peerport,
            :type => 'MSSQL_ENUM',
            :data => "Stored Procedures with Public Execute Permission #{strp.strip}")
        end
      end
    else
      print_status("\tNo Dangerous Stored Procedure found with Public Execute.")
      report_note(:host => mssql_client.peerhost,
        :proto => 'TCP',
        :port => mssql_client.peerport,
        :type => 'MSSQL_ENUM',
        :data => "No Dangerous Stored Procedure found with Public Execute")
    end

    #-------------------------------------------------------
    # Enumerate Instances
    instances =[]
    if vernum.join != "2000"
      querykey = "EXEC master..xp_regenumvalues \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL\'"
      instance_res = mssql_query(querykey)[:rows]
      if instance_res != nil
        instance_res.each do |i|
          instances << i[0]
        end
      end
    else
      querykey = "exec xp_regread \'HKEY_LOCAL_MACHINE\',\'SOFTWARE\\Microsoft\\Microsoft SQL Server\', \'InstalledInstances\'"
      instance_res = mssql_query(querykey)[:rows]
      if instance_res != nil
        instance_res.each do |i|
          instances << i[1]
        end
      end
    end

    print_status("Instances found on this server:")
    instancenames = []
    if instances != nil
      instances.each do |i|
        print_status("\t#{i}")
        instancenames << i.strip
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Instance Name: #{i}")
      end
    else
      print_status("No instances found, possible permission problem")
    end

    #---------------------------------------------------------
    # Enumerate under what accounts the instance services are running under
    print_status("Default Server Instance SQL Server Service is running under the privilege of:")
    privdflt = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQLSERVER\',\'ObjectName\'")[:rows]
    if privdflt != nil
      privdflt.each do |priv|
        print_status("\t#{priv[1]}")
        report_note(:host => mssql_client.peerhost,
          :proto => 'TCP',
          :port => mssql_client.peerport,
          :type => 'MSSQL_ENUM',
          :data => "Default Instance SQL Server running as: #{priv[1]}")
      end
    else
      print_status("\txp_regread might be disabled in this system")
    end

    #------------------------------------------------------------
    if instancenames.length > 1
      instancenames.each do |i|
        if i.strip != "MSSQLSERVER"
          privinst = mssql_query("EXEC master..xp_regread \'HKEY_LOCAL_MACHINE\' ,\'SYSTEM\\CurrentControlSet\\Services\\MSSQL$#{i.strip}\',\'ObjectName\'")[:rows]
          if privinst != nil
            print_status("Instance #{i} SQL Server Service is running under the privilege of:")
            privinst.each do |p|
              print_status("\t#{p[1]}")
              report_note(:host => mssql_client.peerhost,
                :proto => 'TCP',
                :port => mssql_client.peerport,
                :type => 'MSSQL_ENUM',
                :data => "#{i} Instance SQL Server running as: #{p[1]}")
            end
          else
            print_status("\tCould not enumerate credentials for Instance.")
          end
        end
      end
    end

    disconnect
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation