SBN

SCCM Exploitation: Account Compromise Through Automatic Client Push & AD System Discovery 

Author: Marshall Price, Senior Security Consultant

TL;DR: The following conditions can lead to compromise of the SCCM client push account and SCCM machine account. Due to the permissions these accounts hold, this can lead to SCCM site takeover or in the case of the SCCM push account, administrative privileges over numerous computer objects within the domain.

  • The ability to create DNS records as a low-privilege user (default).
  • Join a computer to the domain (10 by default).
  • SCCM deployment configured to allow connections to fall back to NTLM or missing hotfix KB15599094.
  • Enablement of automatic site-wide client push installation and Active Directory system discovery.

Introduction

Over the last few years, a tremendous amount of research within the System Center Configuration Manager (SCCM) ecosystem has been accomplished, resulting in the identification and, ultimately, the remediation of multiple vulnerabilities or misconfigurations. Professionals such as Chris Thompson (@_Mayyhem), Matt Nelson (@enigma0x3), Duane Michael (@subat0mik), Garret Foster (@garrfoster) and many others have released blog posts and tools that have expanded our knowledge in this arena and provided valuable mechanisms to identify and remediate these vulnerabilities which have most certainly resulted in a more secure environment for clients. 

Of particular interest, a blog post by Chris Thompson, titled “Coercing NTLM Authentication from SCCM” identified and provided a road map towards abusing SCCM’s automatic site-wide client push functionality when “Allow fallback to NTLM authentication” is enabled and heartbeat discovery is in use. This blog post does an excellent job detailing what information SCCM uses to create a Data Discovery Record (DDR) which is, in turn, used by the SCCM site to determine whether to attempt to install a client on the host. As mentioned in this post, one property that is looked at is the “Operating System Name and Version.” This is important and the reason will become apparent shortly.

In this blog post, Chris Thompson mentions other discovery methods, specifically referencing “Active Directory System Discovery,” but follows up by explaining that he hadn’t found a way to force automatic client push installation via Active Directory System Discovery. This sparked my curiosity and resulted in further research. I’ve identified a technique to abuse this configuration to coerce the SCCM client push account to authenticate to an arbitrary host without needing access to any SCCM client nor administrative access within the domain.

The Journey

Jumping into this journey, my first impulse was to create a DNS record pointing towards my “attack machine” and a corresponding computer account using the tools addcomputer.py from the Impacket library and dnstool.py from krbrelayx toolkit. Of course, this didn’t work. A quick peek into the adsysdis log within the “Program Files/Microsoft Configuration Manager/Logs” directory shows exactly why.

As we can see, the operatingSystem, operatingSystemVersion, and dNSHostName attributes are not configured on the computer object. Populating the dNSHostName property is easily accomplished. addcomputer.py defaults to using the SAMR method. When this method is used, this attribute will not be populated. However, if the “-ldaps” flag is passed, this tool will connect via LDAPS, and this attribute will be populated. The operatingSystem and operatingSystemVersion attributes will not be filled out. As mentioned by Chris, the machine account creator does not have write permissions to these values. I confirmed this by adding these attributes to the “ucd” section of the addcomputer.py script, but when run with a low-privileged user, I received an error message indicating a “constraintViolation” had taken place. Executing this with a domain admin account was successful, indicating this is a permission issue. Peering into this attribute’s properties with Active Directory Administration Center, shows the account creator does not hold write privileges.

Interestingly, neither SELF nor the computer account held write permissions over this attribute, either.

This became my challenge: How could I create a computer account with these values populated and a DNS record pointing to a machine I control? The answer I found was in the “domain join” process. A low-privileged domain account can, by default, join up to ten workstations to a domain. Armed with that information and access to a low-privileged, regular domain user, this became my attack path.

The Attack Path

1. Create a DNS record for an arbitrary hostname which resolves to my attack machine.

a. This is done first so that if subsequent events result in a dynamic DNS update, my low-privileged user will still control

the DNS record, and I can simply modify it back using that account.

$ python3 dnstool.py -u '<domain\user>' -p '<PASSWORD> -r <desired.fqdn> -a add -t A -d <desired_ip> <dc-ip>

2. Start your NTLM relay or NTLM capture tool.

a. In this demonstration, I am using Responder in analyze mode. Active Directory System Discovery, by default, updates

every 5 minutes. As we have no way to identify when this is happening, this tool should be prepared and ready.

3. Join a real Windows virtual machine to the domain using low-privileged credentials with a computer name matching

this DNS record.

a. This virtual machine could be tunneled or proxied through another host on the network using your C2 framework or

tunneling tool of choice.

4. Authenticate to the newly joined Windows VM using the user it was joined with and delete SPNs associated with this machine

account to force fallback to NTLM.

a. In this step, we are removing the HOST SPN for the machine account of the computer we joined.

b. While researching this problem, I reached out to my friend and coworker, Connor Dowling. He provided this method of

“breaking Kerberos.” After finishing my research, I learned this technique was also used in the blog post “Push Comes to

Shove: Bypassing Kerberos Authentication of SCCM Client Push Accounts” by Brandon Colley(@TechBrandon) of Trimarc

Security. After following up with part one and part two of his blog series, I’ve realized that these blogs touch very closely

on the technique I’m discussing here. As such, I believe this technique is a continuation or clarification of work already

accomplished by Brandon.

setspn -D host/ComputerName ComputerName

setspn -D host/ComputerName.FullyQualified.Domain ComputerName

Wait for AD System Discovery to identify this account and create a DDR for this within SCCM. The resulting client push should happen soon after, leading to the harvesting or capture of credentials.

c. Note: I am using Responder in analyze mode to capture this hash with the following command:

python3 Responder.py -I eth0 -Av

