Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Dop2Mop — DevOps에서 MLOps 인프라로 이어지는 공격 경로를 매핑하는 BloodHound용 OpenGraph 수집기로, CI/CD 파이프라인, 서비스 주체 및 ML 플랫폼 리소스를 수집하여 측면 이동 분석을 수행합니다. | Kitploit
도구/GitHubGitHub/h4wkst3r/dop2mop
Cloud Infrastructure SecurityReconnaissanceContainer SecurityVulnerability AnalysisInformation GatheringPenetration TestingCloud SecurityDevSecOpsIdentity & Access Management (IAM)Supply Chain SecurityRed Teaming
414개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHub
h4wkst3r/dop2mop

Dop2Mop

DevOps에서 MLOps 인프라로 이어지는 공격 경로를 매핑하는 BloodHound용 OpenGraph 수집기로, CI/CD 파이프라인, 서비스 주체 및 ML 플랫폼 리소스를 수집하여 측면 이동 분석을 수행합니다.

저장소 보기

Dop2Mop

BloodHound를 위한 개념 증명 OpenGraph 수집기로, DevOps에서 MLOps 인프라로 이어지는 공격 경로를 매핑합니다.

Brett Hawkins(@h4wkst3r)의 Pipelines of Privilege: Attack Paths from DevOps to MLOps Infrastructure를 기반으로 합니다.

목차

  • 감사의 말
  • 개요
    • 지원 플랫폼
    • 매핑된 신뢰 경계
  • 설치
    • 선택적 종속성
  • 빠른 시작
    • 데모 데이터 생성
    • BloodHound로 수집
  • 설정
    • 설정 파일
    • 자격 증명 검증
  • CLI 참조
    • 명령 개요
    • 전역 옵션
    • dop2mop collect
    • dop2mop demo
  • CLI 사용 예제
    • 기본 수집
    • 단일 플랫폼 수집
    • 다중 플랫폼 수집
    • GitHub 수집 예제
    • Azure DevOps 수집 예제
    • Azure ML 수집 예제
    • AWS SageMaker 수집 예제
    • 전체 환경 수집
  • 환경 변수
  • 노드 유형
    • DevOps 노드
    • MLOps 노드
    • ID 노드
    • 아티팩트 노드
  • 엣지 유형
    • 공격 경로 엣지
    • 구조적 엣지
  • 예제 쿼리
  • 사용자 정의 아이콘
    • BloodHound에 아이콘 업로드
  • Python API
    • 개별 수집기 사용
    • 사용자 정의 그래프 구축
  • 문제 해결
    • 일반적인 문제
  • 라이선스

감사의 말

  • BloodHound와 OpenGraph를 제공한 SpecterOps

개요

Dop2Mop은 DevOps 및 MLOps 플랫폼에서 데이터를 수집하여 CI/CD 파이프라인에서 기계 학습 훈련 인프라로의 측면 이동을 가능하게 하는 공격 경로를 식별합니다. 시각화 및 분석을 위해 BloodHound와 호환되는 OpenGraph JSON을 출력합니다.

지원 플랫폼

DevOps 플랫폼MLOps 플랫폼ID 공급자
GitHub (Actions, Repos, Secrets)Azure Machine LearningAzure AD Service Principals
Azure DevOps (Pipelines, Service Connections)Amazon SageMakerAWS IAM Roles
OIDC/Federated Identity

매핑된 신뢰 경계

Dop2Mop은 연구에서 식별된 다섯 가지 중요한 신뢰 경계를 모델링합니다:

  1. TB1: 코드 저장소에서 CI/CD 파이프라인으로 - 코드 커밋으로 인한 파이프라인 자동 트리거
  2. TB2: 서비스 주체 인증 - 파이프라인이 ML 플랫폼에 액세스하는 데 사용하는 NHI 자격 증명
  3. TB3: 컨테이너 아티팩트 신뢰 - 내부 레지스트리에서 컨테이너 이미지에 대한 암묵적 신뢰
  4. TB4: 작업 정의 실행 - 검증 없이 작업 정의를 실행하는 ML 플랫폼
  5. TB5: 코드 역직렬화 - 데이터셋의 안전하지 않은 역직렬화(pickle, joblib)

