Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Dop2Mop — Recolector OpenGraph para BloodHound que mapea rutas de ataque desde infraestructura DevOps a MLOps, recopilando recursos de pipeline CI/CD, service principal y plataforma ML para análisis de movimiento lateral. | Kitploit
Herramientas/GitHubGitHub/h4wkst3r/dop2mop
Seguridad de Infraestructura en la NubeReconocimientoSeguridad de ContenedoresAnálisis de VulnerabilidadesRecopilación de InformaciónPruebas de PenetraciónSeguridad en la NubeDevSecOpsGestión de Identidad y Acceso (IAM)Seguridad de Cadena de SuministroRed Teaming
41hace 4 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
GitHubh4wkst3r/dop2mop

Dop2Mop

Recolector OpenGraph para BloodHound que mapea rutas de ataque desde infraestructura DevOps a MLOps, recopilando recursos de pipeline CI/CD, service principal y plataforma ML para análisis de movimiento lateral.

Ver Repositorio
Compartir

Dop2Mop

Un recolector OpenGraph de prueba de concepto para BloodHound que mapea rutas de ataque desde infraestructura DevOps hasta MLOps.

Basado en Pipelines of Privilege: Attack Paths from DevOps to MLOps Infrastructure de Brett Hawkins (@h4wkst3r).

Tabla de Contenidos

  • Agradecimientos
  • Resumen
    • Plataformas Compatibles
    • Límites de Confianza Mapeados
  • Instalación
    • Dependencias Opcionales
  • Inicio Rápido
    • Generar Datos de Demostración
    • Ingestar en BloodHound
  • Configuración
    • Archivo de Configuración
    • Validación de Credenciales
  • Referencia CLI
    • Resumen de Comandos
    • Opciones Globales
    • dop2mop collect
    • dop2mop demo
  • Ejemplos de Uso de CLI
    • Recolección Básica
    • Recolección de una Sola Plataforma
    • Recolección de Múltiples Plataformas
    • Ejemplos de Recolección de GitHub
    • Ejemplos de Recolección de Azure DevOps
    • Ejemplos de Recolección de Azure ML
    • Ejemplos de Recolección de AWS SageMaker
    • Recolección Completa del Entorno
  • Variables de Entorno
  • Tipos de Nodo
    • Nodos DevOps
    • Nodos MLOps
    • Nodos de Identidad
    • Nodos de Artefacto
  • Tipos de Borde
    • Bordes de Ruta de Ataque
    • Bordes Estructurales
  • Consultas de Ejemplo
  • Iconos Personalizados
    • Subir Iconos a BloodHound
  • API de Python
    • Usar Recolectores Individuales
    • Construir Grafos Personalizados
  • Solución de Problemas
    • Problemas Comunes
  • Licencia

Agradecimientos

  • SpecterOps por BloodHound y OpenGraph

Resumen

Dop2Mop recolecta datos de plataformas DevOps y MLOps para identificar rutas de ataque que permiten movimiento lateral desde pipelines CI/CD hasta infraestructura de entrenamiento de machine learning. Genera JSON OpenGraph compatible con BloodHound para visualización y análisis.

Plataformas Compatibles

Plataformas DevOpsPlataformas MLOpsProveedores de Identidad
GitHub (Actions, Repos, Secrets)Azure Machine LearningAzure AD Service Principals
Azure DevOps (Pipelines, Service Connections)Amazon SageMakerAWS IAM Roles
OIDC/Federated Identity

Límites de Confianza Mapeados

Dop2Mop modela los cinco límites de confianza críticos identificados en la investigación:

  1. TB1: Repositorio de Código a Pipeline CI/CD - Activación automática de pipelines a partir de commits de código
  2. TB2: Autenticación de Principal de Servicio - Credenciales NHI usadas por pipelines para acceder a plataformas ML
  3. TB3: Confianza en Artefacto de Contenedor - Confianza implícita en imágenes de contenedor de registros internos
  4. TB4: Ejecución de Definición de Trabajo - Plataformas ML ejecutando definiciones de trabajo sin validación
  5. TB5: Deserialización de Código - Deserialización insegura de datasets (pickle, joblib)

