ConfigManBearPig
ConfigManBearPig is a "Python collector for adding SCCM attack paths to BloodHound with OpenGraph."
This was put together by AI using a bunch of troubleshooting I was doing on a live assessment
Prerequisites & Gotchas
Read this first — these are the things that will trip you up if you don't know them going in.
-
BloodHound MUST use the PostgreSQL graph backend, not Neo4j. OpenGraph
SCCM_*/MSSQL_*kinds will not show up in Search/Pathfinding on Neo4j. Switch with bloodhound-cli:./bloodhound-cli config set graph_driver pgSwitching backends starts an empty graph, so you must re-ingest SharpHound/AzureHound/CMBP data afterward.
-
Register the schemas BEFORE trusting query results. If
schema_SCCM.json/schema_MSSQL.jsonaren't uploaded, queries for SCCM/MSSQL edge kinds can return "no results" even when the data exists — a false negative. Register schemas first, then query. -
Python version:
openhoundneeds Python 3.13–3.15. Ifuvcomplains "No interpreter found" or "only system", install and force a managed one:uv python install 3.13 UV_PYTHON_PREFERENCE=managed uv run --python 3.13 openhound ... -
Some saved queries need other collectors' data (the names say so, e.g. "Requires SharpHound Collection", "Requires MSSQLHound Collection"). An empty result on those may just mean you didn't ingest that data — not that there's no attack path.
Install
uv tool install openhound --with configmanbearpig --prerelease=allow
Collect data
uv run openhound collect sccm .\out --run-all -d mayyhem.com --dc dc01.mayyhem.com -u "MAYYHEM\lowpriv" -p "Passw0rd!" -v
On Linux, use ./out and quote/escape the domain-qualified username (e.g. 'MAYYHEM/lowpriv').
Import the schemas
Go into the BloodHound admin web UI and hit Administration > OpenGraph Management. Upload schema_MSSQL.json and schema_SCCM.json.
The schema files ship inside the installed Python package. Find them with:
PKG=$(uv tool run --from configmanbearpig python -c "import openhound_sccm, os; print(os.path.dirname(openhound_sccm.__file__))")
cp "$PKG"/schema_SCCM.json "$PKG"/schema_MSSQL.json ~/
They'll be in ~/ for easy browsing in the upload dialog.
Import the collected data
Upload your collection zip (and your SharpHound/AzureHound data) via Administration > Data Collection > File Ingest > Upload File(s).
If queries later error with failed to translate kinds: unable to map kinds:, upload seed_data.json (in the repo) via File Ingest to populate one instance of each kind.
Import the saved queries
The repo ships ~20 prebuilt Cypher queries (TAKEOVER / CRED / ELEVATE chains, SCCM/MSSQL inventories) in cypher_queries/. These are not bundled with the uv tool install, so grab them from the repo:
git clone https://github.com/SpecterOps/ConfigManBearPig
cd ConfigManBearPig
Uploading them uses openhound searches upload, which talks to the BloodHound API and needs two things in a dlt secrets file: the BloodHound URL and a JWT.
The #1 gotcha: it wants a JWT, NOT a BloodHound API token. Do not create an "API Token" under Administration (that gives you an ID + HMAC key, which this tool does not use — it will fail with
401 Token Authorization failed). Instead, pull the session JWT from your logged-in browser.
1. Get the JWT from your browser
- Log into the BloodHound web UI.
- Open DevTools (F12) → Network tab.
- Run any query / click around so API calls appear, then click a request to
/api/v2/.... - Under Request Headers, find
Authorization: Bearer eyJ.... - Copy only the
eyJ...part — everything afterBearer(noBearer, no leading space).
Browser JWTs are short-lived. If the upload later 401s, your JWT probably expired — grab a fresh one.
2. Create the dlt secrets file
Create ~/.dlt/secrets.toml with exactly this (the JWT goes in the token field):
[destination.bloodhound]
url = "http://localhost:8080"
token = "eyJ...paste-your-JWT-here-no-Bearer..."
Adjust url/port to match your BloodHound instance.
3. Upload
uv run openhound searches upload ./cypher_queries
The queries now appear in BloodHound under Cypher > Saved Queries.
If an upload fails partway through, clear the stuck dlt package before retrying:
uv run --python 3.13 dlt pipeline bloodhound_searches drop-pending-packages
Run the queries
With the schemas registered, data ingested, and the PostgreSQL backend in use, run the saved queries from Cypher > Saved Queries. Suggested order:
SCCM Infrastructure/SCCM Sites— confirm the graph populated (your site should render with proper SCCM node icons).SCCM Shortest TAKEOVER Pathand theSCCM Hierarchy TAKEOVER-1…-9set — the takeover / coerce-and-relay paths. These surface relay-to-SMB / relay-to-MSSQL / relay-to-AdminService edges (drawn when SMB signing is off, EPA isn't required, etc.).SCCM CRED-*and the NAA / stored-account queries — credential-access paths and any Network Access Account identities.
Trust empty results only after the schemas are registered. Before registration, an unregistered edge kind can return "no results" even when the path exists.