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.
PTaaS is NetSPI’s delivery model for penetration testing. It enables customers to simplify the scoping of new engagements, view their testing results in real time, orchestrate faster remediation, perform always-on continuous testing, and more - all through the Resolve™ vulnerability management and orchestration platform.
We help organizations defend against adversaries by being the best at simulating real-world, sophisticated adversaries with the products, services, and training we provide. We know how attackers think and operate, allowing us to help our customers better defend against the threats they face daily.
At NetSPI, we believe that there is simply no replacement for human-led manual deep dive testing. Our Resolve platform delivers automation to ensure our people spend time looking for the critical vulnerabilities that tools miss. We provide automated and manual testing of all aspects of an organization’s entire attack surface, including external and internal network, application, cloud, and physical security.
Our proven methodology ensures that the client experience and our findings aren’t only as good as the latest tester assigned to your project. That consistency gives our customers assurance that if vulnerabilities exist, we will find them.