
Detección consciente de la puntuación de rutas de ataque de BloodHound: la ruta más silenciosa hacia tu objetivo, calibrada en cinco niveles de detección (auditoría/EDR/Elastic/MDI/WDAC) más Azure.
BloodHound (y PlumHound sobre él) encuentra una ruta hacia el objetivo. NoiseHound ingiere los mismos datos de grafo y re-clasifica las rutas según el coste de detección esperado en lugar del número de saltos, de modo que un operador pueda preguntar "cuál es la forma más silenciosa de llegar a Domain Admin" en lugar de solo "cuál es una forma".
¿Nuevo aquí? El Tutorial para operadores es la forma más rápida de ver qué hace esto - un recorrido práctico guiado por capturas de pantalla desde la instalación hasta una prueba de concepto en vivo con BloodHound CE (puntuaciones escritas de vuelta en la interfaz), el motor DeadAir y el informe de brechas de detección del equipo azul.
Estado del proyecto (v1.2.0): estable y probado con datos reales de BloodHound en múltiples dominios. 37 de los 77 bordes del corpus están medidos en laboratorio en cinco niveles de detección on-prem (auditoría de Windows, Defender for Endpoint, Elastic SIEM, alertas de runtime de Defender for Identity y auditoría de WDAC) más un nivel medido de Azure/Entra
- distribuidos como seis perfiles listos para usar en
profiles/, con prueba de bucle cerrado de que cambian las clasificaciones de rutas (docs/VALIDATION.md). El corpus incluye 13 bordes de Azure/Entra (docs/AZURE.md), ingeribles directamente desde la salida de AzureHound. Los bordes on-prem no medidos y todos los bordes de Azure llevan estimaciones de expertos; el arnés de calibración (noisehound-calibrate) es cómo se miden ellos, y su propio entorno. Trate las clasificaciones no calibradas como una guía bien razonada, no como verdad absoluta.
Solo para compromisos autorizados. Esta herramienta puntúa rutas de ataque para la planificación de OPSEC contra sistemas sobre los que tiene permiso por escrito para probar.
NoiseHound es un proyecto comunitario independiente. No está afiliado con, respaldado por, ni asociado con SpecterOps o el proyecto BloodHound; consume el formato de datos abierto de BloodHound.
.zip), un archivo JSON sin procesar o un directorio
de exportaciones en un grafo interno. También se acepta un formato JSON normalizado {nodes, edges}
para análisis sin conexión y pruebas. Los bordes de escalada ESC1-8 de AD CS
se sintetizan en el momento de la carga a partir de las plantillas de certificado y los hechos de CA
que BloodHound recopila (ver más abajo).effective_noise_score (0-100). Cuando varios derechos conectan el mismo par
de nodos, se elige el más silencioso. Los tipos de borde ausentes del corpus
usan por defecto una puntuación conservadora (60) para que las brechas fallen de forma segura en lugar de
subestimar. Un perfil de entorno opcional ajusta las puntuaciones según la postura de
detección declarada del objetivo (ver más abajo).El ruido de ruta deliberadamente no es una suma simple. Activar la misma detección dos veces no es el doble de ruidoso (triaje del SOC, no recuento bruto de eventos). NoiseHound usa:``` path_score = max(edge_scores) * 0.6 + mean(edge_scores) * 0.4
This weights toward the loudest single step (one bad step often burns the whole
op) while still accounting for cumulative exposure. The weights are configurable
(`--max-weight` / `--mean-weight`) so they can be tuned empirically once real
detection data is available from an APT29/Caldera lab.
Every path also reports a **detection probability** - the chance it trips a
correlated alert - blending the loudest edge with the cumulative noisy-OR of all
edges (tuned by `--correlation`). It answers a different question than the noise
score: a short but loud path can have a *lower* overall probability of being
caught than a long but quiet one. Rank by it with `--rank-by probability`.
### Motor de dos niveles (DeadAir)
Para grafos grandes, la resolución se delega en [DeadAir](https://github.com/warpedatom/DeadAir), un motor
compañero en Rust (el nivel OffsetScan-to-OffsetInspect). NoiseHound sigue siendo el
frontend rico en funciones - ingesta, corpus, entorno/Sigma, restricciones,
informes - y entrega el grafo preparado al motor que lo resuelva, de modo que
los resultados son idénticos en ambos casos.
- `--engine auto` (predeterminado): DeadAir cuando su binario se encuentra *y* el grafo es
grande (>= 5000 nodos); el solucionador Python integrado en caso contrario.
- `--engine python`: fuerza el solucionador integrado (no se necesita binario).
- `--engine rust`: fuerza DeadAir (da error si el binario falta).
DeadAir se localiza mediante `$NOISEHOUND_DEADAIR`, luego `PATH`, y después la compilación
hermana `../deadair/target/{release,debug}/`. Es 10-100x más rápido en grafos grandes
(un grafo de 250k nodos se resuelve en ~2s frente a ~30s en Python) mientras produce clasificaciones
byte-idénticas. La salida registra qué motor se ejecutó.
### Enrutamiento multiobjetivo y con restricciones
El ruido, el número de saltos y la probabilidad de detección tiran en direcciones distintas, por lo que
`--pareto` devuelve la **frontera de Pareto** - cada ruta que ninguna otra supera en
los tres criterios a la vez - en lugar de forzar un único ganador. Y las operaciones reales
tienen restricciones: `--avoid NODE` mantiene una ruta fuera de un host específico (una
caja de salto monitorizada por EDR, un honeypot), y `--avoid-edge TYPE` rechaza una técnica
(p. ej. `--avoid-edge DCSync`). Ambos son repetibles y se resuelven de nuevo sobre la marcha.```bash
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --pareto
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --avoid FILESERVER01 --avoid-edge HasSession
La búsqueda de rutas ponderada de BloodHound no es nueva, así que aquí está el posicionamiento honesto:
La contribución de NoiseHound es la combinación: un corpus legible por máquina de aristas de BloodHound a telemetría de detección, una re-resolución ponderada por ruido enmarcada como OPSEC del operador ("la vía más silenciosa hacia DA"), un modelo de entorno que se adapta a la postura declarada de un objetivo, y un bucle de calibración que convierte detecciones de laboratorio en puntuaciones medidas. Las matemáticas de grafos son comunes; el corpus y el marco son el punto. Su valor solo es tan bueno como el corpus, por eso la calibración y la contribución de la comunidad son de primera clase; ver más abajo.
cd NoiseHound python -m pip install -r requirements.txt # networkx>=3.0
noisehound command on PATH:python -m pip install -e .
Requiere Python 3.10+.
## Uso```bash
# Text summary (default)
python -m noisehound --input export.zip --objective "Domain Admins" --source jdoe
# JSON, for downstream tooling / correlation across the DreadHost suite
python -m noisehound -i export.zip -o "Domain Admins" -s jdoe -f json --out paths.json
# Self-contained HTML report
python -m noisehound -i export.zip -o "Domain Admins" -s jdoe -f html --out report.html
Primero, verifica la cordura del parser en tu exportación (histogramas + cobertura del corpus, sin pathing): la forma más rápida de validar NoiseHound con datos del mundo real:```bash noisehound-inspect -i export.zip
### Live BloodHound CE / Neo4j
En lugar de un zip, apunta `--input` a la base de datos Neo4j que BloodHound CE
puebla y NoiseHound lee el grafo (ya analizado) directamente a través de Bolt:```bash
pip install 'noisehound[neo4j]'
export NEO4J_PASSWORD=bloodhoundcommunityedition # match your BHCE compose
noisehound-inspect -i bolt://localhost:7687
python -m noisehound -i bolt://localhost:7687 -s jdoe -o "Domain Admins"
Levanta BloodHound CE (incluye Neo4j en el puerto 7687) con su compose oficial:
curl -L https://ghst.ly/getbhce | docker compose -f - up.
Pruébalo contra las muestras incluidas:```bash python -m noisehound -i samples/sample_graph.json -s jdoe -o "Domain Admins" -d CONTOSO.LOCAL python -m noisehound -i samples/sample_bloodhound_ce.zip -s jdoe -o "Domain Admins" python -m noisehound -i samples/sample_adcs_ce.zip -s jdoe -o "Domain Admins" # ADCS ESC1
python -m noisehound -i samples/sample_fullspectrum_ce.zip -s ALICE -o "Domain Admins" -d CONTOSO.LOCAL -k 3
Ese último es la demostración más clara de la tesis: la ruta más silenciosa hacia
Domain Admins es la ruta de sesión de 4 saltos, clasificada *por encima* de la ruta RDP de 3 saltos y del
ADCS ESC1 de 1 salto: más saltos, menos ruido.
El ejemplo demuestra el valor principal: la ruta más silenciosa es una ruta de sesión
de 4 saltos (puntuación 19.9), clasificada *por encima* de un atajo ForceChangePassword de 2 saltos (36.4).
Menos saltos no significa más silencioso.
### Modo de detección de brechas para el equipo azul
La ruta más silenciosa es donde la detección es más débil, así que añade `--defensive` para invertir
la salida para los defensores: marca los bordes que son silenciosos solo porque su
telemetría está desactivada o ausente, asigna cada uno al control que lo detectaría, y
clasifica esos controles según cuánto elevan la puntuación de la ruta más silenciosa.```bash
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" --defensive
On the full-spectrum sample it finds that the quietest path to Domain Admins
hinges on undetected LSASS access (HasSession, 20 -> 65 if instrumented) and
recommends deploying Sysmon Event 10 - closing that one gap lifts the quietest
path from 19.9 to 48.4. See docs/ROADMAP.md for where this
and the rest of the model are headed.
| Opción | Significado |
|---|---|
--input, -i | BloodHound .zip, .json, o directorio de exportaciones |
--source, -s | Principal de inicio (jdoe o un id de objeto) |
--objective, -o | Nodo objetivo (Domain Admins o un id de objeto) |
--paths, -k | Número de rutas más silenciosas a devolver (por defecto 5) |
--format, -f | text (por defecto), json, o html |
--defensive | Vista de equipo azul: brechas de detección en las rutas más silenciosas + correcciones |
--rank-by | noise (por defecto) o probability (P de una alerta correlacionada) |
--correlation | Coeficiente de correlación del SOC para P(detectado), 0..1 (por defecto 0.5) |
--pareto | Devuelve la frontera de Pareto sobre ruido/saltos/P(detección) |
--engine | auto (por defecto), python, o rust (el motor DeadAir) |
--avoid NODE | Excluye un nodo de todas las rutas (repetible) |
--avoid-edge TYPE | Excluye un tipo de borde de todas las rutas (repetible) |
--corpus | Sobrescribe el directorio del corpus de mapeo de bordes |
--environment, -e | JSON de postura objetivo declarado por el operador (ajusta las puntuaciones) |
--max-weight / --mean-weight | Pesos de puntuación (deben sumar 1.0) |
--default-noise | Puntuación para tipos de borde ausentes del corpus (por defecto 60) |
Una puntuación estática del corpus no puede saber si un objetivo concreto tiene la auditoría de objetos 4662 activada, ejecuta Sysmon, o usa un ITDR como MDI - sin embargo, esos factores mueven enormemente el ruido real de un borde (DCSync es casi silencioso sin auditoría 4662 y casi con certeza detectado con ella). En lugar de fingir que un solo número sirve para cada entorno, declara la postura del objetivo en un pequeño archivo JSON y NoiseHound ajusta las puntuaciones de forma transparente contra las anotaciones de telemetría del propio corpus:```json { "name": "CONTOSO.LOCAL-prod", "object_auditing_4662": true, "ds_change_auditing_5136": false, "edr": "MDI", "sysmon": true, "powershell_logging_4104": true, "adjustments": { "HasSession": 65 } }
Los ajustes solo *elevan* una puntuación hacia un umbral de detección implícito en la
postura declarada. `adjustments` son anulaciones estrictas por arista: el lugar para
registrar valores que has calibrado contra tu propio laboratorio. Esto lo proporciona el operador,
no se mide; no reemplaza la validación en vivo de la Fase 2, pero convierte el
corpus estático de "un número para todos los entornos" en "el número para el
entorno en el que realmente estás". En la muestra incluida, declarar el perfil
anterior cambia la ruta más silenciosa de la sesión de volcado de LSASS a una
ruta de escritura de directorio, que es la decisión correcta una vez que la telemetría del host está activa.```bash
python -m noisehound -i samples/sample_graph.json -s jdoe -o "Domain Admins" \
-e samples/env_profile.example.json
Score precedence: static -> environment-adjusted -> live (Phase 2).
Environment profiles are only as good as the numbers you put in them.
noisehound-calibrate closes the loop: run the techniques in a detection lab,
record what fired, and it emits a calibrated environment profile.
This has been done. profiles/ ships six measured profiles from a
real Hyper-V Vulnerable-AD range and a lab Azure tenant - audit, EDR (Defender for
Endpoint), Elastic SIEM, Defender for Identity, and WDAC tiers plus a measured
Azure/Entra tier, 37 edges - produced by the automated harness (lab/) and this
tool. Use them directly, or measure your own:```bash
noisehound -i export.zip -s jdoe -o "Domain Admins" -e profiles/vulnad-hyperv-audit.json
noisehound-calibrate -i lab_detections.json -o env.calibrated.json noisehound -i export.zip -s jdoe -o "Domain Admins" -e env.calibrated.json
El modelo de puntuación es un estimador de contracción, honesto respecto al tamaño de la muestra:```
p = detections / runs (detection probability)
lab_score = p * severity_loudness + (1 - p) * residual
w = runs / (runs + smoothing) (confidence in the lab)
calibrated = w * lab_score + (1 - w) * corpus_static
lab_score es el costo de detección esperado: la severidad del SOC cuando se activa,
un pequeño residual cuando no lo hace. El peso w evita que una sola ejecución
anule el corpus mientras permite que un resultado bien muestreado domine. En el
ejemplo, HasSession sube de un estático 20 a 52 (el laboratorio detectó el volcado
de LSASS en 4 de 5 ejecuciones) mientras que Kerberoast baja de 60 a 34 (nunca se
activó). Usa --merge existing.json para superponer nueva calibración sobre un
perfil manteniendo sus banderas de postura, y --smoothing / --residual para
ajustar el modelo.
Los perfiles de entorno y la calibración son autodeclarados. noisehound-sigma
puntúa contra las detecciones que un defensor ha realmente escrito: apúntalo a un
conjunto de reglas Sigma y calcula sobre qué bordes del corpus se activaría cada
regla (emparejando los IDs de eventos de telemetría y la técnica ATT&CK del borde),
luego emite un perfil de entorno que eleva los bordes cubiertos: un reemplazo
directo para --environment.```bash
noisehound-sigma -r ./sigma-rules/ -o env.sigma.json
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" -e env.sigma.json --defensive
Para el nivel de identidad, **`noisehound-mdi`** hace lo mismo contra las detecciones integradas de Microsoft Defender
for Identity: mapea las alertas de runtime de MDI (y, con
`--include-posture`, sus evaluaciones ISPM) sobre los bordes del corpus y emite un
perfil del nivel de identidad. MDI es independiente de la herramienta, por lo que su cobertura se mantiene independientemente de las
herramientas del atacante.```bash
noisehound-mdi -o env.mdi.json # + coverage report (which edges MDI watches, and the gaps)
Para los bordes de Azure/Entra, noisehound-entra mide el nivel en la nube
de la misma manera en que se midieron los niveles locales: activa los abusos AZ* en un tenant de laboratorio,
exporta el rastro de directoryAudits de Entra, y cuenta lo que realmente se registró en un
perfil calibrado (docs/AZURE_CALIBRATION.md).```bash
noisehound-entra -a directoryAudits.json -m entra_runs.json --profile-out profiles/lab-tenant-azure.json
La coincidencia es deliberadamente conservadora para que nunca oculte una brecha: una regla solo cuenta si hace referencia a un ID de evento que el edge genera *y*, cuando la regla está etiquetada con ATT&CK, su técnica coincide; así, una regla DCSync de DS-Access (4662) no se acredita erróneamente por cubrir lecturas de LAPS que simplemente comparten el ID de evento. El informe enumera tanto lo que cubren tus reglas como, más útil aún, los edges de ataque que ninguna regla cubre. Combinado con `--defensive`, esto responde a la pregunta "dadas las detecciones que tengo desplegadas, ¿dónde sigue invisible mi ruta de ataque más silenciosa?"
### Inventario en vivo de Elastic Security
`noisehound-elastic` responde a la misma pregunta contra las detecciones que están **realmente habilitadas ahora mismo** en una pila de Elastic Security en ejecución, en lugar de reglas en disco. Lee el motor de detección a través de la API de solo lectura `_find` de Kibana (o una exportación sin conexión), mapea la técnica ATT&CK de cada regla habilitada y cualquier código de evento de Windows en su consulta, y emite el mismo perfil de cobertura de `--environment`.```bash
export KIBANA_URL=https://kibana:5601 KIBANA_API_KEY=<base64 ApiKey>
noisehound-elastic -o env.elastic.json # live, read-only
noisehound-elastic --rules-json rules_find.json -o env.elastic.json # offline export
python -m noisehound -i export.zip -s jdoe -o "Domain Admins" -e env.elastic.json --defensive
Reutiliza el comparador de Sigma y añade un nivel solo de técnica (marcado [technique],
con menor puntuación) para las reglas KQL/EQL de comportamiento que nunca nombran un código de evento.
Las reglas deshabilitadas se ignoran. El mismo patrón de normalizar-y-puntuar se aplica a continuación a Splunk /
Sentinel / MDI.
En el momento de la carga, NoiseHound realiza una versión enfocada del post-procesamiento de ADCS
de BloodHound, sintetizando aristas de escalada a partir de los hechos retenidos de plantillas/CA.
Un derecho Enroll sobre una plantilla vulnerable se convierte en una arista directa
ADCSESCn desde el principal al grupo Domain Admins del dominio (RID 512),
de modo que la escalada por certificados se puede trazar y puntuar como cualquier otra arista:
| Arista | Condición |
|---|---|
ADCSESC1 | El solicitante proporciona el asunto + EKU de autenticación de cliente, sin aprobación/firmas de RA |
ADCSESC2 | EKU Any-Purpose / SubCA, sin aprobación |
ADCSESC3 | Plantilla de agente de inscripción + una plantilla de autenticación en la misma CA |
ADCSESC4 | Control de escritura peligroso sobre una plantilla publicada |
ADCSESC5 | Control del objeto CA o del equipo que lo aloja |
ADCSESC6 | La CA tiene EDITF_ATTRIBUTESUBJECTALTNAME2 establecido |
ADCSESC7 | ManageCA / ManageCertificates en la CA |
ADCSESC8 | Endpoint de inscripción web vulnerable (coerción + relay NTLM) |
Pruébalo: python -m noisehound -i samples/sample_adcs_ce.zip -s jdoe -o "Domain Admins".
Simplificaciones documentadas (fallan de forma segura mostrando más rutas): las restricciones de inscripción a nivel de CA no se modelan (la inscripción en la plantilla se trata como suficiente); ESC5 cubre el objeto CA y su host, no todos los contenedores PKI; ESC9/10/13 quedan fuera del alcance. Las aristas ESC sintéticas ya presentes en una exportación post-procesada se conservan.
edge_mappings/)El corpus de telemetría de aristas es la verdadera propiedad intelectual de esta herramienta; el código es
matemática de grafos comparativamente simple sobre él. Cada edge_mappings/<Edge>.json
mapea un tipo de arista de BloodHound a su superficie de detección:
Extender el corpus es donde debería ir la mayor parte del esfuerzo continuo. Añade un nuevo archivo JSON, mantén el esquema (validado en tiempo de carga) y se recoge automáticamente. v0.3 incluye 43 tipos de aristas que cubren el abuso de ACL, Kerberos, delegación, ADCS ESC1-8, LAPS/gMSA, GPO, confianza y aristas de derechos de acceso que importan para la búsqueda de rutas.
Las puntuaciones se siembran a partir de la matriz de ruido del DreadHost Red Team Operator Playbook (asignaciones de eventos de Windows/Sysmon, calificaciones de ruido de técnicas) y hechos estándar de detección de AD. Ajústalas con tus propios datos de detección de laboratorio.
---
## Hoja de ruta
- **Cobertura de Azure / Entra ID (base enviada, en expansión).** Ahora se incluyen 13 aristas de rutas de ataque `AZ*` con telemetría de detección nativa de Entra; consulta [`docs/AZURE.md`](https://github.com/warpedatom/noisehound/blob/HEAD/docs/AZURE.md). Los datos de Azure recopilados mediante AzureHound en BloodHound CE se puntúan hoy (`noisehound -o "Global Administrator"`), y la ingesta nativa de AzureHound más un nivel de calibración medido de Azure/Entra (`noisehound-entra`, `profiles/lab-tenant-azure.json`) también se incluyen ahora. Siguiente: perfiles de postura de Entra (MDCA / ID Protection / Sentinel) y aristas híbridas (Entra Connect / PHS-PTA) para que **MDI** contribuya a través del límite local/nube.
- **Terminar la calibración: 37/77 medidos, continúa.** Quedan ~40 aristas (coerción/relay, ADCS ESC2-13, CanRDP en metal desnudo), calibración más profunda en múltiples entornos y un corpus multi-EDR (CrowdStrike/S1 junto a MDE), además de calibración de herramientas por arista para ampliar el eje `--tooling`.
- **Síntesis de ADCS ESC10a/10b/13** (la síntesis de ESC1-9 se envía ahora).
Enviado: el motor Rust ([DeadAir](https://github.com/warpedatom/DeadAir), despacho `--engine`), ingesta en vivo de Neo4j Bolt (`--input bolt://...`), el eje seleccionable **`--tooling`** (listo para usar en el host vs remoto/nativo; `docs/TOOLING_AXIS.md`), el enganche de Fase 2 **`--live-scores`** (las puntuaciones medidas anulan el corpus/entorno) y **`noisehound-mdi`** (cobertura de Defender for Identity -> perfil de nivel de identidad). El trabajo restante de MDI es la *calibración de alertas en tiempo de ejecución* limitada al laboratorio (`docs/CALIBRATION.md`).
## Contribuciones
El corpus es extensible por la comunidad y ahí es donde más importan las contribuciones. Añadir una arista es un archivo JSON validado en la carga y en CI:```bash
noisehound-validate # schema + consistency checks over the corpus
python -m pytest tests/ -q
Consulta CONTRIBUTING.md para el esquema, la guía de puntuación y las indicaciones para PR, y docs/edge_schema.json para el esquema formal de edges.
Se miden 30 edges (consulta profiles/); el resto son estimaciones hasta que los midas, y cada entorno difiere. docs/CALIBRATION.md es un manual completo: topología de laboratorio, la política de auditoría de Windows exacta y la configuración de Sysmon para que se activen los ID de eventos del corpus, un runbook de ejercicios por edge, una capa de realismo APT29-vía-Caldera, y cómo compilar los resultados en un perfil calibrado. Comienza con noisehound-calibrate --template -o lab_detections.json.
El kit lab/ automatiza la instrumentación de detección: Enable-Telemetry.ps1 activa la política de auditoría, el registro de bloques de script, el SACL de DCSync y Sysmon; Collect-Detections.ps1 contabiliza lo que se disparó en una ventana. Se apoya en GOAD o Vulnerable-AD (o cualquier AD de laboratorio de entrenamiento existente) para el dominio vulnerable en lugar de reimplementarlos.
NoiseHound es para pruebas de seguridad autorizadas, ejercicios de purple team, ingeniería de detección e investigación. Lee datos de BloodHound que ya hayas recopilado y calcula clasificaciones; no ejecuta nada contra un objetivo. Úsalo solo donde tengas autorización escrita explícita. Las contribuciones no deben incluir datos específicos de objetivos o de compromisos reales.
python -m pytest tests/ # with pytest python tests/test_noisehound.py # dependency-light smoke run
## Diseño```
noisehound/ engine: schema, corpus, ingest, adcs, annotate, environment,
solver, report, cli, calibrate
edge_mappings/ the telemetry corpus (one JSON per edge type) - the IP
samples/ sample_graph.json, sample_bloodhound_ce.zip, sample_adcs_ce.zip,
sample_fullspectrum_ce.zip, env_profile.example.json,
lab_detections.example.json, sample_report.html
tests/ unit + end-to-end tests