
A python tool to map the access rights of network shares into a BloodHound OpenGraphs easily
A tool to map the access rights of network shares into BloodHound OpenGraphs.
Read the associated blog post: https://specterops.io/blog/2025/10/30/sharehound-an-opengraph-collector-for-network-shares/
This repository contains two implementations of ShareHound. They share the same goal — producing BloodHound OpenGraph JSON from SMB share permissions — but differ in language, runtime, and feature set. Pick whichever fits your workflow.
| Implementation | Path | Author | Best for |
|---|---|---|---|
| Python | Python/ | Remi Gascou (@podalirius_) @ SpecterOps | The reference implementation; easy to extend and script |
| Go | Go/ | Javier Azofra @ Siemens Healthineers | Large-scale scans (60,000+ hosts), checkpointing, static binaries |
Each subdirectory has its own README with full installation, usage, and configuration details:
--effective-access-only mode to drastically reduce graph size on large environmentsOnce you've imported the OpenGraph into BloodHound, these queries cover the most common needs. For more, see the per-implementation READMEs.
MATCH (p)-[r]->(s:NetworkShareSMB)
WHERE (p)-[:CanDelete]->(s)
AND (p)-[:CanDsControlAccess]->(s)
AND (p)-[:CanDsCreateChild]->(s)
AND (p)-[:CanDsDeleteChild]->(s)
AND (p)-[:CanDsDeleteTree]->(s)
AND (p)-[:CanDsListContents]->(s)
AND (p)-[:CanDsListObject]->(s)
AND (p)-[:CanDsReadProperty]->(s)
AND (p)-[:CanDsWriteExtendedProperties]->(s)
AND (p)-[:CanDsWriteProperty]->(s)
AND (p)-[:CanReadControl]->(s)
AND (p)-[:CanWriteDacl]->(s)
AND (p)-[:CanWriteOwner]->(s)
RETURN p,r,s
MATCH x=(p)-[r:CanWriteDacl|CanWriteOwner|CanDsWriteProperty|CanDsWriteExtendedProperties]->(s:NetworkShareSMB)
RETURN x
MATCH p=(h:NetworkShareHost)-[:HasNetworkShare]->(s:NetworkShareSMB)-[:Contains*0..]->(f:File)
WHERE toLower(f.name) = toLower("flag.txt")
RETURN p
MATCH p=(h:NetworkShareHost)-[:HasNetworkShare]->(s:NetworkShareSMB)-[:Contains*0..]->(f:File)
WHERE toLower(f.extension) = toLower(".vmdk")
RETURN p
CanEffectiveRead / CanEffectiveWrite / CanEffectiveExecute edges are emitted
by the Go implementation when the same SID has matching rights at both the share
and NTFS levels — i.e. the real access granted over SMB.
MATCH p=(principal)-[:CanEffectiveRead]->(f:File)
RETURN p
Pull requests are welcome for either implementation. Open an issue if you want to discuss a new feature first.