설치```bash

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

root@kitploit:~
## 수집되는 정보

각 수집기는 플랫폼별 리소스를 수집하고 그들 사이의 신뢰 경계를 매핑합니다:

| 수집기 | 수집된 리소스 |
|-----------|-------------------|
| **GitHub** | 조직, 리포지토리, 워크플로우, 시크릿, 브랜치 보호 규칙, OIDC 구성, 컨테이너 이미지 참조, S3 버킷 참조 |
| **Azure DevOps** | 조직, 프로젝트, 파이프라인 (YAML), 서비스 연결 (범위 세부 정보 포함), 변수 그룹, 에이전트 풀, 리포지토리 |
| **Azure ML** | 작업 영역, 컴퓨트 클러스터/인스턴스, 데이터 저장소, ML 환경, 등록된 모델, 작업/실험, 온라인 및 배치 엔드포인트 |
| **SageMaker** | 훈련 작업, 모델, 엔드포인트, 도메인, 노트북 인스턴스, IAM 실행 역할 (정책 분석 포함), ECR 리포지토리/이미지, S3 버킷 (ML 관련으로 필터링됨) |

## 빠른 시작

### 데모 데이터 생성

Dop2Mop을 실제로 확인하는 가장 빠른 방법은 연구에서 나온 공격 시나리오를 보여주는 데모 데이터를 생성하는 것입니다:```bash
dop2mop demo -o demo.json

BloodHound로 수집

  1. BloodHound CE (v8.0+)를 엽니다.
  2. 관리 → 파일 수집으로 이동합니다.
  3. 생성된 JSON 파일을 업로드합니다.
  4. Cypher로 질의:
root@kitploit:~
MATCH (n:Group {name: "DOMAIN [email protected]"})
CALL {
  WITH n
  OPTIONAL MATCH (n)-[:MemberOf]->(g:Group)
  RETURN collect(g.name) AS groupMembership
}
CALL {
  WITH n
  OPTIONAL MATCH (n)-[:AdminTo]->(c:Computer)
  RETURN collect(c.name) AS adminTo
}
CALL {
  WITH n
  OPTIONAL MATCH (n)-[:HasSession]->(c:Computer)
  RETURN collect(c.name) AS hasSession
}
RETURN n.name AS groupName, groupMembership, adminTo, hasSession
``````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

Configuration

Config File

매번 실행할 때마다 자격 증명을 전달하는 대신, 설정 파일에 저장할 수 있습니다. 포함된 예제를 복사하여 값을 입력하세요:```bash cp dop2mop.yaml.example dop2mop.yaml

Edit dop2mop.yaml with your credentials

root@kitploit:~
Dop2Mop은 다음 위치를 순서대로 확인합니다:

1. `--config`로 지정된 경로
2. 현재 디렉토리의 `dop2mop.yaml` / `dop2mop.yml` / `.dop2mop.yaml`
3. `~/.dop2mop.yaml`

> **참고:** `dop2mop.yaml`은 실수로 자격 증명을 커밋하는 것을 방지하기 위해 `.gitignore`에 있습니다. 예제 파일(`dop2mop.yaml.example`)은 커밋해도 안전합니다.

모든 옵션과 설명은 [dop2mop.yaml.example](https://github.com/h4wkst3r/dop2mop/blob/HEAD/dop2mop.yaml.example)을 참조하세요.

**우선순위:** CLI 인수 > 구성 파일 > 환경 변수.

### 자격 증명 검증

전체 수집을 실행하기 전에 자격 증명을 테스트하세요:```bash
# Validate all configured collectors
dop2mop collect --validate -v

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

이는 각 플랫폼에 대해 경량 API 호출을 수행하여 수집을 시작하기 전에 토큰이 유효한지 확인합니다.

수집기 별칭

--collectors와 함께 전체 클래스 이름 대신 짧은 이름을 사용할 수 있습니다:

These are equivalent:

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

root@kitploit:~
---

## CLI 참조

### 명령어 개요```
dop2mop <command> [options]

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