Instalación```bash

git clone https://github.com/h4wkst3r/dop2mop.git cd dop2mop pip install -r requirements.txt pip install -e .

root@kitploit:~
## Lo que se recopila

Cada recopilador reúne recursos específicos de la plataforma y mapea los límites de confianza entre ellos:

| Recopilador | Recursos Recopilados |
|-----------|-------------------|
| **GitHub** | Organizaciones, repositorios, flujos de trabajo, secretos, reglas de protección de ramas, configuraciones OIDC, referencias de imágenes de contenedores, referencias de buckets S3 |
| **Azure DevOps** | Organizaciones, proyectos, pipelines (YAML), conexiones de servicio (con detalles de ámbito), grupos de variables, pools de agentes, repositorios |
| **Azure ML** | Espacios de trabajo, clústeres/instancias de cómputo, almacenes de datos, entornos de ML, modelos registrados, trabajos/experimentos, endpoints en línea y por lotes |
| **SageMaker** | Trabajos de entrenamiento, modelos, endpoints, dominios, instancias de notebook, roles de ejecución de IAM (con análisis de políticas), repositorios/imágenes de ECR, buckets de S3 (filtrados para relevantes de ML) |

## Inicio Rápido

### Generar Datos de Demostración

La forma más rápida de ver Dop2Mop en acción es generar datos de demostración que muestren los escenarios de ataque de la investigación:```bash
dop2mop demo -o demo.json

Ingesta en BloodHound

  1. Abra BloodHound CE (v8.0+)
  2. Navegue a Administración → Ingesta de archivos
  3. Cargue el archivo JSON generado
  4. Consulte con Cypher:
root@kitploit:~
MATCH (n) RETURN n LIMIT 100
``````cypher
// Azure DevOps to Azure ML Lateral Movement
MATCH p=(repo)-[:TriggersPipeline]->(pipeline)-[:UsesServiceConnection]->(svcconn)-[:AuthenticatesAs]->(workspace)-[:CodeExecution]->(compute)
RETURN p

// Container Image Poisoning (Supply Chain Attack)
MATCH p=(workflow)-[:CanPoisonImage]->(image)<-[:PullsImage]-(job)
RETURN p

// OIDC/Federated Identity Abuse (confirmed edges)
MATCH p=(workflow)-[:OIDCTrust]->(oidc)-[:CanAssumeRole]->(role)-[:SubmitsJob]->(job)
RETURN p

// OIDC abuse including inferred paths
MATCH p=(workflow)-[:OIDCTrust]->(oidc)-[:InferredCanAssumeRole]->(role)
RETURN p

// Dataset Poisoning via Pickle Deserialization
MATCH p=(workflow)-[:CanPoisonDataset]->(dataset)<-[:LoadsDataset]-(job)
RETURN p

// Find repos with weak/no branch protection (TB1 exploitable)
MATCH (repo)-[:BypassesProtection]->(repo)
RETURN repo.name, repo.default_branch

// Find overprivileged SageMaker IAM roles
MATCH (role:IAMRole) WHERE role.is_admin = true OR role.has_s3_full_access = true
RETURN role.name, role.attached_policies

// Find SageMaker notebooks with root + internet access
MATCH (nb:SMNotebook) WHERE nb.root_access = 'Enabled' AND nb.direct_internet_access = 'Enabled'
RETURN nb.name, nb.status

// Find self-hosted ADO agent pools
MATCH (agent:ADOAgent) WHERE agent.is_hosted = false
RETURN agent.name, agent.pool_type

Configuración

Archivo de configuración

En lugar de pasar credenciales en cada ejecución, puedes guardarlas en un archivo de configuración. Copia el ejemplo incluido y completa tus valores:```bash cp dop2mop.yaml.example dop2mop.yaml

Edit dop2mop.yaml with your credentials

root@kitploit:~
Dop2Mop comprueba estas ubicaciones en orden:

1. Ruta especificada por `--config`
2. `dop2mop.yaml` / `dop2mop.yml` / `.dop2mop.yaml` en el directorio actual
3. `~/.dop2mop.yaml`

> **Nota:** `dop2mop.yaml` está en `.gitignore` para evitar confirmar credenciales accidentalmente. El archivo de ejemplo (`dop2mop.yaml.example`) es seguro para confirmar.

Consulta [dop2mop.yaml.example](https://github.com/h4wkst3r/dop2mop/blob/HEAD/dop2mop.yaml.example) para conocer todas las opciones disponibles con comentarios.

**Orden de prioridad:** Argumentos de CLI > archivo de configuración > variables de entorno.

### Validación de credenciales

Prueba las credenciales antes de ejecutar una recolección completa:```bash
# Validate all configured collectors
dop2mop collect --validate -v

