Skip to content

BloodHound — Blue Team Usage

¿Cómo usa el Blue Team BloodHound?

BloodHound no es solo una herramienta ofensiva. Los defensores pueden usarlo para identificar misconfigurations antes de que un atacante las explote, monitorear cambios en AD, y crear planes de remediación concretos.

Cosas a monitorear regularmente:

Administradores con sesiones en hosts que no son DCs
Privilegios peligrosos en el grupo Domain Users
Rutas desde usuarios Kerberoasteables hacia DA
Usuarios con privilegios elevados sobre computadoras
Usuarios sin pre-autenticación (ASREPRoasteables)
Usuarios con más sesiones activas de lo normal

Herramientas


BlueHound — Automatización de análisis defensivo

BlueHound automatiza el ciclo completo de recolección, análisis y reporte usando datos de BloodHound. Permite crear dashboards personalizados con queries Cypher sin escribir código.

Instalación y arranque

c
# Descomprimir
Expand-Archive .\BlueHound-win32-x64-1.1.0.zip .

# Ejecutar BlueHound.exe
# Login con credenciales de Neo4j
# usuario: neo4j
# password: Password123

Configuración de SharpHound como fuente de datos

  1. Data Import → deshabilitar todo excepto SharpHound
  2. Edit Settings → Tool path: C:\Tools\SharpHound.exe
  3. Configurar argumentos de SharpHound
  4. Opcional: programar recolección automática (diaria, semanal, mensual)

Configuración básica de BlueHound

Ir a la pestaña Configurations y definir:

Domain Controllers  → DOMAIN CONTROLLERS@INLANEFREIGHT.HTB
Domain Admins Group → DOMAIN ADMINS@INLANEFREIGHT.HTB
Crown Jewels        → SRV01.INLANEFREIGHT.HTB (servidores críticos)

Ejecutar todos los reportes

Query Runner → RUN ALL

Crear query personalizada en BlueHound

c
# Contar usuarios habilitados
MATCH (u:User {enabled:true})
RETURN COUNT(u)

Clic en + → definir nombre → seleccionar tipo y tamaño → ingresar query → guardar.

Importar dashboard personalizado

  1. Import Config → seleccionar archivo .json
  2. Completar la configuración (Domain Controllers, Domain Admins, Crown Jewels)
  3. Cerrar y reabrir BlueHound
  4. Query Runner → RUN ALL

PlumHound — Identificar qué relación eliminar para romper rutas de ataque

PlumHound envuelve las queries de Neo4j en reportes consumibles por equipos de operaciones. Su función más útil para defensores es el Path Analyzer que indica exactamente qué relación hay que eliminar para romper una ruta de ataque.

Instalación

c
cd C:\Tools\PlumHound
python -m pip install -r requirements.txt

# Verificar que funciona
python PlumHound.py --easy -p Password123

Path Analyzer — romper rutas de ataque

c
# Identificar qué relación eliminar entre dos nodos
python PlumHound.py -p Password123 -ap "DOMAIN USERS@INLANEFREIGHT.HTB" "WS01.INLANEFREIGHT.HTB"

# Otro ejemplo
python PlumHound.py -p Password123 -ap "DAVID@INLANEFREIGHT.HTB" "DOMAIN ADMINS@INLANEFREIGHT.HTB"

La salida indica el edge y los nodos involucrados que hay que modificar para cortar el camino. Por ejemplo:

Removing the relationship GpLink between SCREENSAVER@INLANEFREIGHT.HTB and WORKSTATIONS@INLANEFREIGHT.HTB breaks the path!

Cuidado: no todas las recomendaciones son seguras. Por ejemplo, remover un DC del contenedor Domain Controllers rompe la ruta pero también rompe el funcionamiento del DC.


Queries Cypher defensivas útiles

c
# Usuarios habilitados sin MFA (sin smartcard)
MATCH (u:User {enabled:true, smartcardrequired:false})
WHERE u.admincount = true
RETURN u.name

# Grupos con miembros foráneos (usuarios de otros dominios)
MATCH (u:User)-[:MemberOf]->(g:Group)
WHERE u.domain <> g.domain
RETURN u.name, g.name

# Computadoras con más de X admins locales
MATCH (c:Computer) OPTIONAL MATCH (u1:User)-[:AdminTo]->(c)
OPTIONAL MATCH (u2:User)-[:MemberOf*1..]->(:Group)-[:AdminTo]->(c)
WITH COLLECT(u1) + COLLECT(u2) AS admins, c
UNWIND admins AS a
RETURN c.name, COUNT(DISTINCT(a)) AS admin_count
ORDER BY admin_count DESC

# Domain Admins con sesiones fuera de los DCs
MATCH (u:User)-[:MemberOf*1..]->(g:Group {name:"DOMAIN ADMINS@INLANEFREIGHT.HTB"})
MATCH (u)-[:HasSession]->(c:Computer)
WHERE NOT c.name CONTAINS "DC"
RETURN u.name, c.name

# GPOs con permisos de escritura para usuarios no admin
MATCH p=(u:User)-[r:GenericWrite|WriteDacl|WriteOwner|GenericAll]->(g:GPO)
WHERE u.admincount = false
RETURN u.name, g.name, type(r)