전역 옵션

옵션설명
-v, --verbose자세한 출력 활성화 (INFO 수준 로깅)
--debug디버그 출력 활성화 (DEBUG 수준 로깅)

dop2mop collect

구성된 DevOps 및 MLOps 플랫폼에서 데이터를 수집합니다.```bash dop2mop collect [OPTIONS]

root@kitploit:~
#### 일반 옵션

| 옵션 | 설명 |
|--------|-------------|
| `-o, --output FILE` | 출력 파일 경로 (기본값: `dop2mop_output.json`) |
| `--zip` | 출력을 ZIP 파일로 압축 |
| `--config FILE` | YAML/JSON 설정 파일 경로 |
| `--validate` | 수집 전 자격 증명 검증 |
| `--collectors LIST` | 쉼표로 구분된 수집기 또는 별칭 목록 (예: `github,sm`) |
| `--max-items N` | 유형별 최대 수집 항목 수 |
| `--no-secrets` | 비밀/자격 증명 열거 건너뛰기 |

#### GitHub 옵션

| 옵션 | 설명 |
|--------|-------------|
| `--github-token TOKEN` | GitHub 개인 액세스 토큰 |
| `--github-org ORG` | GitHub 조직 이름 |
| `--github-enterprise-url URL` | GitHub Enterprise Server URL |

#### Azure DevOps 옵션

| 옵션 | 설명 |
|--------|-------------|
| `--azure-devops-token TOKEN` | Azure DevOps 개인 액세스 토큰 (PAT) |
| `--azure-devops-access-token TOKEN` | Azure DevOps 액세스 토큰 (Bearer 인증, 선택 사항) |
| `--azure-devops-org ORG` | Azure DevOps 조직 이름 |

#### Azure ML 옵션

| 옵션 | 설명 |
|--------|-------------|
| `--azure-subscription-id ID` | Azure 구독 ID |
| `--azure-tenant-id ID` | Azure AD 테넌트 ID |
| `--azure-client-id ID` | 서비스 주체 클라이언트 ID (선택 사항) |
| `--azure-client-secret SECRET` | 서비스 주체 클라이언트 비밀 (선택 사항) |
| `--azure-access-token TOKEN` | Azure ML 인증용 Azure 액세스 토큰 (선택 사항) |

#### AWS SageMaker 옵션

| 옵션 | 설명 |
|--------|-------------|
| `--aws-access-key-id KEY` | AWS 액세스 키 ID |
| `--aws-secret-access-key SECRET` | AWS 비밀 액세스 키 |
| `--aws-region REGION` | AWS 리전 (기본값: `us-east-1`) |
| `--aws-profile PROFILE` | AWS CLI 프로필 이름 |

#### 사용 가능한 수집기

| 수집기 이름 | 플랫폼 | 필요 자격 증명 |
|----------------|----------|---------------------|
| `GitHubCollector` | GitHub | `--github-token`, `--github-org` |
| `AzureDevOpsCollector` | Azure DevOps | `--azure-devops-token` 또는 `--azure-devops-access-token`, `--azure-devops-org` |
| `AzureMLCollector` | Azure ML | `--azure-subscription-id`, `--azure-tenant-id` |
| `SageMakerCollector` | AWS SageMaker | `--aws-profile` 또는 `--aws-access-key-id` |

---

### `dop2mop demo`

연구에서 제시된 네 가지 공격 시나리오를 보여주는 데모 데이터를 생성합니다.```bash
dop2mop demo [OPTIONS]
옵션설명
-o, --output FILE출력 파일 경로 (기본값: dop2mop_demo.json)

dop2mop icons

BloodHound 노드 유형에 대한 사용자 지정 아이콘 구성을 생성합니다.```bash dop2mop icons [OPTIONS]

root@kitploit:~
| 옵션 | 설명 |
|--------|-------------|
| `-o, --output FILE` | 출력 파일 경로 (기본값: `dop2mop_icons.json`) |

---

## CLI 사용 예제

### 기본 수집```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

단일 플랫폼 컬렉션```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:~
### 다중 플랫폼 컬렉션```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

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:~
### 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