# Validate specific collectors
dop2mop collect --validate --collectors github,sagemaker -v

Esto realiza una llamada ligera a la API por plataforma para verificar que los tokens sean válidos antes de iniciar la recopilación.

Alias de Collector

Puede usar nombres cortos en lugar de nombres de clase completos con --collectors:

These are equivalent:

dop2mop collect --collectors GitHubCollector,SageMakerCollector dop2mop collect --collectors github,sagemaker dop2mop collect --collectors gh,sm

root@kitploit:~
---

## Referencia de CLI

### Descripción general de comandos```
dop2mop <command> [options]

Commands:
  collect    Collect data from DevOps/MLOps platforms
  demo       Generate demo data with attack scenarios

Opciones Globales

OpciónDescripción
-v, --verboseHabilitar salida detallada (registro a nivel INFO)
--debugHabilitar salida de depuración (registro a nivel DEBUG)

dop2mop collect

Recolectar datos de plataformas DevOps y MLOps configuradas.```bash dop2mop collect [OPTIONS]

root@kitploit:~
#### Opciones generales

| Opción | Descripción |
|--------|-------------|
| `-o, --output FILE` | Ruta del archivo de salida (predeterminado: `dop2mop_output.json`) |
| `--zip` | Comprimir la salida en un archivo ZIP |
| `--config FILE` | Ruta al archivo de configuración YAML/JSON |
| `--validate` | Validar credenciales antes de la recolección |
| `--collectors LIST` | Lista separada por comas de recolectores o alias (p. ej., `github,sm`) |
| `--max-items N` | Número máximo de elementos a recolectar por tipo |
| `--no-secrets` | Omitir enumeración de secretos/credenciales |

#### Opciones de GitHub

| Opción | Descripción |
|--------|-------------|
| `--github-token TOKEN` | Token de acceso personal de GitHub |
| `--github-org ORG` | Nombre de la organización de GitHub |
| `--github-enterprise-url URL` | URL del servidor de GitHub Enterprise |

#### Opciones de Azure DevOps

| Opción | Descripción |
|--------|-------------|
| `--azure-devops-token TOKEN` | Token de acceso personal (PAT) de Azure DevOps |
| `--azure-devops-access-token TOKEN` | Token de acceso de Azure DevOps (autenticación Bearer, opcional) |
| `--azure-devops-org ORG` | Nombre de la organización de Azure DevOps |

#### Opciones de Azure ML

| Opción | Descripción |
|--------|-------------|
| `--azure-subscription-id ID` | ID de suscripción de Azure |
| `--azure-tenant-id ID` | ID de inquilino de Azure AD |
| `--azure-client-id ID` | ID de cliente de la entidad de servicio (opcional) |
| `--azure-client-secret SECRET` | Secreto de cliente de la entidad de servicio (opcional) |
| `--azure-access-token TOKEN` | Token de acceso de Azure para autenticación de Azure ML (opcional) |

#### Opciones de AWS SageMaker

| Opción | Descripción |
|--------|-------------|
| `--aws-access-key-id KEY` | ID de clave de acceso de AWS |
| `--aws-secret-access-key SECRET` | Clave de acceso secreta de AWS |
| `--aws-region REGION` | Región de AWS (predeterminado: `us-east-1`) |
| `--aws-profile PROFILE` | Nombre del perfil de AWS CLI |

#### Recolectores disponibles

| Nombre del recolector | Plataforma | Credenciales requeridas |
|----------------|----------|---------------------|
| `GitHubCollector` | GitHub | `--github-token`, `--github-org` |
| `AzureDevOpsCollector` | Azure DevOps | `--azure-devops-token` o `--azure-devops-access-token`, `--azure-devops-org` |
| `AzureMLCollector` | Azure ML | `--azure-subscription-id`, `--azure-tenant-id` |
| `SageMakerCollector` | AWS SageMaker | `--aws-profile` o `--aws-access-key-id` |

---

### `dop2mop demo`

Generar datos de demostración que muestren los cuatro escenarios de ataque de la investigación.```bash
dop2mop demo [OPTIONS]
OptionDescription
-o, --output FILERuta del archivo de salida (por defecto: dop2mop_demo.json)

dop2mop icons

