MSSQL
Pentesting MSSQL - TCP Port 1433
Theory
Microsoft SQL Server (MSSQL) is a relational database management system developed by Microsoft. By default, it runs on port TCP 1433
Default MS-SQL System Tables:
master Database: Records all the system-level information for an instance of SQL Server.
msdb Database: Is used by SQL Server Agent for scheduling alerts and jobs.
model Database: Is used as the template for all databases created on the instance of SQL Server. Modifications made to the model database, such as database size, collation, recovery model, and other database options, are applied to any databases created afterwards.
Resource Databas: Is a read-only database that contains system objects that are included with SQL Server. System objects are physically persisted in the Resource database, but they logically appear in the sys schema of every database.
tempdb Database : Is a work-space for holding temporary objects or intermediate result sets.
Practice
Enumerate
Using nmap scripts, we can enumerate the version of the TNS-Listener
# Usefull Scipts
nmap --script ms-sql-info -p 1433 <target-ip>
nmap --script ms-sql-config -p 1433 <target-ip>
nmap --script ms-sql-empty-password,ms-sql-xp-cmdshell -p 1433 <target-ip>
nmap --script ms-sql-* -p 1433 <target-ip>
# Run all Scripts
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 <IP>In Active Directory environements, we can directly request the Domain Controller for a list of SPNs, to stealthly identify MSSQL servers.
From a Windows Domain-Joined Computer, we can use the setspn or GetUserSPNs.ps1 command as follows.
# Setspn LOLBIN
setspn -T domain.local -Q MSSQLSvc/*
# Using GetUserSPNs
. .\GetUserSPNs.ps1From an UNIX-Like hosts, we can directly search using GetUserSPNs from impacket:
GetUserSPNs.py -dc-ip <DC_IP> '<DOMAIN>/<USER>:<Password>'Enumerate DB Objects
To enumerate Databases, Tables, Columns, Users, Permissions, refers to the following page
Enum DatabasesBrute Force Credentials
If you don't have credentials you can try to guess them. You can use nmap or metasploit. Be careful, you can block accounts if you fail login several times using an existing username.
Using NetExec, we may bruteforce MSSQL credentials.
Using Hydra, we may bruteforce MSSQL credentials.
Sign-in
Using mssqlclient from Impacket, we can login to an MSSQL instance.
Using sqsh we can connect to a MSSQL instance.
Tools like NetExec can be used to login to an MSSQL instance, and to perform SQL queries.
Remote Code Execution
Tools like NetExec can be used to execute OS commands from MSSQL
MSSqlPwner can be used to execute remote commands through various methods.
Using mssqlclient from Impacket, we may be able to execute code.
Local Code Execution
To localy execute/read/write files on an MSSQL instance, see the following page:
Read/Write/ExecuteCoerced Auths (Stealing NTLM Hash)
On MS-SQL (Microsoft SQL) servers, the EXEC method can be used to access a remote SMB share. MSSQL uses Keberos to authenticate users so we can retrieve the NTLM hash.
Living off the landMSSQL Privilege Escalation
SQL Server has a special permission, named IMPERSONATE, that allows the executing user to take on the permissions of another user or login until the context is reset or the session ends.
UNIX-Like
From an UNIX-Like host, using NetExec, we can enumerate for impersonation privileges and PrivEsc as follows
Windows
To enumerate users that you can impersonate, run the following queries
We may also use mssqlclient from Impacket to enumerate users that we can impersonate
If you can impersonate a user, even if he isn't sysadmin, you should check if the user has access to other databases or linked servers.
Note that once you are sysadmin you can impersonate any other one:
If a regular user is given the role db_owner over the database owned by an admin user (such as sa) and that database is configured as trustworthy, that user can abuse these privileges to privesc because stored procedures created in there that can execute as the owner (admin).
Windows
To enumerate, run the following queries
If you found you are db_owner of a trustworthy database, you can privesc
Otherwise, we can use Invoke-SqlServerDbElevateDbOwner powershell script to automate the exploit
Local Privilege Escalation
The user running MSSQL server will have enabled the privilege token SeImpersonatePrivilege. You probably will be able to escalate to Administrator or NT AUTHORITY\SYSTEM following this page:
Abusing TokensLinked SQL Servers Abuse
Linked servers are typically configured to enable the database engine to execute a Transact-SQL statement that includes tables in another instance of SQL Server. From an attacking perspective, misconfigured linked servers can enable privilege escalation, lateral movement, and unauthorized data access by pivoting through trusted database connections.
From an UNIX-Like machine, we can enumerate Linked SQL Servers using MssqlClient.py or MSSqlPwner.
Remote Execution
From an UNIX-Like machine, we can execute code on a Linked SQL Servers using MssqlClient.py or MSSqlPwner.
The SQL login on the Linked SQL Server must be sysadmin
Decrypting Linked Server Passwords
After compromising a machine hosting an MSSQL Server instance with linked servers, an attacker can extract and decrypt the credentials used for linked server authentication (MSSQL Server Authentication).
To do so, you need to have:
A login with
sysadminrole on the SQL Server instance.Local administratorprivileges on the underlying Windows server.
MSSQL stores link server information, including the encrypted password, in master.sys.syslnklgns table. Specifically, the encrypted password is stored in the pwdhash column (even though it’s not a hash).
The master.sys.syslnklgns table cannot be accessed using a normal SQL connection, but rather a Dedicated Administrative Connection (DAC) is needed. By default, DACs may only be created locally (controlled by the remote admin connections configuration option).
These credentials stored in master.sys.syslnklgns are symmetrically encrypted with the Service Master Key, which is stored inside the sys.key_encryptions table with a key_id value of 102. SMK is encrypted using Windows Data Protection API (DPAPI) and there are two versions of it in the database:
One encrypted as
LocalMachine(withthumbprintset to0x01)One encrypted in the context of
CurrentUser,meaning the SQL Server service account .
We generally choose the LocalMachine option as it can be decrypted without needing to impersonate the service account.
Additional entropy is added to strengthen the encryption but the entropy bytes can be found in the registry at HKLM:SOFTWAREMicrosoftMicrosoft SQL Server[instancename]SecurityEntropy.
Manually
One connected on MSSQL via DAC, we can enumerate and retreive encrypted credentials as follows.
We can then use following Powershell script, as Local Administrator, to decrypt the Service Master Key:
Results of previous script is the hex-encoded decrypted SMK, which can now be used to decrypt the pwdhash.
Since MSSQL Server 2012, the Service Master Key is used with AES for encryption ( 3DES was used before) . We can then decrypt the credentials using the following parameters:
The
IVis the first 16 bytes ofpwdhash(after padding)The
Ciphertextis the remaining bytes frompwdhashThe
Keyis theService Master Key
Instead of doing this manually, we can split the pwhash using the following SQL query
We can finally use this CyberChef recipe to decrypt pwdhash !
Automated - Get-MSSQLLinkPasswords
We can automate this process with the Get-MSSQLLinkPasswords (Powershell) script. It should be run as a Local Administrator with a sysadmin role on the SQL Server instance.
Resources
Last updated
Was this helpful?