A PowerShell collector for adding SCCM attack paths to BloodHound with OpenGraph by Chris Thompson at SpecterOps
Check out the introductory blog post here: https://specterops.io/blog/2026/01/13/introducing-configmanbearpig-a-bloodhound-opengraph-collector-for-sccm/
Please hit me up on the BloodHound Slack (@Mayyhem), Twitter (@_Mayyhem), or open an issue if you have any questions I can help with!
- Overview
- System Requirements
- Limitations
- Usage Info
- Command Line Options
- Future Development
- SCCM Nodes Reference
- SCCM Edges Reference
- LocalAdminRequired
- CoerceAndRelayToAdminService
- CoerceAndRelayToMSSQL
- CoerceAndRelaytoSMB
- HasSession
- MSSQL_Contains
- MSSQL_ControlDB
- MSSQL_ControlServer
- MSSQL_ExecuteOnHost
- MSSQL_GetAdminTGS
- MSSQL_GetTGS
- MSSQL_HasLogin
- MSSQL_HostFor
- MSSQL_IsMappedTo
- MSSQL_MemberOf
- MSSQL_ServiceAccountFor
- SameHostAs
- SCCM_AdminsReplicatedTo
- SCCM_AllPermissions
- SCCM_ApplicationAdministrator
- SCCM_AssignAllPermissions
- SCCM_AssignSpecificPermissions
- SCCM_Contains
- SCCM_FullAdministrator
- SCCM_HasADLastLogonUser
- SCCM_HasClient
- SCCM_HasCurrentUser
- SCCM_HasMember
- SCCM_HasNetworkAccessAccount
- SCCM_HasPrimaryUser
- SCCM_HasStoredAccount
- SCCM_IsAssigned
- SCCM_IsMappedTo
Collects BloodHound OpenGraph compatible data and creates a zip in the current directory
- Example:
sccm-bloodhound-20251020-115610.zip
ConfigManBearPig follows these ordered steps when run without arguments:
- LDAP (identify sites, site servers, fallback status points, and management points in System Management container)
- Local (identify management points and distribution points in logs when running this script on an SCCM client)
- DNS (identify management points published to DNS)
- *DHCP (identify PXE-enabled distribution points and management points in boot media)
- Remote Registry (identify site servers, site databases, and current users on targets)
- MSSQL (check database servers for Extended Protection for Authentication)
- AdminService (collect information from SMS Providers with privileges to query site information)
- *WMI (if AdminService collection fails)
- HTTP (identify management points, distribution points, and SMS Providers via exposed web services)
- SMB (identify site servers and distribution points via file shares)
*Work in progress
- PowerShell 4.0 or higher
- Active Directory domain context with line of sight to a domain controller
- Various permissions based on collection methods used
- You MUST include the 'MSSQL' collection method to remotely identify EPA settings on site database servers with any domain user (or 'RemoteRegistry' to collect from the registry with admin privileges on the system hosting the database).
- SCCM hierarchies don't have their own unique identifier, so the site code for the site that data is collected from is used in the identifier for objects (e.g., SMS00001@PS1), preventing merging of objects if there are more than one hierarchy in the same graph database (e.g., both hierarchies will have the SMS00001 collection but different members), but causing duplicate objects if collecting from two sites within the same hierarchy.
- If the same site code exists more than once in the environment (Microsoft recommends against this, so it shouldn't), the nodes and edges for those sites will be merged, causing false positives in the graph. This is not recommended within the same forest: https://learn.microsoft.com/en-us/intune/configmgr/core/servers/deploy/install/prepare-to-install-sites#bkmk_sitecodes
- It is assumed in some cases (e.g., during DP and SMS Provider collection) that a single system does not host site system roles in more than one site. If this is the case, only one site code will be associated with that system.
- CoerceAndRelayNTLMtoSMB collection doesn't work because post-processed AdminTo edges can't be added via OpenGraph yet, so added CoerceAndRelayToSMB edges instead
- MSSQL collection assumes that any collection target hosting a SQL Server instance is a site database server. If there are other SQL Servers in the environment, false positives may occur.
- I'm not a hooking expert, so if you see crashes during MSSQL collection due to the InitializeSecurityContextW hooking method that's totally vibe-coded, disable it. The hooking function doesn't work in PowerShell v7+ due to lack of support for certain APIs.
By default, ConfigManBearPig attempts to run all collection phases against all discovered systems that may be related to SCCM, so you can run the script without any arguments and get as much data as it is capable of collecting in your authentication context. However, I recommend the following options for troubleshooting any issues that might come up:
.\ConfigManBearPig.ps1 -LogFile ConfigManBearPig_output.log -Verbose
To populate the SCCM node glyphs in BloodHound, execute ConfigManBearPig.ps1 -OutputFormat CustomNodes (or copy the following) and use the API Explorer page to submit the JSON to the custom-nodes endpoint.
{
"custom_types": {
"SCCM_ClientDevice": {
"icon": {
"color": "#f59b42",
"name": "desktop",
"type": "font-awesome"
}
},
"SCCM_Collection": {
"icon": {
"color": "#fff82e",
"name": "sitemap",
"type": "font-awesome"
}
},
"MSSQL_Database": {
"icon": {
"color": "#f54242",
"name": "database",
"type": "font-awesome"
}
},
"MSSQL_ServerRole": {
"icon": {
"color": "#6942f5",
"name": "users-gear",
"type": "font-awesome"
}
},
"SCCM_AdminUser": {
"icon": {
"color": "#558eea",
"name": "user-gear",
"type": "font-awesome"
}
},
"MSSQL_DatabaseUser": {
"icon": {
"color": "#f5ef42",
"name": "user",
"type": "font-awesome"
}
},
"MSSQL_DatabaseRole": {
"icon": {
"color": "#f5a142",
"name": "users",
"type": "font-awesome"
}
},
"MSSQL_Server": {
"icon": {
"color": "#42b9f5",
"name": "server",
"type": "font-awesome"
}
},
"MSSQL_Login": {
"icon": {
"color": "#dd42f5",
"name": "user-gear",
"type": "font-awesome"
}
},
"SCCM_Site": {
"icon": {
"color": "#67ebf0",
"name": "city",
"type": "font-awesome"
}
},
"SCCM_SecurityRole": {
"icon": {
"color": "#9852ed",
"name": "users-gear",
"type": "font-awesome"
}
}
}
}
For the latest and most reliable information, please execute ConfigManBearPig with the -Help flag.
| Option ______________________________________________ |
Values _______________________________________________________________________________________________ |
|---|---|
-Help <switch> |
Display usage information |
-CollectionMethods <string> |
Collection methods to use (comma-separated): • All (default): All SCCM collection methods • LDAP • Local • DNS • DHCP • RemoteRegistry • MSSQL • AdminService • WMI • HTTP • SMB |
-ComputerFile <string> |
Specify the path to a file containing computer targets (limits to Remote Registry, MSSQL, AdminService, HTTP, SMB) |
-Computers <string> |
List of computer targets (comma-separated) |
-SMSProvider <string> |
Specify a specific SMS Provider to collect from (limits to AdminService, WMI) |
-SiteCodes <string> |
Specify site codes to use for DNS collection (file path or comma-separated string) |
-OutputFormat <string> |
• Zip: OpenGraph implementation that collects data in separate files for each MSSQL server, then zips them up and deletes the originals. The zip can be uploaded to BloodHound by navigating to Administration > File Ingest• CustomNodes: Generate JSON to POST to custom-nodes API endpoint |
-TempDir <string> |
Specify the path to a temporary directory where .json files will be stored before being zipped Default: new directory created with [System.IO.Path]::GetTempPath() |
-ZipDir <string> |
Specify the path to a directory where the final .zip file will be stored • Default: current directory |
-LogFile <string> |
Specify the path to a log file to write script log to |
-MemoryThresholdPercent <uint> |
Maximum memory allocation limit, after which the script will exit to prevent availability issues • Default: 95 |
-Domain <string> |
Specify a domain to use for name and SID resolution |
-DomainController <string> |
Specify a domain controller FQDN/IP to use for name and SID resolution |
| -DisablePossibleEdges (switch) | • Off: Collect the following edges (useful for offensive engagements but prone to false positive edges that may not be abusable): • CoerceAndRelayToMSSQL By default, EPA setting is assumed to be Off if the MSSQL server can't be reached • SameHostAs/SCCM_HasClient By default, domain computers with the CmRcService SPN are assumed to be SCCM client devices • SCCM_HasNetworkAccessAccount By default, the NAA is assumed to be an enabled account with a valid password • MSSQL_* By default, any targeted MSSQL Server instances are assumed to be site database server • Off: The edges above are not collected |
-FileSizeLimit <string> |
Stop enumeration after all collected files exceed this size on disk • Supports MB, GB • Default: 1GB |
-FileSizeUpdateInterval <uint> |
Receive periodic size updates as files are being written for each server • Default: 5 seconds |
-EnableBadOpsec <switch> |
• Off (default): Do not create edges that launch cmd.exe/powershell.exe or access SYSTEM DPAPI keys on the system where ConfigManBearPig is executed (e.g., to dump and decrypt the NAA username) • On: Create the edges above (WILL be detected by EDR/AV solutions) |
-ShowCleartextPasswords <switch> |
• Off (default): Do not decrypt or display cleartext passwords • On: Display cleartext passwords when they are discovered |
-Help <switch> |
Display usage information |
-Version <switch> |
Display version information and exit |
- Edge entity panels with abuse info
- altauth to allow collection when client cert is required
- Get members of groups with permissions on System Management container
- Parse task sequences and collection variables for usernames and passwords during Local collection
- Automatic client push installation detection (ELEVATE-2)
- Identify site database service account via RemoteRegistry + SPNs
- Relay management point computer accounts to site databases
- Secondary site databases
- Group and user collection members
- DHCP Collection (requires unauthenticated network access)
- WMI Collection (requires an SCCM admin account)
- CMPivot Collection (requires an SCCM admin account)
| Property ______________________________________________ |
Definition _______________________________________________________________________________________________ |
|---|---|
| Name/Label: string | • Format: <domainShortname>\<samAccountName>• Example: • MAYYHEM\DOMAINADMIN |
| Object ID: string | • Format: <domainShortname>\<samAccountName>@<rootSiteCode>• Example: • MAYYHEM\DOMAINADMIN@CAS |
| Collection Source: List<string> | • The collection phase(s) used to populate this entity panel • Example: • AdminService-SMS_Admin |
| Admin ID: uint | • The admin identifier in SCCM • Example: • 16777218 |
| Admin SID: string | • The domain SID of the admin user • Example: • S-1-5-21-3242052782-1287495003-4091326449-1105 |
| Collection IDs: List<string> | • The collections this admin user is assigned • Example: • ['SMS00001@CAS','SMS00004@CAS'] |
| Admin SID: string | • The domain SID of the admin user • Example: • S-1-5-21-3242052782-1287495003-4091326449-1105 |
| Last Modified By: string | • The admin user that last modified this admin user • Format: <domainShortname>\<samAccountName>• Example: • MAYYHEM\DOMAINADMIN |
| Last Modified Date: datetime | • Example: • 2025-11-26T15:52:46.24Z |
| Member Of: List<string> | • The security roles this admin user is assigned • Example: • ['SMS0001R@CAS (Full Administrator)'] |
| Property ______________________________________________ |
Definition _______________________________________________________________________________________________ |
|---|---|
| Name/Label: string | • Format: <samAccountName>@<siteCode>• Examples: • ps1-dev@ps1 |
| Object ID: string | • Format: <smsId>• Examples: • GUID:8BCADD46-7EAD-4767-9D54-06AE64756026 |
| Collection Source: List<string> | • The collection phase(s) used to populate this entity panel • Example: • AdminService-SMS_Admin |
| AAD Device ID: string | • Example: • 20ac5936-4b2f-46a7-8b70-db08ef1f99cd |
| AAD Tenant ID: string | • Example: • 6c12b0b0-b2cc-4a73-8252-0b94bfca2145 |
| AD Domain SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1119 |
| AD Last Logon Time: datetime | • Example: • 2026-01-09T02:37:28Z |
| AD Last Logon User: string | • Example: • domainuser |
| AD Last Logon User Domain: string | • Example: • mayyhem |
| AD Last Logon User SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1104 |
| CN: string | • Example: • PS1-DEV |
| Collection IDs: List<string> | • Example: • ['SMS00001@PS1','SMS000KM@PS1'] |
| CoManaged: bool | true/false |
| Current Logon User: string | • Example: • mayyhem\domainuser |
| Current Logon User SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1104 |
| Current Management Point: string | • Example: • ps1-mp.mayyhem.com |
| Current Management Point SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1118 |
| Device OS: string | • Example: • Microsoft Windows NT Workstation 10.0 (Tablet Edition) |
| Device OS Build: string | • Example: • 10.0.22621.525 |
| Distinguished Name: string | • Example: • CN=PS1-DEV,OU=Workstations,DC=mayyhem,DC=com |
| DNS Hostname: string | • Example: • ps1-dev.mayyhem.com |
| Domain: string | • Example: • 10.0.22621.525 |
| Is Virtual Machine: bool | true/false |
| Last Active Time: datetime | • Example: • 2026-01-13T23:14:34Z |
| Last Offline Time: datetime | • Example: • 2025-12-09T09:02:06.13Z |
| Last Online Time: datetime | • Example: • 2026-01-13T22:50:28.293Z |
| Last Reported MP Server Name: string | • Example: • PS1-MP.MAYYHEM.COM |
| Last Reported MP Server SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1118 |
| Previous SMSID: string | • Example: • GUID:6C25F505-E982-4A0D-8C6E-BFC74992D581 |
| Previous SMSID Change Date: datetime | • Example: • 11/26/2025 19:32:13 |
| Primary User: string | • Example: • mayyhem\domainuser |
| Primary User SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1104 |
| Resource ID: uint | • Format: <resourceId>@<siteCode>• Example: • 16777231@PS1 |
| Site Code: string | • Example: • PS1 |
| SMSID: string | • Example: • GUID:8BCADD46-7EAD-4767-9D54-06AE64756026 |
| Source Site Code: string | • Example: • PS1 |
| User Name: string | • Example: • domainuser |
| User Domain Name: string | • Example: • mayyhem |
| Property ______________________________________________ |
Definition _______________________________________________________________________________________________ |
|---|---|
| Name/Label: string | • Format: <collectionId>• Examples: • SMS00001 |
| Object ID: string | • Format: <collectionId>@<siteCode>• Examples: • SMS00001@PS1 |
| Collection Source: List<string> | • The collection phase(s) used to populate this entity panel • Example: • AdminService-SMS_Admin |
| Collection Type: uint | • 1: User Collection • 2: Device Collection |
| Collection Variables Count: uint | Number of collection variables for this collection |
| Comment: string | Admin-provided comment or description |
| Is Built In: bool | Does the collection ship with SCCM or was it added by the organization? |
| Last Change Time: datetime | • Example: • 2026-01-13T23:14:34Z |
| Last Member Change Time: datetime | • Example: • 2026-01-13T23:14:34Z |
| Member Count: uint | Number of members in this collection |
| Members: List<string> | • Format: <resourceId>@<siteCode>• Example: • ['16777226@PS1','16777219@PS1'] |
| Source Site Code: string | • Example: • PS1 |
| Property ______________________________________________ |
Definition _______________________________________________________________________________________________ |
|---|---|
| Name/Label: string | • Format: <roleId>• Example: • SMS0001R |
| Object ID: string | • Format: <roleId>@<siteCode>• Example: • SMS0001R@PS1 |
| Collection Source: List<string> | • The collection phase(s) used to populate this entity panel • Example: • AdminService-SMS_Admin |
| Created By: string | • Example: • mayyhem\domainadmin |
| Created Date: datetime | • Example: • 2026-01-13T23:14:34Z |
| Is Built In: bool | Does the security role ship with SCCM or was it added by the organization? |
| Is Sec Admin Role: bool | Does the security role allow assignment of any security role to users? |
| Last Modified By: string | • Example: • mayyhem\domainadmin |
| Last Modified Date: datetime | • Example: • 2026-01-13T23:14:34Z |
| Members: List<string> | • Format: <name>@<rootSiteCode>• Example: • ['mayyhem\domainuser@PS1','mayyhem\domainadmin@PS1'] |
| Number of Admins: uint | Number of admins assigned this role |
| Role Description: string | Admin-provided comment or description |
| Role ID: string | • Example: • SMS0001R |
| Role Name: string | • Example: • Full Administrator |
| Site Code: string | • Example: • CAS |
| Property ______________________________________________ |
Definition _______________________________________________________________________________________________ |
|---|---|
| Name/Label | |
| Object ID: string | • Format: <siteCode>• Examples: • PS1 |
| Collection Source: List<string> | • The collection phase(s) used to populate this entity panel • Example: • AdminService-SMS_Admin |
| Build Number: uint | • Example: • 9106 |
| Display Name: string | • Example: • Primary Site One |
| Distinguished Name: string | • Example: • CN=SMS-Site-PS1,CN=System Management,CN=System,DC=mayyhem,DC=com |
| Install Dir: string | • Example: • C:\Program Files\Microsoft Configuration Manager |
| Parent Site Code: string | • Example: • CAS |
| Root Site Code: string | • Example: • CAS |
| Site Code: string | • Example: • PS1 |
| Site GUID: string | • Example: • {5BBD28B5-EF88-44EB-BCC8-725ED8DA08C8} |
| Site Server Domain SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1112 |
| Site Server FQDN: string | • Example: • ps1-pss.mayyhem.com |
| Site Server Name: string | • Example: • ps1-pss.mayyhem.com |
| Site System Roles: List<string> | • Example: • [ps1-mp.mayyhem.com: SMS Management Point@PS1, ps1-dp.mayyhem.com: SMS Distribution Point@PS1] |
| Site Type: string | • Example: • Primary Site |
| Source Forest: string | • Example: • mayyhem.com |
| SQL Database Name: string | • Example: • CM_PS1 |
| SQL Server Domain SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1109 |
| SQL Server FQDN: string | • Example: • ps1-db.mayyhem.com |
| SQL Server Name: string | • Example: • ps1-db.mayyhem.com |
| SQL Service Port: uint | • Example: • 1433 |
| SQL Service Account Domain SID: string | • Example: • S-1-5-21-3242052782-1287495003-4091326449-1116 |
| SQL Service Account Name: string | • Example: • sqlsccmsvc |
| Stored Accounts: List<string> | • Example: • [networkaccess (S-1-5-21-3242052782-1287495003-4091326449-1120), sccm_push (S-1-5-21-3242052782-1287495003-4091326449-1121)] |
| Version: string | • Example: • 5.00.9106.1000 |
This edge is drawn from SCCM site server Computer nodes to Computer nodes hosting site system roles in the same site because the site server's domain computer account MUST be in the local Administrators group on these systems.
This edge has no unique properties.
This edge is drawn from the Authenticated Users group to SCCM_Site nodes that have an SMS Provider that is remote from a site server.
The Coercion Victim and Relay Target Pairs property specifies site servers that can be coerced and remote SMS Providers that can be relayed to in order to conduct the TAKEOVER-5 attack technique.
This edge is drawn from the Authenticated Users group to MSSQL_Login nodes that belong to an SCCM site server that is hosted remotely from the site database when the site database MSSQL server does NOT have EPA set to Required/Allowed.
The Coercion Victim and Relay Target Pairs property specifies site servers that can be coerced and remote site database servers that can be relayed to in order to conduct the TAKEOVER-1 attack technique.
This edge is drawn from the Authenticated Users group to Computer nodes that belong to an SCCM site database or SMS Provider that is hosted remotely from the site server when the system does NOT have SMB signing set to Required.
The Coercion Victim Hostnames property specifies site servers that can be coerced and remote site database and SMS Provider servers that can be relayed to in order to conduct the TAKEOVER-2, TAKEOVER-6, and TAKEOVER-7 attack techniques.
This edge is drawn between Computer and SCCM_ClientDevice nodes that represent the same machine.
This edge has no unique properties.
This edge is drawn between primary sites in the same hierarchy in both directions because global data, including administrative users and security roles, are replicated throughout the hierarchy. Own one site, own them all. It is also drawn from primary sites to their child secondary sites, but only in that direction.
This edge has no unique properties.
This edge is drawn from SCCM_AdminUser nodes that are assigned the All Systems and All Users and User Groups collections and the Full Administrator security role to all SCCM_Site nodes in that hierarchy.
This edge has no unique properties.
This edge is drawn from SCCM_AdminUser nodes that are assigned the Application Administrator security role and any device collection containing the target SCCM_ClientDevice node.
This edge has no unique properties.
This edge is drawn in two places.
First, it is drawn from the site database MSSQL_Database node to the SCCM_Site node for the site it controls.
Second, it is drawn from the Computer node to the SCCM_Site node for each site system role that allows an attacker to compromise the hierarchy by adding an administrative user role assignment, including SMS Providers and site database servers.
This edge has no unique properties.
This edge is drawn from SCCM_Site nodes to SCCM_AdminUser, SCCM_Collection, and SCCM_SecurityRole nodes in the same hierarchy.
This edge has no unique properties.
This edge is drawn from SCCM_AdminUser nodes that are assigned the Full Administrator security role and any device collection containing the target SCCM_ClientDevice node.
This edge has no unique properties.
This edge is drawn from an SCCM_ClientDevice node to the User node representing the principal who was last to log into the device according to Active Directory the last time SCCM ran Active Directory discovery.
This edge has no unique properties.
This edge is drawn from an SCCM_Site node to ALL SCCM_ClientDevice nodes that are members of that primary site.
This edge has no unique properties.
This edge is drawn from an SCCM_ClientDevice node to the User node representing the principal who is currently logged in according to the fast notification service that connects client devices to their management point.
This edge has no unique properties.
This edge is drawn from an SCCM_Collection to the SCCM_ClientDevice nodes it contains.
This edge has no unique properties.
This edge is drawn from a Computer node to each User node representing a network access account that has saved credentials on the host.
This edge has no unique properties.
This edge is drawn from an SCCM_ClientDevice node to the User node representing the principal who is the primary user according to user device affinity relationships in SCCM, which may be manually assigned by an SCCM administrator or automatically assigned when a user is logged on for >40 hours in a month.
This edge has no unique properties.
This edge is drawn from an SCCM_Site node to each User node representing a credential saved in SCCM.
This edge has no unique properties.
This edge is drawn from an SCCM_AdminUser node to the SCCM_Collection and SCCM_SecurityRole nodes it is assigned.
This edge has no unique properties.
This edge is drawn from an AD principal (i.e., a Base node) to the SCCM_AdminUser node it corresponds to in SCCM.
This edge has no unique properties.