참고: Azure DevOps 인증 우선순위: 액세스 토큰(Bearer) > PAT(Basic). 액세스 토큰은 az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 명령어로 얻을 수 있습니다.

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:~
> **참고:** Azure ML 인증 우선순위: 액세스 토큰 > 서비스 주체 > DefaultAzureCredential (az login).
> 액세스 토큰은 `az account get-access-token --resource https://management.azure.com/`을 통해 얻을 수 있습니다.

### 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

전체 환경 수집```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:~
---

## 환경 변수

모든 명령줄 옵션은 환경 변수로 설정할 수 있습니다:

| 환경 변수 | CLI 해당 옵션 | 설명 |
|---------------------|----------------|-------------|
| `GITHUB_TOKEN` | `--github-token` | GitHub 개인 액세스 토큰 |
| `GITHUB_ORG` | `--github-org` | GitHub 조직 이름 |
| `GITHUB_ENTERPRISE_URL` | `--github-enterprise-url` | GitHub Enterprise Server URL |
| `AZURE_DEVOPS_TOKEN` | `--azure-devops-token` | Azure DevOps PAT |
| `AZURE_DEVOPS_ACCESS_TOKEN` | `--azure-devops-access-token` | Azure DevOps 액세스 토큰 (Bearer) |
| `AZURE_DEVOPS_ORG` | `--azure-devops-org` | Azure DevOps 조직 |
| `AZURE_SUBSCRIPTION_ID` | `--azure-subscription-id` | Azure 구독 ID |
| `AZURE_TENANT_ID` | `--azure-tenant-id` | Azure AD 테넌트 ID |
| `AZURE_CLIENT_ID` | `--azure-client-id` | Azure 서비스 주체 클라이언트 ID |
| `AZURE_CLIENT_SECRET` | `--azure-client-secret` | Azure 서비스 주체 비밀 |
| `AZURE_ACCESS_TOKEN` | `--azure-access-token` | Azure ML용 Azure 액세스 토큰 |
| `AWS_ACCESS_KEY_ID` | `--aws-access-key-id` | AWS 액세스 키 ID |
| `AWS_SECRET_ACCESS_KEY` | `--aws-secret-access-key` | AWS 비밀 액세스 키 |
| `AWS_REGION` | `--aws-region` | AWS 리전 (기본값: us-east-1) |
| `AWS_PROFILE` | `--aws-profile` | AWS CLI 프로필 이름 |

**우선순위:** CLI 인수 > 설정 파일 > 환경 변수.

---

## 노드 유형

### DevOps 노드

| 종류 | 설명 |
|------|-------------|
| `GHOrganization` | GitHub 조직 |
| `GHRepository` | GitHub 저장소 |
| `GHWorkflow` | GitHub Actions 워크플로 |
| `GHSecret` | GitHub Actions 비밀 |
| `ADOOrganization` | Azure DevOps 조직 |
| `ADOProject` | Azure DevOps 프로젝트 |
| `ADOPipeline` | Azure DevOps 파이프라인 |
| `ADOServiceConnection` | Azure DevOps 서비스 연결(NHI) 및 범위 세부 정보 |
| `ADOAgent` | Azure DevOps 에이전트 풀(호스트형 또는 자체 호스트형) |
| `ADOVariableGroup` | Azure DevOps 변수 그룹 |

### MLOps 노드

| 종류 | 설명 |
|------|-------------|
| `AzMLWorkspace` | Azure ML 작업 영역 |
| `AzMLCompute` | Azure ML 컴퓨트 클러스터/인스턴스 |
| `AzMLExperiment` | Azure ML 작업/실험 |
| `AzMLDatastore` | Azure ML 데이터 저장소 |
| `AzMLEnvironment` | Azure ML 환경(컨테이너 정의) |
| `AzMLModel` | Azure ML 등록 모델 |
| `SMDomain` | SageMaker Studio 도메인 |
| `SMTrainingJob` | SageMaker 학습 작업 |
| `SMModel` | SageMaker 모델 |
| `SMEndpoint` | SageMaker 엔드포인트(Azure ML 엔드포인트에도 사용됨) |
| `SMNotebook` | SageMaker 노트북 인스턴스 |

### ID 노드

| 종류 | 설명 |
|------|-------------|
| `ServicePrincipal` | Azure AD 서비스 주체 |
| `IAMRole` | AWS IAM 역할 |
| `OIDCIdentity` | OIDC 페더레이션 ID |
| `ManagedIdentity` | Azure 관리 ID |

### 아티팩트 노드

| 종류 | 설명 |
|------|-------------|
| `ContainerRegistry` | 컨테이너 레지스트리(ECR, ACR) |
| `ContainerImage` | 컨테이너 이미지 |
| `S3Bucket` | AWS S3 버킷 |
| `Dataset` | ML 데이터셋 |

## 엣지 유형

### 공격 경로 엣지

| 종류 | 신뢰 경계 | 설명 |
|------|----------------|-------------|
| `TriggersPipeline` | TB1 | 코드 커밋이 CI/CD를 트리거함 |
| `HasBranchProtection` | TB1 | 저장소에 브랜치 보호 규칙이 있음 |
| `BypassesProtection` | TB1 | 약함/없는 브랜치 보호(악용 가능) |
| `AuthenticatesAs` | TB2 | 파이프라인이 서비스 주체를 사용함 |
| `CanAssumeRole` | TB2 | OIDC ID가 IAM 역할을 수임할 수 있음 |
| `OIDCTrust` | TB2 | 워크플로가 OIDC 페더레이션을 사용함 |
| `UsesServiceConnection` | TB2 | 파이프라인이 ADO 서비스 연결을 사용함 |
| `PullsImage` | TB3 | 학습 작업이 컨테이너 이미지를 가져옴 |
| `CanPoisonImage` | TB3 | 파이프라인이 컨테이너 이미지를 수정할 수 있음 |
| `SubmitsJob` | TB4 | 서비스 주체가 ML 작업을 제출함 |
| `CodeExecution` | TB4 | 작업이 컴퓨트에서 코드를 실행함 |
| `LoadsDataset` | TB5 | 학습 작업이 데이터셋을 로드함 |
| `CanPoisonDataset` | TB5 | 파이프라인이 데이터셋을 수정할 수 있음 |
| `Deserializes` | TB5 | 안전하지 않은 역직렬화 |

### 추론된 엣지

이 엣지는 명시적 API 데이터가 없을 때(예: 비밀에 저장된 역할 ARN) 휴리스틱 분석을 통해 생성됩니다. BloodHound 쿼리에서 필터링할 수 있도록 고유한 엣지 유형을 사용합니다.

| 종류 | 설명 |
|------|-------------|
| `InferredCanAssumeRole` | OIDC ID가 역할을 수임할 수 있을 수 있음(추론) |
| `InferredSubmitsJob` | 워크플로가 OIDC를 통해 학습 작업을 제출할 수 있음(추론) |
| `InferredPullsImage` | 학습 작업이 감염된 컨테이너 이미지를 가져올 수 있음(추론) |
| `InferredLoadsDataset` | 학습 작업이 감염된 데이터셋을 로드할 수 있음(추론) |

### 구조적 엣지

| 종류 | 설명 |
|------|-------------|
| `Contains` | 부모-자식 관계 |
| `MemberOf` | 그룹 멤버십 |
| `HasAccessTo` | 리소스에 액세스할 권한 |
| `HasExecutionRole` | 리소스가 IAM/실행 역할을 사용함 |
| `Owns` | 소유권 관계 |

## 예제 쿼리

포괄적인 쿼리 예제는 [queries/dop2mop_queries.cypher](https://github.com/h4wkst3r/dop2mop/blob/HEAD/queries/dop2mop_queries.cypher)를 참조하세요.

---

## 사용자 정의 아이콘

Dop2Mop에는 [data/custom_icons.json](https://github.com/h4wkst3r/dop2mop/blob/HEAD/data/custom_icons.json)에 BloodHound 사용자 정의 노드 유형을 위한 사전 구성된 아이콘 파일이 포함되어 있습니다.

### BloodHound에 아이콘 업로드하기

#### 옵션 1: API 탐색기 (가장 쉬움)

1. BloodHound CE를 열고 **설정** → **API 탐색기**로 이동합니다.
2. **POST /api/v2/custom-nodes**를 찾습니다.
3. "시도하기"를 클릭합니다.
4. `custom_icons.json`의 내용을 붙여넣습니다.
5. "실행"을 클릭합니다.

#### 옵션 2: HMAC 인증 (자동화에 권장)

먼저 BloodHound에서 API 토큰을 생성합니다:
1. **설정** → **관리** → **사용자 관리**로 이동합니다.
2. 사용자를 클릭 → **토큰 생성**을 클릭합니다.
3. **토큰 ID**와 **토큰 키**를 저장합니다.

그런 다음 이 Python 스크립트를 사용하여 업로드합니다:```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()