Genera configuración de iconos personalizados para los tipos de nodos de BloodHound.```bash dop2mop icons [OPTIONS]

root@kitploit:~
| Opción | Descripción |
|--------|-------------|
| `-o, --output FILE` | Ruta del archivo de salida (por defecto: `dop2mop_icons.json`) |

---

## Ejemplos de uso de CLI

### Colección básica```bash
# Collect from all configured platforms (uses environment variables)
dop2mop collect -o output.json

# Use a config file
dop2mop collect --config dop2mop.yaml -o output.json -v

# Validate credentials first, then collect
dop2mop collect --validate -o output.json -v

# Collect with verbose logging
dop2mop collect -o output.json -v

# Collect with debug logging
dop2mop collect -o output.json --debug

# Collect and compress to ZIP
dop2mop collect -o output.json --zip

# Limit collection size
dop2mop collect --max-items 100 -o output.json

# Skip secret enumeration
dop2mop collect --no-secrets -o output.json

Colección de Plataforma Única```bash

GitHub only (aliases: github, gh)

dop2mop collect --collectors github -o github.json -v

Azure DevOps only (aliases: ado, azuredevops)

dop2mop collect --collectors ado -o ado.json -v

Azure ML only (aliases: azureml, azure-ml)

dop2mop collect --collectors azureml -o azureml.json -v

SageMaker only (aliases: sagemaker, sm)

dop2mop collect --collectors sm -o sagemaker.json -v

root@kitploit:~
### Colección multiplataforma```bash
# GitHub + SageMaker
dop2mop collect --collectors github,sagemaker -o output.json -v

# GitHub + Azure DevOps
dop2mop collect --collectors github,ado -o output.json -v

# Azure DevOps + Azure ML (full Azure stack)
dop2mop collect --collectors ado,azureml -o azure.json -v

# All collectors explicitly
dop2mop collect --collectors github,ado,azureml,sagemaker -o full.json -v

Ejemplos de Colección de GitHub```bash

Using environment variables

export GITHUB_TOKEN="ghp_xxxxxxxxxxxx" export GITHUB_ORG="your-org" dop2mop collect --collectors GitHubCollector -o github.json -v

Using command-line arguments

dop2mop collect --collectors GitHubCollector
--github-token ghp_xxxxxxxxxxxx
--github-org your-org
-o github.json -v

GitHub Enterprise Server

dop2mop collect --collectors GitHubCollector
--github-token ghp_xxxxxxxxxxxx
--github-org your-org
--github-enterprise-url https://github.yourcompany.com/api/v3
-o github.json -v

Skip secret enumeration

dop2mop collect --collectors GitHubCollector
--github-token ghp_xxxxxxxxxxxx
--github-org your-org
--no-secrets
-o github.json -v

Limit to 50 repositories

dop2mop collect --collectors GitHubCollector
--github-token ghp_xxxxxxxxxxxx
--github-org your-org
--max-items 50
-o github.json -v

root@kitploit:~
### Ejemplos de la colección de Azure DevOps```bash
# Using environment variables
export AZURE_DEVOPS_TOKEN="your-pat"
export AZURE_DEVOPS_ORG="your-org"
dop2mop collect --collectors AzureDevOpsCollector -o ado.json -v

# Using command-line arguments (PAT)
dop2mop collect --collectors AzureDevOpsCollector \
  --azure-devops-token your-pat \
  --azure-devops-org your-org \
  -o ado.json -v

# Using access token (Bearer auth)
dop2mop collect --collectors AzureDevOpsCollector \
  --azure-devops-access-token eyJ0... \
  --azure-devops-org your-org \
  -o ado.json -v

Nota: Prioridad de autenticación de Azure DevOps: token de acceso (Bearer) > PAT (Básico). Los tokens de acceso se pueden obtener mediante az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798.

Ejemplos de la Colección de Azure ML```bash

Using environment variables

export AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" export AZURE_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" dop2mop collect --collectors AzureMLCollector -o azureml.json -v

Using DefaultAzureCredential (az login)

dop2mop collect --collectors AzureMLCollector
--azure-subscription-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-tenant-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
-o azureml.json -v

Using Service Principal

dop2mop collect --collectors AzureMLCollector
--azure-subscription-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-tenant-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-client-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-client-secret your-secret
-o azureml.json -v

Using Access Token

dop2mop collect --collectors AzureMLCollector
--azure-subscription-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-tenant-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
--azure-access-token eyJ0...
-o azureml.json -v

root@kitploit:~
> **Nota:** Prioridad de autenticación de Azure ML: token de acceso > entidad de servicio > DefaultAzureCredential (az login).
> Los tokens de acceso se pueden obtener mediante `az account get-access-token --resource https://management.azure.com/`.

