
Una herramienta en Python para mapear fácilmente los derechos de acceso de los recursos compartidos de red hacia los OpenGraphs de BloodHound
Una herramienta para mapear los derechos de acceso de los recursos compartidos de red en OpenGraphs de BloodHound.
Lee el artículo de blog asociado: https://specterops.io/blog/2025/10/30/sharehound-an-opengraph-collector-for-network-shares/
Este repositorio contiene dos implementaciones de ShareHound. Ambas comparten el mismo objetivo — generar JSON de OpenGraph de BloodHound a partir de los permisos de recursos compartidos SMB — pero difieren en lenguaje, tiempo de ejecución y conjunto de funciones. Elige la que mejor se adapte a tu flujo de trabajo.
| Implementación | Ruta | Autor | Ideal para |
|---|---|---|---|
| Python | Python/ | Remi Gascou (@podalirius_) @ SpecterOps | La implementación de referencia; fácil de ampliar y automatizar |
| Go | Go/ | Javier Azofra @ Siemens Healthineers | Escaneos a gran escala (60,000+ hosts), puntos de control, binarios estáticos |
Cada subdirectorio tiene su propio README con todos los detalles de instalación, uso y configuración:
--effective-access-only para reducir drásticamente el tamaño del grafo en entornos grandesUna vez que hayas importado el OpenGraph en BloodHound, estas consultas cubren las necesidades más comunes. Para más, consulta los README de cada implementación.
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
Las aristas CanEffectiveRead / CanEffectiveWrite / CanEffectiveExecute son
emitidas por la implementación Go cuando el mismo SID tiene derechos coincidentes
tanto a nivel de recurso compartido como de NTFS, es decir, el acceso real
otorgado a través de SMB.
MATCH p=(principal)-[:CanEffectiveRead]->(f:File)
RETURN p
Las pull requests son bienvenidas para cualquiera de las dos implementaciones. Abre un issue si quieres discutir primero una nueva funcionalidad.