Option 3: Bearer Token (빠른 테스트)

BloodHound에 로그인한 상태에서 브라우저의 DevTools Network 탭에서 JWT를 가져오세요:```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())

개별 수집기 사용하기```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:~
### 커스텀 그래프 구축```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")

문제 해결

먼저 검증하기

항상 자격 증명 검증부터 시작하여 인증 문제를 조기에 발견하십시오:```bash dop2mop collect --validate --collectors github,sm -v

root@kitploit:~
출력은 수집이 시작되기 전에 각 수집기별로 OK/FAILED를 표시합니다.

### 수집 요약

매 실행 후, Dop2Mop은 수집된 항목과 실패한 항목을 보여주는 요약을 출력합니다:```
============================================================
  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
============================================================

일반적인 문제

"GitHub collector not configured, skipping"

  • GITHUB_TOKEN 및 GITHUB_ORG 환경 변수가 설정되었는지 확인하거나, --github-token 및 --github-org를 전달하세요.

"Azure ML collector not configured, skipping"

  • AZURE_SUBSCRIPTION_ID와 AZURE_TENANT_ID가 설정되었는지 확인하세요.
  • DefaultAzureCredential을 사용하는 경우 az login을 실행하세요.
  • 또는 az account get-access-token에서 얻은 유효한 토큰을 --azure-access-token으로 전달하세요.