### Ejemplos de Colección de AWS SageMaker```bash
# Using AWS profile (environment variable)
export AWS_PROFILE="your-profile"
dop2mop collect --collectors SageMakerCollector -o sagemaker.json -v

# Using AWS profile (command-line)
dop2mop collect --collectors SageMakerCollector \
  --aws-profile your-profile \
  -o sagemaker.json -v

# Using access keys
dop2mop collect --collectors SageMakerCollector \
  --aws-access-key-id AKIAXXXXXXXXXXXXXXXX \
  --aws-secret-access-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  --aws-region us-east-1 \
  -o sagemaker.json -v

# Different AWS region
dop2mop collect --collectors SageMakerCollector \
  --aws-profile your-profile \
  --aws-region us-west-2 \
  -o sagemaker.json -v

Recopilación completa del entorno```bash

Set all environment variables

export GITHUB_TOKEN="ghp_xxxxxxxxxxxx" export GITHUB_ORG="your-org" export AZURE_DEVOPS_TOKEN="your-pat" export AZURE_DEVOPS_ORG="your-org" export AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" export AZURE_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" export AWS_PROFILE="your-profile"

Collect from all platforms (auto-detects configured collectors)

dop2mop collect -o full_collection.json -v

Or with explicit collectors

dop2mop collect
--collectors GitHubCollector,AzureDevOpsCollector,AzureMLCollector,SageMakerCollector
-o full_collection.json -v

root@kitploit:~
---

## Variables de Entorno

Todas las opciones de línea de comandos se pueden configurar mediante variables de entorno:

| Variable de Entorno | Equivalente CLI | Descripción |
|---------------------|----------------|-------------|
| `GITHUB_TOKEN` | `--github-token` | Token de acceso personal de GitHub |
| `GITHUB_ORG` | `--github-org` | Nombre de la organización de GitHub |
| `GITHUB_ENTERPRISE_URL` | `--github-enterprise-url` | URL de GitHub Enterprise Server |
| `AZURE_DEVOPS_TOKEN` | `--azure-devops-token` | PAT de Azure DevOps |
| `AZURE_DEVOPS_ACCESS_TOKEN` | `--azure-devops-access-token` | Token de acceso de Azure DevOps (Bearer) |
| `AZURE_DEVOPS_ORG` | `--azure-devops-org` | Organización de Azure DevOps |
| `AZURE_SUBSCRIPTION_ID` | `--azure-subscription-id` | ID de suscripción de Azure |
| `AZURE_TENANT_ID` | `--azure-tenant-id` | ID de inquilino de Azure AD |
| `AZURE_CLIENT_ID` | `--azure-client-id` | ID de cliente de la entidad de servicio de Azure |
| `AZURE_CLIENT_SECRET` | `--azure-client-secret` | Secreto de la entidad de servicio de Azure |
| `AZURE_ACCESS_TOKEN` | `--azure-access-token` | Token de acceso de Azure para Azure ML |
| `AWS_ACCESS_KEY_ID` | `--aws-access-key-id` | ID de clave de acceso de AWS |
| `AWS_SECRET_ACCESS_KEY` | `--aws-secret-access-key` | Clave de acceso secreta de AWS |
| `AWS_REGION` | `--aws-region` | Región de AWS (predeterminada: us-east-1) |
| `AWS_PROFILE` | `--aws-profile` | Nombre del perfil de AWS CLI |

**Prioridad:** argumentos CLI > archivo de configuración > variables de entorno.

---

## Tipos de Nodo

### Nodos de DevOps

| Tipo | Descripción |
|------|-------------|
| `GHOrganization` | Organización de GitHub |
| `GHRepository` | Repositorio de GitHub |
| `GHWorkflow` | Flujo de trabajo de GitHub Actions |
| `GHSecret` | Secreto de GitHub Actions |
| `ADOOrganization` | Organización de Azure DevOps |
| `ADOProject` | Proyecto de Azure DevOps |
| `ADOPipeline` | Pipeline de Azure DevOps |
| `ADOServiceConnection` | Conexión de servicio de Azure DevOps (NHI) con detalles de ámbito |
| `ADOAgent` | Grupo de agentes de Azure DevOps (alojado o autogestionado) |
| `ADOVariableGroup` | Grupo de variables de Azure DevOps |

### Nodos de MLOps

| Tipo | Descripción |
|------|-------------|
| `AzMLWorkspace` | Área de trabajo de Azure ML |
| `AzMLCompute` | Clúster/instancia de cómputo de Azure ML |
| `AzMLExperiment` | Trabajo/experimento de Azure ML |
| `AzMLDatastore` | Almacén de datos de Azure ML |
| `AzMLEnvironment` | Entorno de Azure ML (definición de contenedor) |
| `AzMLModel` | Modelo registrado de Azure ML |
| `SMDomain` | Dominio de SageMaker Studio |
| `SMTrainingJob` | Trabajo de entrenamiento de SageMaker |
| `SMModel` | Modelo de SageMaker |
| `SMEndpoint` | Punto de conexión de SageMaker (también usado para puntos de conexión de Azure ML) |
| `SMNotebook` | Instancia de cuaderno de SageMaker |

### Nodos de Identidad

| Tipo | Descripción |
|------|-------------|
| `ServicePrincipal` | Entidad de servicio de Azure AD |
| `IAMRole` | Rol de IAM de AWS |
| `OIDCIdentity` | Identidad federada OIDC |
| `ManagedIdentity` | Identidad administrada de Azure |

### Nodos de Artefacto

| Tipo | Descripción |
|------|-------------|
| `ContainerRegistry` | Registro de contenedores (ECR, ACR) |
| `ContainerImage` | Imagen de contenedor |
| `S3Bucket` | Bucket S3 de AWS |
| `Dataset` | Conjunto de datos de ML |

## Tipos de Arista

### Aristas de Ruta de Ataque

| Tipo | Límite de Confianza | Descripción |
|------|---------------------|-------------|
| `TriggersPipeline` | TB1 | El commit de código activa CI/CD |
| `HasBranchProtection` | TB1 | El repositorio tiene reglas de protección de ramas |
| `BypassesProtection` | TB1 | Protección de ramas débil/ausente (explotable) |
| `AuthenticatesAs` | TB2 | El pipeline usa una entidad de servicio |
| `CanAssumeRole` | TB2 | La identidad OIDC puede asumir un rol de IAM |
| `OIDCTrust` | TB2 | El flujo de trabajo usa federación OIDC |
| `UsesServiceConnection` | TB2 | El pipeline usa una conexión de servicio de ADO |
| `PullsImage` | TB3 | El trabajo de entrenamiento extrae una imagen de contenedor |
| `CanPoisonImage` | TB3 | El pipeline puede modificar la imagen de contenedor |
| `SubmitsJob` | TB4 | La entidad de servicio envía un trabajo de ML |
| `CodeExecution` | TB4 | El trabajo ejecuta código en el cómputo |
| `LoadsDataset` | TB5 | El trabajo de entrenamiento carga un conjunto de datos |
| `CanPoisonDataset` | TB5 | El pipeline puede modificar el conjunto de datos |
| `Deserializes` | TB5 | Deserialización no segura |

### Aristas Inferidas

Estas aristas se crean mediante análisis heurístico cuando no están disponibles datos explícitos de la API (por ejemplo, ARN de roles almacenados en secretos). Utilizan tipos de arista distintos para que puedas filtrarlos en las consultas de BloodHound.

| Tipo | Descripción |
|------|-------------|
| `InferredCanAssumeRole` | La identidad OIDC podría poder asumir un rol (inferido) |
| `InferredSubmitsJob` | El flujo de trabajo podría enviar un trabajo de entrenamiento mediante OIDC (inferido) |
| `InferredPullsImage` | El trabajo de entrenamiento podría extraer una imagen de contenedor envenenada (inferido) |
| `InferredLoadsDataset` | El trabajo de entrenamiento podría cargar un conjunto de datos envenenado (inferido) |

### Aristas Estructurales

| Tipo | Descripción |
|------|-------------|
| `Contains` | Relación padre-hijo |
| `MemberOf` | Pertenencia a grupo |
| `HasAccessTo` | Permiso para acceder a un recurso |
| `HasExecutionRole` | El recurso usa un rol de IAM/ejecución |
| `Owns` | Relación de propiedad |

## Consultas de Ejemplo

Consulta [queries/dop2mop_queries.cypher](https://github.com/h4wkst3r/dop2mop/blob/HEAD/queries/dop2mop_queries.cypher) para ejemplos completos de consultas.

---

## Iconos Personalizados

Dop2Mop incluye un archivo de iconos preconfigurado para tipos de nodo personalizados de BloodHound en [data/custom_icons.json](https://github.com/h4wkst3r/dop2mop/blob/HEAD/data/custom_icons.json).

### Subir Iconos a BloodHound

#### Opción 1: Explorador de API (Más Sencilla)

1. Abre BloodHound CE y ve a **Configuración** → **Explorador de API**
2. Busca **POST /api/v2/custom-nodes**
3. Haz clic en "Probar"
4. Pega el contenido de `custom_icons.json`
5. Haz clic en "Ejecutar"

#### Opción 2: Autenticación HMAC (Recomendada para Automatización)

Primero, crea un token de API en BloodHound:
1. Ve a **Configuración** → **Administración** → **Gestionar Usuarios**
2. Haz clic en tu usuario → **Crear Token**
3. Guarda el **ID de Token** y la **Clave de Token**

Luego, usa este script de Python para subir:```python
#!/usr/bin/env python3
"""Upload custom icons to BloodHound CE using HMAC authentication."""

