
Modelado mundial de defensa contra amenazas cibernéticas
Sistema de Modelado Mundial de Defensa contra Amenazas Cibernéticas
Bandjacks es un sistema integral de inteligencia de amenazas cibernéticas (CTI) que:
| Guía | Descripción |
|---|---|
| Inicio Rápido | Póngase en marcha en 5 minutos |
| Configuración Completa | Configuración completa del entorno |
| Uso de CLI | Guía de interfaz de línea de comandos |
| Referencia de API | Documentación de la API REST |
| Análisis de Co-ocurrencia | Documentación de análisis |
| Generación de AttackFlow | Guía de generación de flujo |
| Sistema de Revisión | Revisión con intervención humana |
git clone https://github.com/yourusername/bandjacks.git cd bandjacks
uv sync
pip install -e .
cd ui && npm install && cd ..
### Configuración del Entorno
**IMPORTANTE:** Debes configurar las variables de entorno antes de iniciar la aplicación. La aplicación requiere que `NEO4J_PASSWORD` esté configurada.
Crea un archivo `.env` en la raíz del proyecto:```bash
# Copy the sample file
cp infra/env.sample .env
# Edit .env and set your actual passwords
nano .env
Configuración requerida en .env:```bash
NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=your-actual-neo4j-password # MUST BE SET - no default provided
OPENSEARCH_URL=http://localhost:9200 OPENSEARCH_USER=admin OPENSEARCH_PASSWORD=your-opensearch-password # Optional if security is disabled
LOCAL_LLM_API_BASE=http://192.168.1.100:8080/v1 # Base URL of your local server LOCAL_LLM_MODEL=mistral-nemo # Model name as the server reports it LOCAL_LLM_API_KEY=no-key # Most local servers accept any value
PRIMARY_LLM=gemini GOOGLE_API_KEY=your-gemini-api-key
OPENAI_API_KEY=your-openai-api-key
ATTACK_INDEX_URL=https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master/index.json ATTACK_COLLECTION=enterprise-attack ATTACK_VERSION=latest
REDIS_URL=redis://localhost:6379
**Nota:** La aplicación fallará al iniciar si `NEO4J_PASSWORD` no está configurada. Consulte [Solución de variables de entorno](https://github.com/blevene/bandjacks/blob/main/ENV_VARIABLES_FIX.md) para más detalles.
### Iniciando los Servicios```bash
# Start the FastAPI backend server
uv run uvicorn bandjacks.services.api.main:app --reload --port 8000
# In another terminal, start the Next.js frontend
cd ui && npm run dev
# Access the applications
open http://localhost:8000/docs # API documentation
open http://localhost:3000 # Frontend UI
Bandjacks incluye una CLI completa para operaciones de inteligencia de amenazas:```bash
uv run python -m bandjacks.cli.main --help
> **Nota:** The CLI requiere que se configuren variables de entorno (NEO4J_PASSWORD, etc.). Ejecútalo desde la raíz del proyecto donde se encuentra `.env`.
### Comandos de Consulta```bash
# Search for threat intelligence
uv run python -m bandjacks.cli.main query search "ransomware encryption techniques" --top-k 10
# Explore graph relationships
uv run python -m bandjacks.cli.main query graph "attack-pattern--abc123" --depth 2
uv run python -m bandjacks.cli.main review queue --status pending --limit 20
uv run python -m bandjacks.cli.main review approve "candidate-123" --reviewer analyst-1
uv run python -m bandjacks.cli.main review reject "candidate-456" --reviewer analyst-1 --reason "False positive"
### Extracción de Documentos```bash
# Extract CTI from a document
uv run python -m bandjacks.cli.main extract document ./report.pdf --confidence-threshold 80 --show-evidence
Nota: Los comandos de análisis requieren datos de
AttackEpisodeen Neo4j para devolver resultados.```bash
uv run python -m bandjacks.cli.main analytics top-cooccurrence --limit 25 --min-episode-size 2
uv run python -m bandjacks.cli.main analytics conditional "attack-pattern--abc123" --limit 25
uv run python -m bandjacks.cli.main analytics actor "intrusion-set--xyz789" --metric npmi
uv run python -m bandjacks.cli.main analytics bundles --min-support 3 --min-size 3 --max-size 5 --format json --output bundles.json
uv run python -m bandjacks.cli.main analytics global --min-support 2 --limit 50 --format csv --output pairs.csv
### Comandos de flujo de trabajo```bash
# Process a directory of reports with analytics
uv run python -m bandjacks.cli.main workflow process-reports ./reports/ --workers 3 --analyze --export-dir ./results/
# Bulk export all analytics data
uv run python -m bandjacks.cli.main workflow bulk-export --export-dir ./analytics_export/
uv run python -m bandjacks.cli.main admin health
uv run python -m bandjacks.cli.main admin cache-stats
uv run python -m bandjacks.cli.main admin cache-clear --pattern "search:*"
uv run python -m bandjacks.cli.main admin optimize
## Frontend UI
El frontend de Next.js proporciona una interfaz moderna para trabajar con el sistema.
### Gestión de Informes (`/reports`)
- **Lista de Informes**: Ver todos los informes ingeridos con estado y recuento de técnicas
- **Nuevo Informe** (`/reports/new`): Subir archivos PDF/TXT o pegar contenido del informe
- **Detalle del Informe** (`/reports/[id]`): Ver técnicas extraídas, entidades y evidencia
- **Interfaz de Revisión** (`/reports/[id]/review`): Flujo de trabajo de revisión con intervención humana
### Analítica de Co-ocurrencia (`/analytics/cooccurrence`)
> **Nota:** Estas páginas requieren datos de `AttackEpisode` en Neo4j. Procese los informes a través del pipeline de extracción primero, o use `POST /v1/flows/build` para generar episodios a partir de datos de conjuntos de intrusiones.
- **Página Principal**: Resumen con recuentos de episodios/técnicas/actores
- **Pares Principales** (`/pairs`): Pares de técnicas co-ocurrentes con métricas NPMI/Lift
- **Condicional** (`/conditional`): Probabilidades condicionales P(B|A)
- **Paquetes** (`/bundles`): Paquetes de técnicas que co-ocurren con frecuencia
- **Actores** (`/actors`): Patrones de técnicas específicos de actores
- **Puente** (`/bridging`): Técnicas utilizadas en múltiples actores
### Salud del Sistema (`/health`)
- Estado de salud en tiempo real de todos los componentes (Neo4j, OpenSearch, Redis)
- Estadísticas de caché y uso de memoria
- Endpoints de salud compatibles con Kubernetes
### Iniciando el Frontend```bash
cd ui
npm run dev # Development mode with hot reload
npm run build # Production build
npm run start # Start production server
# Ensure backend is running
# API_URL defaults to http://localhost:8000/v1
Primero, carga el framework MITRE ATT&CK en tu grafo de conocimiento:```bash
curl -X POST "http://localhost:8000/v1/stix/load/attack"
-H "Content-Type: application/json"
-d '{
"collection": "enterprise-attack",
"version": "latest",
"adm_strict": false
}'
### 2. Extrayendo Técnicas de Informes
Extraer técnicas de MITRE ATT&CK de informes de inteligencia de amenazas:```python
import httpx
import time
# For small reports (<5KB) - synchronous processing
response = httpx.post(
"http://localhost:8000/v1/reports/ingest",
json={
"content": "APT29 used spearphishing emails with malicious attachments...",
"title": "APT29 Campaign Analysis",
"config": {
"use_optimized_extractor": True,
"span_score_threshold": 0.7,
"top_k": 5
}
}
)
result = response.json()
print(f"Extracted {len(result['extraction']['techniques'])} techniques")
# For large reports (>5KB) - asynchronous processing
response = httpx.post(
"http://localhost:8000/v1/reports/ingest_async",
json={
"content": large_report_text,
"title": "Large Report Analysis"
}
)
job_id = response.json()["job_id"]
# Check job status
status = httpx.get(f"http://localhost:8000/v1/reports/jobs/{job_id}/status")
while status.json()["status"] == "processing":
time.sleep(2)
status = httpx.get(f"http://localhost:8000/v1/reports/jobs/{job_id}/status")
# Get results from completed job
result = status.json()["result"]
print(f"Extracted {result['techniques_count']} techniques in {result['elapsed_time']} seconds")
Para acceso programático sin la API:```python from bandjacks.llm.extraction_pipeline import run_extraction_pipeline
config = { "use_optimized_extractor": True, # Use optimized pipeline "span_score_threshold": 0.7, # Minimum span confidence "max_spans": 20, "top_k": 5, "chunk_size": 2000, # For large documents "max_chunks": 100 }
result = run_extraction_pipeline( report_text, config, source_id="report_123", neo4j_config=neo4j_config )
techniques = result["techniques"] # Dict of technique_id -> details bundle = result.get("bundle") # STIX 2.1 bundle if configured entities = result.get("entities") # Extracted entities
for tech_id, info in techniques.items(): print(f"{tech_id}: {info['name']}") print(f" Confidence: {info['confidence']}%") print(f" Evidence: {info['evidence']}")
## Arquitectura del Pipeline de Extracción
El pipeline de extracción de Bandjacks utiliza una arquitectura multiagente para extraer inteligencia de amenazas estructurada:
### Componentes del Pipeline
El pipeline de extracción utiliza 9 agentes especializados en secuencia:
#### 1. **EntityExtractionAgent** - Reconocimiento de Entidades
- Extrae actores de amenaza, malware, herramientas y campañas
- Se ejecuta primero para proporcionar contexto para la extracción de técnicas
- Utiliza few-shot prompting con validación de esquema JSON
- Maneja documentos fragmentados con extracción progresiva por ventanas
#### 2. **SpanFinderAgent** - Detección de Texto Comportamental
- Detecta fragmentos de texto que contienen comportamientos de amenaza usando 14 patrones regex específicos de tácticas
- Identifica IDs de técnica explícitos (T1566.001) y patrones de comportamiento
- Puntúa fragmentos por confianza con refuerzo de índice de palabras clave
- Sin llamadas LLM — solo coincidencia de patrones para velocidad
#### 3. **BatchRetrieverAgent** - Recuperación de Candidatos
- Utiliza búsqueda vectorial KNN de OpenSearch para encontrar técnicas candidatas por fragmento
- Deduplica textos de fragmentos idénticos antes de la codificación para evitar embeddings redundantes
- Devuelve los top-k candidatos con puntuaciones de similitud para cada fragmento
#### 4. **Pre-filter** - Reducción de Fragmentos
- Limita los fragmentos a `max_spans_per_technique` (por defecto 2) por técnica candidata
- Conserva los fragmentos con mayor puntuación por candidato para mantener la calidad de la evidencia
- Reduce las llamadas LLM del mapeador en ~46% con una pérdida mínima de técnicas
#### 5. **DiscoveryAgent** - Descubrimiento LLM (condicional)
- Se activa cuando la confianza del recuperador es baja (promedio <0.7)
- Utiliza LLM para descubrir técnicas que la búsqueda vectorial no encontró
- Una sola llamada por lotes para todos los fragmentos de baja confianza
#### 6. **BatchMapperAgent** - Mapeo de Técnicas (LLM)
- Procesa fragmentos por lotes en grupos de hasta 10 (`MAX_MAPPER_BATCH_SIZE`, por defecto reducido de 25 en 2026-05 para limitar la truncación del LLM en la nube)
- Extrae TODAS las técnicas relevantes por fragmento con puntuaciones de confianza
- Utiliza validación de esquema JSON para salida estructurada
#### 7. **EvidenceVerifierAgent** - Validación de Evidencias
- Verificación basada en patrones de citas y referencias de líneas
- Puntúa la calidad de la evidencia en una escala de 40 a 100 puntos
- Sin llamadas LLM — coincidencia de regex y texto
#### 8. **ConsolidatorAgent** - Consolidación de Evidencias
- Fusiona técnicas duplicadas encontradas en múltiples fragmentos
- Agrega evidencia usando similitud de Jaccard (umbral >85%)
- Produce una lista final de técnicas con puntuaciones de confianza consolidadas
#### 9. **AttackFlowSynthesizer** - Generación de Secuencia (LLM)
- Analiza marcadores temporales ("primero", "luego", "después")
- Infiere relaciones causales a partir de la narrativa
- Crea objetos Attack Flow de STIX con aristas probabilísticas
- Recurre al modelado de co-ocurrencia cuando la secuencia no es clara
### Optimizaciones de Rendimiento
- **Smart Chunking**: Documentos divididos en fragmentos de 2KB con superposición
- **Batch Processing**: El mapeador procesa hasta 25 fragmentos por llamada LLM
- **Parallel Processing**: Fragmentos procesados concurrentemente a través de hilos de trabajo
- **Response Caching**: Respuestas LLM almacenadas en caché para evitar llamadas duplicadas
- **Early Termination**: Extracciones de alta confianza omiten la verificación
- **TechniqueCache**: Todas las técnicas de ATT&CK cargadas al inicio para búsquedas O(1)
- **Pre-filter**: Limita fragmentos por técnica candidata antes del mapeador LLM (46% menos llamadas)
- **Batch Embedding**: Embeddings de técnicas generados por lotes (2-5x más rápido)
- **Connection Pooling**: Conexiones compartidas de Neo4j/OpenSearch entre solicitudes
- **UNWIND Batches**: Escrituras Neo4j por lotes mediante UNWIND (30-40 consultas → 6-7)
- **Model Pre-warming**: Modelo de embeddings cargado al inicio para evitar latencia de arranque en frío
### Tiempos de Procesamiento
| Tamaño del Documento | Tiempo de Procesamiento | Técnicas Extraídas |
|--------------|-----------------|---------------------|
| Pequeño (<5KB) | 10-20 segundos | 5-10 técnicas |
| Mediano (5-15KB) | 20-40 segundos | 10-15 técnicas |
| Grande (>15KB) | 30-60 segundos | 15-25 técnicas |
## Análisis de Co-ocurrencia
Bandjacks proporciona análisis para comprender las relaciones entre técnicas.
> **Nota:** Los análisis requieren datos de `AttackEpisode` y `AttackAction` en Neo4j. Estos se crean cuando:
> - Los informes se procesan a través del pipeline de extracción
> - Los flujos de ataque se construyen mediante `/v1/flows/build`
> - Se ingieren paquetes STIX con episodios de ataque
>
> Si no existen episodios, los análisis devolverán resultados vacíos.
### Co-ocurrencia Global
Calcular qué técnicas aparecen juntas con frecuencia en todos los episodios de ataque:```python
# Via API
response = httpx.post(
"http://localhost:8000/v1/analytics/cooccurrence/global",
json={"min_support": 2, "min_episodes_per_pair": 2, "limit": 50}
)
for pair in response.json()["pairs"]:
print(f"{pair['name_a']} + {pair['name_b']}: NPMI={pair['npmi']:.3f}")
Calcular P(B|A) - dado que se usó la técnica A, ¿cuál es la probabilidad de la técnica B:```python response = httpx.get( "http://localhost:8000/v1/analytics/cooccurrence/conditional", params={"technique_id": "attack-pattern--abc123", "limit": 25} )
### Paquetes de Técnicas
Identificar paquetes de técnicas que co-ocurren con frecuencia (3-5 técnicas):```python
response = httpx.post(
"http://localhost:8000/v1/analytics/cooccurrence/bundles",
json={"min_support": 3, "min_size": 3, "max_size": 5}
)
Analice los patrones de técnicas para actores de amenazas específicos:```python response = httpx.post( "http://localhost:8000/v1/analytics/cooccurrence/actor", json={"intrusion_set_id": "intrusion-set--xyz789", "min_support": 1} )
## Sistema de Revisión Humano en el Bucle
Bandjacks incluye un sistema de revisión completo para validar la inteligencia extraída:
### Interfaz Unificada de Revisión
El sistema de revisión presenta todos los elementos extraídos en una sola interfaz:```typescript
// Review workflow
1. Upload/ingest report → Extraction pipeline runs
2. Navigate to /reports/{id}/review
3. Review extracted items across three tabs:
- Entities (threat actors, malware, tools)
- Techniques (ATT&CK mappings with evidence)
- Attack Flow (sequenced steps)
4. Take actions on each item:
- Approve: Accept as correct
- Reject: Mark as incorrect
- Edit: Modify details (name, confidence, etc.)
5. Submit all decisions atomically
response = httpx.post( f"http://localhost:8000/v1/reports/{report_id}/unified-review", json={ "decisions": [ { "item_id": "technique-0", "action": "approve", "confidence_adjustment": 5, "notes": "Confirmed via external CTI" }, { "item_id": "entity-malware-1", "action": "edit", "edited_value": { "name": "Corrected Malware Name", "confidence": 95 } } ], "global_notes": "Review completed by analyst-1" } )
### 4. Búsqueda de Técnicas
Busca técnicas de ATT&CK usando lenguaje natural:```python
# Vector search for similar techniques
response = httpx.post(
"http://localhost:8000/v1/search/ttx",
json={
"query": "ransomware that encrypts files and demands payment",
"top_k": 5
}
)
techniques = response.json()["results"]
for tech in techniques:
print(f"{tech['external_id']}: {tech['name']} (score: {tech['score']:.2f})")
Consulta el grafo de conocimiento en busca de relaciones:```python
response = httpx.get( "http://localhost:8000/v1/graph/group/G0016/techniques" )
response = httpx.get( "http://localhost:8000/v1/defense/technique/T1566.001" )
### 6. Generación de modelos AttackFlow
Cree modelos de co-ocurrencia que muestren cómo los actores de amenazas usan las técnicas juntas:```python
# Generate flow for a specific intrusion set (e.g., APT29)
response = httpx.post(
"http://localhost:8000/v1/flows/build",
json={
"intrusion_set_id": "intrusion-set--899ce53f-13a0-479b-a0e4-67d46e241542"
}
)
flow = response.json()
print(f"Generated flow '{flow['name']}' with {len(flow['steps'])} techniques")
print(f"Co-occurrence edges: {len(flow['edges'])}")
Generación Masiva: Generar flujos para todos los actores de amenazas con técnicas:```bash
uv run python scripts/build_intrusion_flows_simple.py
AttackFlow models utilizan **co-ocurrencia** en lugar de orden secuencial, ya que los conjuntos de intrusiones no tienen información de secuencia inherente. Las técnicas se conectan mediante:
- **Enlaces intra-táctica**: Entre técnicas dentro de la misma táctica de kill chain
- **Enlaces entre tácticas**: Entre técnicas a través de tácticas adyacentes
- **Patrones hub-spoke**: Para conjuntos grandes de técnicas, evitando la explosión de enlaces
Consulte la [Guía de Generación de AttackFlow](https://github.com/blevene/bandjacks/blob/main/docs/ATTACKFLOW_GENERATION.md) para un uso detallado.
## Formatos de Entrada Soportados
El pipeline de extracción admite múltiples formatos de entrada:
- **Texto Plano** - Contenido de texto directo
- **Markdown** - Documentos markdown formateados
- **PDF** - Extracción vía pdfplumber
- **HTML** - Análisis vía BeautifulSoup
- **JSON** - Extracción de datos estructurados
### Extraer desde Texto Plano```python
# Direct text extraction
plaintext_report = """
The threat actors used spearphishing emails with malicious attachments.
After gaining access, they deployed Mimikatz to harvest credentials and
used RDP for lateral movement across the network.
"""
result = asyncio.run(run_agentic_v2_async(plaintext_report, {
"cache_llm_responses": True,
"single_pass_threshold": 500
}))
markdown_report = """
| Tool | Purpose |
|---|---|
| Mimikatz | Credential dumping |
| PsExec | Remote execution |
| Cobalt Strike | C2 communications |
| """ |
result = run_extraction_pipeline(markdown_report, { "use_optimized_extractor": True, "span_score_threshold": 0.7 }, source_id="markdown_report")
### Extracto de PDF```python
import pdfplumber
from bandjacks.llm.extraction_pipeline import run_extraction_pipeline
# Read PDF with pdfplumber (recommended)
with pdfplumber.open("threat_report.pdf") as pdf:
text = ""
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
# Extract techniques using extraction pipeline
result = run_extraction_pipeline(text, {
"use_optimized_extractor": True,
"span_score_threshold": 0.7,
"chunk_size": 2000
}, source_id="threat_report")
print(f"Found {len(result['techniques'])} techniques")
from pathlib import Path import json
reports_dir = Path("./reports") results = []
for pdf_file in reports_dir.glob("*.pdf"): # Extract text and techniques # ... (see above)
results.append({
"file": pdf_file.name,
"techniques": list(result["techniques"].keys()),
"count": len(result["techniques"])
})
with open("extraction_summary.json", "w") as f: json.dump(results, f, indent=2)
### Construcción de Flujos de Ataque```python
# Generate attack flow from extracted techniques
response = httpx.post(
"http://localhost:8000/v1/flows/build",
json={
"source_id": "report-123",
"technique_ids": ["T1566.001", "T1059.001", "T1003.001"]
}
)
flow = response.json()
print(f"Generated flow with {len(flow['steps'])} steps")
Ejecuta el conjunto de pruebas para verificar tu instalación:```bash
uv run pytest
python tests/test_optimized_extraction.py
python tests/test_graph_upsert.py
python tests/test_bundle_validation.py
cd ui && npm test
## API Endpoints
### Endpoints principales
- `POST /v1/stix/load/attack` - Cargar datos MITRE ATT&CK
- `POST /v1/reports/ingest` - Ingesta de informes síncrona (<5KB)
- `POST /v1/reports/ingest_async` - Ingesta de informes asíncrona (>5KB)
- `POST /v1/reports/ingest/upload` - Subir archivos PDF/TXT
- `GET /v1/reports/jobs/{id}/status` - Verificar estado del trabajo
- `POST /v1/reports/{id}/unified-review` - Enviar decisiones de revisión
- `POST /v1/search/ttx` - Buscar técnicas
- `GET /v1/graph/technique/{id}` - Obtener detalles de técnica
### Flujos de ataque
- `POST /v1/flows/build` - Generar modelos de co-ocurrencia de AttackFlow
- `GET /v1/flows/{flow_id}` - Recuperar detalles específicos de AttackFlow
- `POST /v1/flows/search` - Buscar flujos de ataque similares
- `GET /v1/flows/dump` - Exportar flujos en lote con paginación y filtrado
### Analítica
- `GET /v1/analytics/cooccurrence/global` - Métricas de co-ocurrencia global
- `GET /v1/analytics/cooccurrence/conditional` - Probabilidades condicionales
- `GET /v1/analytics/cooccurrence/bundles` - Paquetes de técnicas
- `GET /v1/analytics/cooccurrence/actor` - Patrones específicos de actor
- `GET /v1/coverage/gaps` - Brechas de cobertura de técnicas
### Defensa y Detección
- `GET /v1/defense/technique/{id}` - Obtener recomendaciones defensivas
- `GET /v1/detections/technique/{id}` - Estrategias de detección
- `POST /v1/sigma/validate` - Validar reglas Sigma
### Monitoreo
- `GET /health` - Verificación de salud básica
- `GET /health/live` - Sonda de actividad de Kubernetes
- `GET /health/ready` - Sonda de preparación de Kubernetes
- `GET /health/components/{component}` - Salud de componente individual
- `GET /v1/costs/stats` - Seguimiento de costos LLM (agregado diario por modelo)
- `GET /v1/cache/stats` - Obtener estadísticas de caché LLM
- `POST /v1/cache/clear` - Limpiar caché LLM
- `GET /v1/compliance/report` - Métricas de cumplimiento
- `GET /v1/drift/status` - Estado de detección de deriva
- `GET /v1/ml-metrics/performance` - Métricas de modelo ML
### Actores y Procedencia
- `GET /v1/actors` - Listar actores de amenaza
- `GET /v1/actors/{id}` - Obtener detalles del actor
- `GET /v1/provenance/{object_id}` - Procedencia del objeto
- `GET /v1/provenance/{object_id}/lineage` - Cadena de linaje completa
- `GET /v1/provenance/{object_id}/evidence` - Fragmentos de evidencia
### Funciones solo API (Sin interfaz/CLI)
Estos endpoints son completamente funcionales pero se accede a ellos solo a través de la API REST (sin páginas frontend ni comandos CLI):
#### Simulación de rutas de ataque
- `POST /v1/simulation/paths` - Simular rutas de ataque desde técnica/grupo inicial
- `POST /v1/simulation/predict` - Predecir las siguientes técnicas probables dado el estado actual
- `POST /v1/simulation/whatif` - Análisis de hipótesis para escenarios defensivos
- `POST /v1/simulation/scenario` - Simular desde conjuntos de grupos/software/técnicas
- `GET /v1/simulation/statistics/{technique_id}` - Estadísticas de uso de técnicas
- `GET /v1/simulation/groups/{group_id}/patterns` - Patrones de ataque de grupo
- `POST /v1/simulation/compare` - Comparar múltiples rutas de ataque
#### Política y despliegue MDP
- `POST /v1/simulate/rollout` - Simulación de despliegue PTG
- `POST /v1/simulate/mdp` - Calcular política de defensa óptima MDP
- `GET /v1/simulate/models` - Listar modelos PTG disponibles
#### Detección y monitoreo de deriva
- `GET /v1/drift/status` - Estado actual de deriva en todas las métricas
- `POST /v1/drift/analyze` - Ejecutar análisis de deriva con umbrales personalizados
- `GET /v1/drift/alerts` - Obtener alertas de deriva activas
- `POST /v1/drift/alerts/{alert_id}/acknowledge` - Reconocer alerta
- `GET /v1/drift/metrics/{metric_name}` - Obtener métrica de deriva específica
#### Seguimiento de métricas ML
- `POST /v1/ml-metrics/prediction` - Registrar predicción del modelo para seguimiento
- `POST /v1/ml-metrics/review` - Registrar métricas de decisión de revisión
- `POST /v1/ml-metrics/coverage-gap` - Registrar brecha de cobertura
- `GET /v1/ml-metrics/performance` - Obtener métricas de rendimiento del modelo
- `GET /v1/ml-metrics/dashboard` - Exportar métricas del panel
#### Notificaciones
- `GET /v1/notifications/history` - Obtener historial de notificaciones
- `POST /v1/notifications/clear-history` - Limpiar historial de notificaciones
- `GET /v1/notifications/config` - Obtener configuración de notificaciones
- `POST /v1/notifications/test` - Enviar notificación de prueba
#### Gestión de actualizaciones de vectores
- `GET /v1/vectors/status` - Estado del sistema de actualización de vectores
- `GET /v1/vectors/metrics` - Métricas detalladas de actualización de vectores
- `POST /v1/vectors/update` - Activar manualmente la actualización de vectores
- `POST /v1/vectors/process-batch` - Forzar procesamiento por lotes
- `DELETE /v1/vectors/queue` - Limpiar cola de actualizaciones pendientes
- `GET /v1/vectors/health` - Verificación de salud del sistema de vectores
#### Lista de ignorados de entidades
- `GET /v1/ignorelist` - Obtener estado actual de la lista de ignorados
- `POST /v1/ignorelist/add` - Agregar entidad a la lista de ignorados
- `DELETE /v1/ignorelist/remove` - Eliminar entidad de la lista de ignorados
- `POST /v1/ignorelist/reload` - Recargar lista de ignorados desde disco
#### Revisión de patrones candidatos
- `GET /v1/review/candidates` - Listar patrones de ataque candidatos
- `POST /v1/review/candidates` - Crear patrón candidato
- `GET /v1/review/candidates/{id}` - Obtener detalles del candidato
- `POST /v1/review/candidates/{id}/approve` - Aprobar candidato
- `POST /v1/review/candidates/{id}/reject` - Rechazar candidato
- `GET /v1/review/candidates/{id}/similar` - Encontrar patrones similares
- `GET /v1/review/candidates/stats/summary` - Estadísticas de candidatos
### Documentación completa de la API
Acceda a la documentación completa de la API en:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
## Arquitectura
### Estructura del proyecto```
bandjacks/
├── bandjacks/
│ ├── analysis/ # Graph analysis & interdiction
│ │ ├── graph_analyzer.py
│ │ └── interdiction.py
│ ├── analytics/ # Co-occurrence & clustering
│ │ ├── clustering.py
│ │ ├── cooccurrence.py
│ │ └── detection_bundles.py
│ ├── cli/ # Command-line interface
│ │ ├── main.py # CLI entry point
│ │ ├── batch_extract.py
│ │ ├── formatters.py
│ │ └── workflows.py
│ ├── config/ # Configuration files
│ │ └── entity_ignorelist.yaml
│ ├── core/ # Core utilities
│ │ ├── cache.py # Redis caching
│ │ ├── connection_pool.py
│ │ └── query_optimizer.py
│ ├── llm/ # Extraction pipeline
│ │ ├── extraction_pipeline.py
│ │ ├── agents_v2.py # Core extraction agents
│ │ ├── chunked_extractor.py
│ │ ├── optimized_chunked_extractor.py
│ │ ├── entity_extractor.py
│ │ ├── flow_builder.py
│ │ ├── cache.py # LLM response caching
│ │ └── experimental/ # Experimental features
│ ├── loaders/ # Data loading & indexing
│ │ ├── attack_catalog.py
│ │ ├── attack_upsert.py
│ │ ├── opensearch_index.py
│ │ ├── hybrid_search.py
│ │ └── sigma_loader.py
│ ├── monitoring/ # Metrics & monitoring
│ │ ├── compliance_metrics.py
│ │ ├── defense_metrics.py
│ │ ├── drift_detector.py
│ │ └── ml_metrics.py
│ ├── services/ # API & services
│ │ ├── api/ # FastAPI application
│ │ │ ├── main.py
│ │ │ ├── routes/ # API route handlers
│ │ │ └── middleware/
│ │ ├── technique_cache.py
│ │ └── actor_cache.py
│ ├── simulation/ # Attack simulation
│ │ ├── attack_simulator.py
│ │ ├── mdp_solver.py
│ │ └── ptg_rollout.py
│ └── store/ # Data stores
│ ├── report_store.py
│ ├── candidate_store.py
│ └── review_store.py
├── ui/ # Next.js frontend
│ ├── app/ # App Router pages
│ │ ├── reports/ # Report management
│ │ ├── analytics/ # Analytics dashboards
│ │ └── health/ # Health monitoring
│ ├── components/ # React components
│ └── hooks/ # Custom React hooks
├── tests/ # Test suite
├── samples/ # Sample reports
├── scripts/ # Utility scripts
└── docs/ # Documentation
Pipeline de extracción (bandjacks/llm/)
extraction_pipeline.py - Orquestador principal de extracciónchunked_extractor.py - Procesamiento estándar por fragmentosoptimized_chunked_extractor.py - Procesamiento optimizado avanzadoagents_v2.py - Agentes de extracción centrales (SpanFinder, Mapper, Consolidator)entity_extractor.py - Agente de reconocimiento de entidadesflow_builder.py - Generación de flujo de ataquememory.py - Memoria de trabajo compartidacache.py - Caché de respuestas del LLMCapa de datos (bandjacks/loaders/)
Capa de API (bandjacks/services/api/)
El sistema admite LLMs en la nube y cualquier API local compatible con OpenAI:```bash
LOCAL_LLM_API_BASE=http://192.168.1.100:8080/v1 LOCAL_LLM_MODEL=mistral-nemo LOCAL_LLM_API_KEY=no-key # optional — most local servers don't require a key
PRIMARY_LLM=gemini # "gemini" (default) or "openai" GOOGLE_API_KEY=your-key # Gemini OPENAI_API_KEY=your-key # OpenAI (used as fallback when Gemini is primary)
**Prioridad del proveedor:** API local > Gemini > OpenAI > proxy LiteLLM.
Cuando un servidor local está configurado, los proveedores en la nube se añaden automáticamente como fallbacks.
#### Ejemplos comunes de servidores locales
| Servidor | `LOCAL_LLM_API_BASE` | `LOCAL_LLM_MODEL` |
|----------|----------------------|-------------------|
| vLLM | `http://host:8000/v1` | `mistralai/Mistral-Nemo-Instruct-2407` |
| llama.cpp | `http://host:8080/v1` | `mistral-nemo` |
| Ollama | `http://host:11434/v1` | `mistral-nemo` |
| LM Studio | `http://host:1234/v1` | `mistral-nemo` |
| LocalAI | `http://host:8080/v1` | `mistral-nemo` |
### Configuración de extracción
El sistema utiliza un único pipeline asíncrono de alto rendimiento con opciones configurables:```python
{
"cache_llm_responses": True, # Enable LLM caching (default: True)
"single_pass_threshold": 500, # Max words for single-pass (default: 500)
"early_termination_confidence": 90, # Skip verification above this (default: 90)
"disable_discovery": False, # Disable LLM discovery agent
"max_spans": 20, # Maximum spans to process
"span_score_threshold": 0.7, # Minimum span quality
"top_k": 5, # Candidates per span
# Cost optimization options
"max_spans_per_technique": 2, # Pre-filter: max spans per candidate technique (0=disable, default=2)
"enable_span_dedup": False, # Text-based span dedup before mapping (default=False)
}
El pipeline de extracción rastrea los costos de LLM mediante litellm.completion_cost() con métricas por informe y un endpoint de agregado diario.
Controles de costos:
Monitoreo:```bash
curl http://localhost:8000/v1/costs/stats
curl http://localhost:8000/v1/reports/{id} # -> extraction.metrics.cost_usd
### Umbrales de Confianza
Controla la calidad de la extracción```python
{
"confidence_threshold": 50.0, # Minimum confidence (0-100)
"auto_ingest": True # Auto-add high-confidence results
}
La API proporciona puntos finales completos de monitoreo de salud para supervisión operativa e implementaciones en Kubernetes:
curl http://localhost:8000/health
curl http://localhost:8000/health/live
curl http://localhost:8000/health/ready
curl http://localhost:8000/health/components/neo4j curl http://localhost:8000/health/components/opensearch curl http://localhost:8000/health/components/redis curl http://localhost:8000/health/components/caches curl http://localhost:8000/health/components/system
### Ejemplo de Respuesta de Salud```json
{
"status": "healthy",
"timestamp": "2025-01-28T17:43:30.184036Z",
"version": "1.0.0",
"components": {
"neo4j": {
"status": "healthy",
"latency_ms": 5
},
"opensearch": {
"status": "degraded",
"cluster_status": "yellow",
"indices": {
"attack_nodes": false,
"bandjacks_reports": true
}
},
"redis": {
"status": "healthy",
"latency_ms": 2,
"memory_mb": 1.69
},
"caches": {
"status": "healthy",
"technique_cache": {
"count": 993,
"loaded": true
},
"actor_cache": {
"count": 145,
"loaded": true
}
},
"system": {
"status": "healthy",
"memory": {
"available_gb": 8.84,
"percent_used": 72.4
},
"disk": {
"available_gb": 353.11,
"percent_used": 2.9
},
"cpu": {
"percent_used": 7.7
}
}
}
}
Para despliegues en Kubernetes, configure los probes de la siguiente manera:```yaml livenessProbe: httpGet: path: /health/live port: 8000 initialDelaySeconds: 30 periodSeconds: 10
readinessProbe: httpGet: path: /health/ready port: 8000 initialDelaySeconds: 45 periodSeconds: 5
## Optimización del Rendimiento
### Almacenamiento en Caché
El sistema incluye almacenamiento en caché automático de respuestas de LLM para mejorar el rendimiento:```python
# Check cache statistics
response = httpx.get("http://localhost:8000/v1/cache/stats")
stats = response.json()
print(f"Cache hit rate: {stats['hit_rate']}")
# Clear cache if needed
httpx.post("http://localhost:8000/v1/cache/clear")
Elige un perfil según tus necesidades:```python
fast_config = { "single_pass_threshold": 1000, "max_spans": 5, "skip_verification": True, "top_k": 3 }
balanced_config = { "single_pass_threshold": 500, "max_spans": 10, "early_termination_confidence": 90, "top_k": 5 }
quality_config = { "single_pass_threshold": 200, "max_spans": 20, "disable_discovery": False, "min_quotes": 3, "top_k": 10 }
## Seguridad
### Validación de Entrada
- **Prevención de Inyección Cypher**: Todos los endpoints de consulta de grafos validan los parámetros `relationship_types` proporcionados por el usuario contra una lista blanca de tipos de relación conocidos (USES, MITIGATES, HAS_TACTIC, etc.) más un patrón de regex estricto (`^[A-Z][A-Z0-9_]*$`). La entrada no válida devuelve 400 antes de la construcción de la consulta.
- **Validación de Esquema JSON**: Las respuestas de LLM se validan contra esquemas JSON para evitar que datos mal formados ingresen al pipeline.
- **Validación ADM**: Todo el contenido STIX debe pasar la validación del Modelo de Datos ATT&CK antes de la ingesta.
### Autenticación y Autorización
- **Autenticación JWT**: Middleware opcional para autenticación de API (`JWTAuthMiddleware`)
- **Limitación de Tasa**: Limitación de tasa por endpoint con umbrales configurables
- **CORS**: Intercambio de recursos de origen cruzado configurable
## Características Avanzadas
### Seguimiento de Procedencia
Cada entidad extraída incluye procedencia completa:```python
# Get provenance for an object
response = httpx.get(
"http://localhost:8000/v1/provenance/attack-pattern--abc123"
)
El sistema incluye una cola de revisión para mejorar la extracción:```python
response = httpx.get("http://localhost:8000/v1/review_queue/next")
response = httpx.post( "http://localhost:8000/v1/feedback/extraction", json={ "extraction_id": "ext-123", "correct": True, "corrections": [] } )
### Análisis de Cobertura
Analice su cobertura de inteligencia de amenazas:```python
# Get coverage analysis
response = httpx.get("http://localhost:8000/v1/analytics/coverage")
coverage = response.json()
print(f"Summary: {coverage['summary']}")
for tactic in coverage['tactics']:
print(f" {tactic['tactic']}: {tactic['coverage_percentage']}%")
Nota: Platform coverage (
_analyze_platforms_coverage) actualmente devuelve datos provisionales. La cobertura de tácticas y grupos utiliza consultas reales de Neo4j.
El módulo de simulación proporciona predicción de rutas de ataque basada en MDP:```python
from bandjacks.simulation.attack_simulator import AttackSimulator from bandjacks.simulation.mdp_solver import MDPSolver
## Estado de las Funcionalidades
Esta sección proporciona transparencia sobre el estado de implementación de diversas funcionalidades:
### Completamente Funcional ✅
- **Pipeline de Extracción de Informes** - La extracción de técnicas basada en LLM funciona de extremo a extremo
- **Carga de MITRE ATT&CK** - Carga datos ATT&CK empresariales/móviles/ICS en Neo4j
- **Búsqueda Vectorial** - Búsqueda semántica basada en OpenSearch para técnicas
- **Sistema de Revisión** - Flujo de trabajo de revisión con intervención humana a través de API y UI
- **Monitoreo de Salud** - Verificaciones de salud de componentes y sondas de Kubernetes
- **Comandos CLI de Consulta/Administración** - Búsqueda, recorrido de grafos, gestión de caché
- **Generación de Flujos de Ataque** - Construcción de flujos basada en co-ocurrencia para conjuntos de intrusiones
- **Simulación de Ataques** - Simulación de rutas basada en MDP mediante `/simulation/*` y `/simulate/*`
- **Informes de Cobertura** - Informes JSON para vistas ejecutiva, técnica, táctica y operativa
### Funcional con Dependencias de Datos ⚠️
- **Analítica de Co-ocurrencia** - Requiere nodos `AttackEpisode` del procesamiento de informes
- **Analítica de Actores** - Requiere episodios atribuidos a conjuntos de intrusiones
- **Paquetes de Técnicas** - Requiere suficientes datos de episodios para minería de patrones
- **Comandos CLI de Analítica** - Funcionan pero devuelven vacío si no existen episodios
### Solo API (Sin UI/CLI) 🔌
Estas son funcionalidades completamente implementadas accesibles solo a través de la API REST:
- **Simulación de Rutas de Ataque** - Rutas `/simulation/*` para predicción de rutas y análisis hipotético
- **Solucionador de Políticas MDP** - `/simulate/mdp` para cálculo de política de defensa óptima
- **Detección de Desviación** - Rutas `/drift/*` para monitorear la desviación en la calidad de los datos
- **Métricas de ML** - `/ml-metrics/*` para seguimiento del rendimiento del modelo a lo largo del tiempo
- **Gestión de Vectores** - `/vectors/*` para gestionar embeddings vectoriales
- **Lista de Ignorados de Entidades** - `/ignorelist/*` para filtrar entidades falsas positivas
- **Patrones Candidatos** - `/review/candidates/*` para candidatos de técnicas novedosas
- **Notificaciones** - `/notifications/*` para configuración e historial de alertas
- **Procedencia** - `/provenance/*` para seguimiento de linaje de extracción
- **Cumplimiento** - `/compliance/*` para informes de métricas de cumplimiento
### Experimental (en `llm/experimental/`) 🧪
- **PTG (Grafo de Amenazas Probabilístico)** - Lógica central implementada, pruebas limitadas
- **Integración de Juez** - Validación de secuencias basada en LLM
- **Simulador de Flujos de Ataque** - Motor de simulación basado en flujos
- **Extractor de Secuencias** - Extraer secuencias de flujos
### Eliminado/Limpiado 🗑️
Las siguientes funcionalidades esqueleto han sido eliminadas de la API:
- ~~Análisis de Cobertura de Plataformas~~ - Devolvía datos de prueba fijos
- ~~Análisis de Tendencias~~ - Devolvía datos sintéticos aleatorios
- ~~Exportación de Informes CSV/PDF~~ - Devolvía 501; ahora solo JSON
- ~~Inferencia de Secuencias Gemini~~ - Era un esqueleto 501; usar `/sequence/propose` en su lugar
### Matriz de Conectividad
| Área de Funcionalidad | Interfaz de Usuario | CLI | API REST |
|------------------------|----------------------|-----|----------|
| Gestión de Informes | ✅ | ✅ | ✅ |
| Flujo de Revisión | ✅ | ✅ | ✅ |
| Búsqueda (TTX) | ✅ | ✅ | ✅ |
| Analítica de Co-ocurrencia | ✅ | ✅ | ✅ |
| Analítica de Cobertura | ✅ | - | ✅ |
| Monitoreo de Salud | ✅ | - | ✅ |
| Detecciones/Sigma | ✅ | - | ✅ |
| Flujos de Ataque | ✅ | - | ✅ |
| Superposición de Defensa | ✅ | - | ✅ |
| Secuencias/PTG | ✅ | - | ✅ |
| Actores | ✅ | - | ✅ |
| Simulación de Ataques | - | - | ✅ |
| Detección de Desviación | - | - | ✅ |
| Métricas de ML | - | - | ✅ |
| Gestión de Vectores | - | - | ✅ |
| Lista de Ignorados de Entidades | - | - | ✅ |
| Patrones Candidatos | - | - | ✅ |
| Notificaciones | - | - | ✅ |
| Procedencia | - | - | ✅ |
| Cumplimiento | - | - | ✅ |
### Páginas del Frontend
| Página | Estado | Notas |
|--------|--------|-------|
| `/reports` | ✅ Funcionando | Listar, crear, ver informes |
| `/reports/[id]/review` | ✅ Funcionando | Flujo de revisión completo |
| `/analytics/cooccurrence` | ⚠️ Dependiente de datos | Muestra KPIs si existen episodios |
| `/analytics/cooccurrence/pairs` | ⚠️ Dependiente de datos | Llama a la API real |
| `/analytics/cooccurrence/bundles` | ⚠️ Dependiente de datos | Llama a la API real |
| `/analytics/cooccurrence/actors` | ⚠️ Dependiente de datos | Llama a la API real |
| `/health` | ✅ Funcionando | Estado de salud en tiempo real |
## Solución de Problemas
### Problemas Comunes
1. **Conexión a OpenSearch fallida**
- Asegúrate de que OpenSearch esté en ejecución: `curl http://localhost:9200`
- Verifica que el índice exista: `curl http://localhost:9200/bandjacks_attack_nodes-v1`
2. **Conexión a Neo4j fallida**
- Verifica que Neo4j esté en ejecución: `neo4j status`
- Comprueba que `NEO4J_PASSWORD` esté configurada en el archivo `.env`
- Asegúrate de que la contraseña coincida con tu instancia de Neo4j
- Si ves "NEO4J_PASSWORD environment variable is required", debes configurarla en tu archivo `.env`
3. **Bajo recall de extracción**
- Asegúrate de estar usando el método `agentic_v2`
- Verifica que la clave API de LLM sea válida
- Confirma que el nombre del modelo sea correcto (gemini-flash-latest)
4. **Errores de tiempo de espera**
- Aumenta la configuración de tiempo de espera para documentos grandes
- Considera dividir informes muy grandes en fragmentos
5. **El frontend no se conecta a la API**
- Asegúrate de que la API se esté ejecutando en el puerto 8000
- Verifica la configuración de CORS en la configuración de la API
### Modo de Depuración
Habilitar registro detallado:```python
import logging
logging.basicConfig(level=logging.DEBUG)
# Run extraction with debug output
result = run_agentic_v2(text, config)
uv run pytest tests/unit
uv run pytest tests/integration
uv run pytest tests/test_agentic_v2.py::test_extraction
uv run pytest --cov=bandjacks
cd ui && npm test cd ui && npm run test:coverage
### Contribuyendo
1. Haz un fork del repositorio
2. Crea una rama de funcionalidad
3. Realiza tus cambios
4. Ejecuta las pruebas: `uv run pytest`
5. Ejecuta el linting: `uv run ruff check`
6. Envía una solicitud de extracción
### Calidad del Código```bash
# Format code
uv run ruff format
# Check linting
uv run ruff check
# Type checking
uv run mypy bandjacks
[Tu Licencia Aquí]
Frontend (ui/)
| Opción | Valor por defecto | Efecto | Impacto en la Calidad |
|---|
MAX_MAPPER_BATCH_SIZE (env var) | 10 | Spans por llamada al mapper LLM (reducido de 25 en 2026-05; las respuestas en la nube tienen un límite de ~800 tokens, ~12% de los lotes más grandes devolvían JSON truncado) | Ninguno |
max_spans_per_technique (config) | 2 | Prefiltro: mejores N spans por técnica candidata | ~19% menos técnicas, mayor confianza |
enable_span_dedup (config) | false | Eliminar texto de span duplicado antes del mapeo | ~15% menos técnicas |