"SageMaker collector not configured, skipping"

  • AWS_PROFILE 또는 AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY를 모두 설정하세요.
  • 자격 증명에 SageMaker 읽기 권한이 있는지 확인하세요.

Branch protection returns 403

  • GitHub API는 브랜치 보호 규칙을 읽기 위해 관리자 액세스가 필요합니다.
  • 관리자가 아닌 토큰은 브랜치 보호 수집을 건너뜁니다(요약에 보고됨).

Rate limiting (429 errors)

  • Dop2Mop은 속도 제한 응답에 대해 지수 백오프 방식으로 자동 재시도합니다.
  • 대규모 조직의 경우 --max-items를 사용하여 API 호출을 줄이세요.
  • GitHub 속도 제한: 인증된 사용자의 경우 시간당 5,000회 요청.

No results in BloodHound Cypher console

  • 쿼리가 속성이 아닌 전체 노드(RETURN a, b)를 반환하는지 확인하세요(RETURN a.name, b.name 아님).
  • BloodHound의 Cypher 콘솔은 그래프 시각화용이며 표 형식 데이터용이 아닙니다.
  • 속성 기반 쿼리는 Neo4j 브라우저(localhost:7474)를 사용하세요.

Filtering inferred vs. collected edges

  • 추론된 에지는 고유한 유형을 사용합니다(예: CanAssumeRole 대신 InferredCanAssumeRole).
  • 확인된 에지만 쿼리: MATCH p=()-[:CanAssumeRole]->() RETURN p
  • 추론된 에지 쿼리: MATCH p=()-[:InferredCanAssumeRole]->() RETURN p

라이선스

MIT License - 자세한 내용은 LICENSE를 참조하세요.

도구 다운로드
별칭수집기
github, ghGitHubCollector
ado, azuredevops, azure-devopsAzureDevOpsCollector
azureml, azure-mlAzureMLCollector
sagemaker, smSageMakerCollector