There is no shortage of dependable control channels or RATs these days, but I thought it would be a fun side project to develop one that uses SQL Server. In this blog, I’ll provide an overview of how to create and maintain access to an environment using SQL Server as the controller and the agent using a new PoC script called SQLC2.
It should be interesting to the adversarial simulation, penetration testing, red, purple, blue, and orange? teams out there looking for something random to play with. Did I miss any marketing terms?
Why SQL Server?
Well, the honest answer is I just spend a lot of time with SQL Server and it sounded fun. However, there are practical reasons too. More companies are starting to use Azure SQL Server databases. When those Azure SQL Server instances are created, they are made accessible via a subdomain of “*.database.windows.net” on port 1433. For example, I could create an SQL Server instance named “mysupersqlserver.database.windows.net”. As a result, some corporate network configurations allow outbound internet access to any “*.database.windows.net” domain on port 1433.
So, the general idea is that as Azure SQL Server adoption grows, there will be more opportunity to use SQL Server as a control channel that looks kind of like normal traffic .
SQLC2 is a PowerShell script for deploying and managing a command and control system that uses SQL Server as both the control server and the agent.
Basic functionality includes:
Configuring any SQL Server to be a controller
Installing/Uninstalling PowerShell and SQL Server based SQLC2 agents on Windows systems
At its core, SQLC2 is just a few tables in an SQL Server instance that tracks agents, commands, and results. Nothing too fancy, but it may prove to be useful on some engagements. Although this blog focuses on using an Azure SQL Server instance, you could host your own SQL Server in any cloud environment and have it listen on port 443 with SSL enabled. So, it could offer a little more flexibility depending on how much effort you want to put into it.
Naturally, SQLC2 was built for penetration test and red team engagements but be aware that for this release I didn’t make a whole lot of effort to avoid blue team detection. If that’s your goal, I recommend using the “Install-SQLC2AgentLink” agent installer instead of “Install-SQLC2AgentPs”. The link agent operates almost entirely at the SQL Server layer and doesn’t use any PowerShell so it’s able to stay under the radar more than the other supported persistence methods.
Below is a diagram illustrating the SQLC2 architecture.
For those who are interested, below I’ve provided an overview of the Azure setup, and a walkthrough of the basic SQLC2 workflow. Enjoy!
The SQLC2 controller can be installed on any SQL Server by creating two tables within the provided database. That database will then be used in future commands to check-in agents, download commands, and upload command results.
Below is the command to setup the SQLC2 tables in a target SQL instance.
Once agents and commands have been processed the actual C2 tables will simply store the data. You can also connect directly to your Azure SQL Server with SQL Server Management Studio to view the results as well. Below is an example screenshot.
SQLC2: Installing C2 Agents
SQLC2 supports three methods for installing and running agents for downloading and executing commands from the C2 server.
Direct Execution: Executing directly via the Get-SQLC2Command
Windows Schedule Task: Installing an SQLC2 PowerShell agent to run via a scheduled task that runs every minute.
SQL Server Agent Job: Installing an SQLC2 SQL Server agent job that communicates to the C2 server via a server link.
Option 1: Direct Execution
You can list pending commands for the agent with the command below. All Get-SQLC2Command execution will automatically register the agent with the C2 server.
The examples above show how to run SQLC2 commands manually. However, you could have any persistence method load SQLC2 and run these commands to maintain access to the environment.
Option 2: Windows Scheduled Task
Installing an SQLC2 PowerShell agent to run via a scheduled task that runs every minute. Note: Using the -Type parameter options you can also install persistence via “run” or “image file execution options” registry keys.
To send a command to a specific agent, you can use the command below. Please note that in this release the agent names are either the computer name or sql server instance name the agent was installed on. Below are a few command examples showing a registered agent and issuing a command to it.
The PowerShell commands and agents should show up in your PowerShell logs which can be a useful data source.
The persistence methods for tasks, registry run keys, and “image file execution options” registry keys can all be audited, and alerts can be configured. The commands used to create the persistence also tend to generate Windows event logs can all be useful and most Endpoint Detection and Response solutions can identify the commands at execution time.
If possible, deploy audit configurations to internal SQL Servers to help detect rogue agent jobs, ad-hoc queries, and server links. I have some old examples of logging options here. If configured correctly they can feed alert directly into the Windows event log.
Although it’s harder than it sounds, try to understand what’s normal for your environment. If you can restrict access to “*.database.windows.net” to only those who need it, then it can be an opportunity to both block outbound access and detect failed attempts. Network and DNS logs can come in handy for that.
SQLC2 is a pretty basic proof of concept, but I think it’s functional enough to illustrate the idea. Eventually, I’ll likely role it into PowerUpSQL for the sake of keeping the offensive SQL Server code together. At that point, maybe I’ll also role in a few CLR functions to step it up a bit. In the meantime, for those of you looking to explore more offensive cloudscape options, check out Karl Fosaaen’s blog on other Azure services that can be useful during red team engagements. It’s pretty interesting.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
YouTube session cookie.
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.
Discover how NetSPI ASM solution helps organizations identify, inventory, and reduce risk to both known and unknown assets.