d. In this demo, the resultant hash is NTLMv1. My lab is currently, purposefully misconfigured in a vulnerable state to

evaluate vulnerabilities associated with NTLMv1. In other environments, it may be NTLMv2.

e. As depicted in the image below, we will receive authentication attempts from both the client push account and the

SCCM machine account. The former is more than likely a local administrator over many machines in an environment, and

the latter can be relayed to the MSSQL database in some scenarios to affect an SCCM site takeover.

So why does this work, and what’s happening behind the scenes?

Digging into SCCM Active Directory System Discovery is the best place to start. By default, this functionality is not enabled; however, if an organization elects to enable this feature, its default setting is to perform a full poll of whatever Active Directory path is configured every seven days. Between these full polls, it completes a “Delta discovery” update, which is when it identifies new or recently updated resources every five minutes.

Caveat – Depending on what Active Directory LDAP “path” an organization sets as the starting point for system discovery, it may not discover the newly created computer account. For example, if newly joined machines are added to the “Computers” container but that path starts in a lower sub-container, this delta discovery may not discover the account.

If we examine the adsysdis log once more, we now see this device was successfully discovered and a DDR created.

Investigating the ccm log within the “Program Files/Microsoft Configuration Manager/logs” directory, we can identify authentication attempts towards the FQDN and the NetBIOS name of our created computer using the SCCM client push and machine account.

These connection attempts are using NTLM because this SCCM deployment is configured to allow connection fallback to NTLM. This could also happen if this were an old installation of SCCM and the requisite hotfix was not applied. Removing the SPNs associated with our created computer account ensures this will happen.

What was passed to fill the Operating System and Version property within SCCM? If we examine the computer object using the PowerShell “Get-ADComputer” cmdlet provided by RSAT, we can identify what Active Directory recorded versus what is contained within SCCM.

Looking at the computer properties within the Configuration Management console shows us exactly what Chris Thompson identified in his article, which is “Microsoft Windows NT Workstation <Version>.”

What is the impact?

The impact of this attack is similar to previously identified SCCM Client Push NTLM relay attacks. As the client push account is required to be a local administrator for any device on which client install is desired, this account is often local administrator over a great deal of assets. Additionally, if the machine account is relayed this could lead to site takeover. If the prerequisite configuration within SCCM is present, namely, automatic site-wide client push is enabled, Active Directory System Discovery is enabled with default options, and low-privileged users can join ten machines to the domain, an attacker could go from low-privileged credentials to controlling the SCCM client push account at a bare minimum within 5-10 minutes.

How do we mitigate?

Aside from the recommendations that will apply to NTLM relaying abuse, such as SMB Signing configured on all assets, Extended Protection for MSSQL and HTTPS, and LDAP signing/LDAPS channel binding, the recommendations below will help prevent this attack technique:

  • Hotfix KB15599094 – This update should be installed, and “Allow connection fallback to NTLM” should be disabled. For new installations, this option should not be enabled. This update prevents fallback to NTLM when WMI queries are executed during the client installation phase and supersedes hotfix KB15498768 which also fixes a condition in which connections would fallback to NTLM when Kerberos fails regardless of whether “Allow connection fallback to NTLM” was disabled.
  • Consider disabling automatic site-wide client push installation.
  • Set the MS-DS-Machine-Account-Quota value to zero for all users except specific accounts required to join/create computer accounts.
  • Ensure that the SCCM Client push account is not over-privileged. This account should not be a Domain Admin or within the built-in administrator group for computers that do not need Client Push installation.

How can we detect?

  • Monitor authentication logs for authentication attempts (success/failure) by the SCCM client push account against any workstation/server that shouldn’t require an SCCM client installation.
  • For environments that cannot immediately disable automatic site-wide client push installation and are using AD system discovery, the adsysdis and ccm log can be ingested into a SIEM and used to create and monitor dashboards or threat hunt for new DDR creation and subsequent authentication attempts resulting for automatic client push.
  • Client push accounts are used to authenticate to services other than SMB.

What’s next?

We are continuing research into this attack path, particularly on methods to create a DDR with the Operating System and Version property filled. I’m personally working to better understand how these properties get populated within Active Directory when a computer is joined versus when a machine account is created through something like Impacket addcomputer.py. My research thus far indicates that the creator and the machine account itself do not have write permissions to these attributes, so it is unclear how they get populated. In the meantime, GuidePoint Security is continuing to identify SCCM misconfigurations during our assessments, so keep an eye out for further posts on this subject.

Tools used in research or attack

  • Impacket addcomputer.py – Used to create a computer account within Active Directory.
  • krbrelayx dnstool.py – Used to create or modify a DNS record within Active Directory DNS services.
  • sccmhunter – A huge source of inspiration for this research. sccmhunter’s ability to use the SCCM Management Point’s http endpoint to register a new device and retrieve NAA credentials, along with Chris Thompson’s blog on coercing NTLM authentication through client push, provided the impetus that drove my desire to research and learn about this subject.
  • Ludus – The easiest way to deploy dev/test infrastructure.
  • GOAD – Game of Active Directory Automated AD lab is an incredible resource for standing up a vulnerable AD environment. This lab formed the base of my Active Directory lab for this demonstration, which included SCCM built within this environment.
  • SharpSCCM – This is an incredible tool for identifying and abusing SCCM misconfigurations. This tool and the accompanying research are valuable for any security practitioner involved in securing SCCM.
  • Setspn.exe – Used to break Kerberos authentication by removing the HOST SPN from the account, forcing the fallback to NTLM.

Resources

*** This is a Security Bloggers Network syndicated blog from The Guiding Point | GuidePoint Security authored by GuidePoint Security. Read the original post at: https://www.guidepointsecurity.com/blog/sccm-exploitation-account-compromise-through-automatic-client-push-amp-ad-system-discovery/