import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
import requests

# Configuration
BLOODHOUND_URL = "http://localhost:8080"
TOKEN_ID = "your-token-id"
TOKEN_KEY = "your-token-key"
ICONS_FILE = "custom_icons.json"

def hmac_auth(method: str, uri: str, body: bytes = b"") -> dict:
    """Generate HMAC authentication headers."""
    digester = hmac.new(
        base64.b64decode(TOKEN_KEY),
        msg=None,
        digestmod=hashlib.sha256
    )
    
    now = datetime.now(timezone.utc)
    timestamp = now.strftime("%Y-%m-%dT%H:%M:%SZ")
    
    digester.update(f"{method}".encode())
    digester.update(f"{uri}".encode())
    digester.update(timestamp.encode())
    if body:
        digester.update(body)
    
    signature = base64.b64encode(digester.digest()).decode()
    
    return {
        "Authorization": f"bhesignature {TOKEN_ID}",
        "RequestDate": timestamp,
        "Signature": signature,
        "Content-Type": "application/json",
    }

def upload_icons():
    """Upload custom icons to BloodHound."""
    uri = "/api/v2/custom-nodes"
    url = f"{BLOODHOUND_URL}{uri}"
    
    with open(ICONS_FILE, "rb") as f:
        body = f.read()
    
    headers = hmac_auth("POST", uri, body)
    response = requests.post(url, headers=headers, data=body)
    
    print(f"Status: {response.status_code}")
    print(f"Response: {response.text}")
    return response.status_code == 200

if __name__ == "__main__":
    upload_icons()

Opción 3: Bearer Token (Prueba rápida)

Obtén un JWT desde la pestaña Red de DevTools de tu navegador mientras estás conectado a BloodHound:```bash curl -X POST http://localhost:8080/api/v2/custom-nodes
-H "Authorization: Bearer eyJ..."
-H "Content-Type: application/json"
-d @custom_icons.json

root@kitploit:~
---

## Python API```python
from dop2mop import Dop2MopCollector, CollectorConfig

# Configure collection
config = CollectorConfig(
    github_token="ghp_xxx",
    github_org="myorg",
    aws_profile="default",
)

# Validate credentials first
collector = Dop2MopCollector(config)
results = collector.validate_all()
print(results)  # {'GitHubCollector': True, 'SageMakerCollector': True, ...}

# Run collection (supports aliases)
collector.run(collectors=["github", "sm"])

# Save output
collector.save("output.json")

# Get statistics
print(collector.get_stats())

# Get per-collector failure/skip details
print(collector.get_collection_summary())

Usando Colectores Individuales```python

from dop2mop import CollectorConfig, GitHubCollector, SageMakerCollector from dop2mop.graph import OpenGraphBuilder

Create shared builder

builder = OpenGraphBuilder(source_kind="MLOpsBase")

Configure

config = CollectorConfig( github_token="ghp_xxx", github_org="myorg", aws_profile="default", )

Run individual collectors

github = GitHubCollector(config, builder) github.collect()

sagemaker = SageMakerCollector(config, builder) sagemaker.collect()

Save combined output

builder.save("combined.json")

root@kitploit:~
### Construyendo gráficos personalizados```python
from dop2mop.graph import OpenGraphBuilder
from dop2mop.models import NodeKind, EdgeType

builder = OpenGraphBuilder(source_kind="CustomSource")

# Add nodes
builder.create_node(
    id="my-pipeline",
    kinds=[NodeKind.AZURE_DEVOPS_PIPELINE.value],
    name="My Pipeline",
    displayname="Production Pipeline",
)

builder.create_node(
    id="my-ml-workspace",
    kinds=[NodeKind.AZURE_ML_WORKSPACE.value],
    name="ML Workspace",
    displayname="Training Workspace",
)

# Add edge
builder.create_edge(
    start_id="my-pipeline",
    end_id="my-ml-workspace",
    kind=EdgeType.SUBMITS_JOB,
    properties={"trust_boundary": "TB4"}
)

# Export
builder.save("custom_graph.json")

Solución de problemas

Validar primero

Comience siempre con la validación de credenciales para detectar problemas de autenticación de forma temprana:```bash dop2mop collect --validate --collectors github,sm -v

root@kitploit:~
La salida mostrará OK/FAILED por recolector antes de que comience cualquier recolección.

### Resumen de recolección

Después de cada ejecución, Dop2Mop imprime un resumen que muestra lo que se recolectó y lo que falló:```
============================================================
  Dop2Mop Collection Summary
============================================================
  Total Nodes: 142
    DevOps:   45
    MLOps:    38
    Identity: 12
    Artifact: 47

  Total Edges: 201
    Contains: 62
    TriggersPipeline: 15
    ...

  ────────────────────────────────────────────────────────
  Collection Issues:
    GitHubCollector: 45 collected, 3 failed, 1 skipped
      FAIL: branch_protection:org/repo - 404 Not Found
      SKIP: branch_protection:org/private - Insufficient permissions

  Output: output.json
============================================================

Problemas Comunes

"Colector de GitHub no configurado, omitiendo"

  • Asegúrate de que las variables de entorno GITHUB_TOKEN y GITHUB_ORG estén configuradas, o pasa --github-token y --github-org

"Colector de Azure ML no configurado, omitiendo"

  • Asegúrate de que AZURE_SUBSCRIPTION_ID y AZURE_TENANT_ID estén configuradas
  • Ejecuta az login si usas DefaultAzureCredential
  • Alternativamente, pasa --azure-access-token con un token válido de az account get-access-token

"Colector de SageMaker no configurado, omitiendo"

  • Configura AWS_PROFILE o ambas AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY
  • Asegúrate de que las credenciales tengan permisos de lectura en SageMaker

La protección de rama devuelve 403

  • La API de GitHub requiere acceso de administrador para leer las reglas de protección de rama
  • Los tokens que no sean de administrador omitirán la recopilación de protección de rama (reportado en el resumen)

Límite de velocidad (errores 429)

  • Dop2Mop reintenta automáticamente con retroceso exponencial en respuestas de límite de velocidad
  • Para organizaciones grandes, usa --max-items para reducir las llamadas a la API
  • Límites de velocidad de GitHub: 5,000 solicitudes/hora para usuarios autenticados

Sin resultados en la consola Cypher de BloodHound

  • Asegúrate de que las consultas devuelvan nodos completos (RETURN a, b) no propiedades (RETURN a.name, b.name)
  • La consola Cypher de BloodHound es para visualización de grafos, no datos tabulares
  • Usa Neo4j Browser (localhost:7474) para consultas basadas en propiedades

Filtrar aristas inferidas vs. recopiladas

  • Las aristas inferidas usan tipos distintos (por ejemplo, InferredCanAssumeRole en lugar de CanAssumeRole)
  • Consulta solo aristas confirmadas: MATCH p=()-[:CanAssumeRole]->() RETURN p
  • Consulta aristas inferidas: MATCH p=()-[:InferredCanAssumeRole]->() RETURN p

Licencia

Licencia MIT - Consulta LICENSE para más detalles.

Descargar herramienta
AliasCollector
github, ghGitHubCollector
ado, azuredevops, azure-devopsAzureDevOpsCollector
azureml, azure-mlAzureMLCollector
sagemaker, smSageMakerCollector