# CVE-2026-42826 — Structure Diagrams ## Attack Flow Overview ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ CVE-2026-42826 Attack Flow │ │ │ │ Attacker Azure DevOps API Target Organization │ │ ──────── ────────────────── ────────────────── │ │ │ │ 1. GET /_apis/projects ──────────────► │ │ (no authentication) │ │ 2. API checks project visibility │ │ → public? return data │ │ → private? return 401 │ │ │ │ 3. 200 OK ◄──────────────────────── │ │ { projects: [...] } │ │ → identifies public projects │ │ │ │ 4. GET /{project}/_apis/pipelines ──► │ │ 5. Returns pipeline metadata │ │ + YAML configs │ │ │ │ 6. 200 OK ◄──────────────────────── │ │ { pipelines: [...], yaml: "..." } │ │ → extracts service connection names │ │ → extracts subscription references │ │ │ │ 7. GET /{project}/_apis/ ──► │ │ distributedtask/variablegroups │ │ 8. Returns variable groups │ │ + non-secret values │ │ │ │ 9. 200 OK ◄──────────────────────── │ │ { variables: { API_KEY: "sk-..." } } │ │ → harvests plaintext values │ │ │ │ 10. GET /{project}/_apis/ ──► │ │ serviceendpoint/endpoints │ │ 11. Returns service connections │ │ + Azure subscription IDs │ │ + tenant IDs │ │ │ │ 12. 200 OK ◄─────────────────────── │ │ { endpoints: [...], subscriptionId: "..." } │ │ → maps internal infrastructure │ │ │ │ 13. GET /{project}/_apis/git/ ──► │ │ repositories/{repo}/items │ │ 14. Returns file contents │ │ (azure-pipelines.yml) │ │ │ │ 15. 200 OK ◄─────────────────────── │ │ → scans YAML for secrets │ │ → extracts infrastructure refs │ │ │ │ RESULT: Complete infrastructure map + sensitive data │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## Exploit Component Architecture ``` ┌─────────────────────────────────────────────────────────────────────┐ │ PoC Exploit Architecture │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │ │ exploit.py │ │ detect.py │ │ test_exploit.py │ │ │ │ │ │ │ │ │ │ │ │ • 6 attack │ │ • 5 checks │ │ • 30+ unit tests │ │ │ │ vectors │ │ • Hardening │ │ • Mocked API tests │ │ │ │ • Secret │ │ recommend. │ │ • Secret scanner │ │ │ │ scanner │ │ • Org policy │ │ validation │ │ │ │ • Report gen │ │ check │ │ • Report generation │ │ │ │ • JSON output │ │ • VG audit │ │ • 401 handling │ │ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Azure DevOps REST API │ │ │ │ │ │ │ │ /_apis/projects → Project enumeration │ │ │ │ /{proj}/_apis/pipelines → Pipeline configs │ │ │ │ /{proj}/_apis/distributedtask/variablegroups → VG harvest │ │ │ │ /{proj}/_apis/serviceendpoint/endpoints → SC extract │ │ │ │ /{proj}/_apis/git/repositories → Repo enum │ │ │ │ /{proj}/_apis/build/builds/{id}/logs → Log extract │ │ │ │ /{proj}/_apis/git/repositories/{repo}/items → File fetch │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ ``` --- ## Data Extraction Pipeline ``` Exploit Execution Flow ───────────────────── Phase 0: Public Exposure Check ┌─────────────────────────────────────────────┐ │ GET /_apis/projects (no auth) │ │ ├── 200 → Public projects exist! │ │ │ → Record CRITICAL finding │ │ │ → List public project names │ │ └── 401 → No public access │ │ → Need PAT for further enum │ └─────────────────────────────────────────────┘ │ ▼ Phase 1: Project Enumeration ┌─────────────────────────────────────────────┐ │ GET /_apis/projects (with PAT if needed) │ │ → Extract: id, name, description, │ │ visibility, state, revision │ │ → Filter: public vs private │ └─────────────────────────────────────────────┘ │ ▼ Phase 2: Pipeline Config Extraction ┌─────────────────────────────────────────────┐ │ For each project: │ │ GET /{proj}/_apis/pipelines │ │ → Extract: pipeline names, IDs, folders │ │ → Query pipeline configuration endpoint │ │ → Search repos for azure-pipelines.yml │ │ → Scan YAML for sensitive patterns │ └─────────────────────────────────────────────┘ │ ▼ Phase 3: Variable Group Harvesting ┌─────────────────────────────────────────────┐ │ For each project: │ │ GET /{proj}/_apis/distributedtask/ │ │ variablegroups │ │ → Extract: VG names, descriptions │ │ → For each variable: │ │ ├── isSecret=true → mask value │ │ └── isSecret=false → capture plaintext │ └─────────────────────────────────────────────┘ │ ▼ Phase 4: Service Connection Extraction ┌─────────────────────────────────────────────┐ │ For each project: │ │ GET /{proj}/_apis/serviceendpoint/ │ │ endpoints │ │ → Extract: connection names, types │ │ → Extract from data object: │ │ ├── subscriptionId │ │ ├── subscriptionName │ │ ├── tenantId │ │ ├── resourceGroup │ │ ├── scope │ │ ├── environment │ │ └── registryUrl │ └─────────────────────────────────────────────┘ │ ▼ Phase 5: Repository Enumeration ┌─────────────────────────────────────────────┐ │ For each project: │ │ GET /{proj}/_apis/git/repositories │ │ → Extract: repo names, branches, sizes │ │ → For each repo: │ │ GET /{proj}/_apis/git/repositories/ │ │ {repo}/items?path=azure-pipelines.yml│ │ → Extract YAML content │ │ → Scan for secrets and infra refs │ └─────────────────────────────────────────────┘ │ ▼ Phase 6: Build Log Extraction ┌─────────────────────────────────────────────┐ │ For each project: │ │ GET /{proj}/_apis/build/builds │ │ → For each build (top 10): │ │ GET /{proj}/_apis/build/builds/{id}/ │ │ logs │ │ → Extract log entries (first 5) │ │ → Scan for secrets in log text │ └─────────────────────────────────────────────┘ │ ▼ Report Generation ┌─────────────────────────────────────────────┐ │ Aggregate all extracted data │ │ Count findings by severity │ │ Generate JSON report │ │ Print summary to console │ │ Optionally save to file │ └─────────────────────────────────────────────┘ ``` --- ## Attack Vector Comparison ``` ┌────────────────────┬──────────────┬──────────────┬──────────────────────┐ │ Vector │ Auth Req │ Conditions │ Data Exposed │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Public Project │ None │ Project set │ Repos, pipelines, │ │ Access │ │ to public │ logs, work items │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Auth Bypass │ None │ Internal API │ Project data from │ │ (CVE specific) │ │ endpoint bug │ private projects │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Pipeline YAML │ None (public)│ Public repo │ Service connection │ │ Reconnaissance │ or PAT │ with YAML │ names, infra refs │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Variable Group │ PAT │ VG with non- │ Plaintext variable │ │ Harvesting │ │ secret vars │ values │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Service Connection │ PAT │ SC with │ Subscription IDs, │ │ Extraction │ │ metadata │ tenant IDs, URLs │ ├────────────────────┼──────────────┼──────────────┼──────────────────────┤ │ Build Log │ PAT │ Build logs │ Env vars, tokens, │ │ Extraction │ │ with secrets │ connection strings │ └────────────────────┴──────────────┴──────────────┴──────────────────────┘ ``` --- ## Mermaid Diagram ```mermaid flowchart TD A[Attacker] -->|GET /_apis/projects no auth| B{API Response} B -->|200 OK| C[Public projects found] B -->|401 Unauthorized| D[Need PAT] D -->|Provide PAT| E[Authenticated API Access] C --> F[Enumerate Projects] E --> F F --> G[For each project] G --> H[Extract Pipeline YAML] G --> I[Harvest Variable Groups] G --> J[Extract Service Connections] G --> K[Enumerate Repositories] G --> L[Extract Build Logs] H --> M[Scan for secrets & infra refs] I --> N[Capture non-secret variable values] J --> O[Extract subscription/tenant IDs] K --> P[Fetch azure-pipelines.yml files] L --> Q[Scan log fragments for secrets] M --> R[Generate Report] N --> R O --> R P --> R Q --> R R --> S[JSON Report with all findings] S --> T[Infrastructure Map] S --> U[Sensitive Data Points] S --> V[Vulnerability Findings] style C fill:#ff4444,color:#fff style N fill:#ff4444,color:#fff style O fill:#ff4444,color:#fff style Q fill:#ff4444,color:#fff ``` --- ## Network Traffic Flow ``` Attacker Azure DevOps API │ │ │ GET /_apis/projects │ │ Authorization: None │ │ ──────────────────────────► │ │ │ │ 200 OK │ │ { "value": [ │ │ { "name": "ProjA", │ │ "visibility": "public" │ │ } │ │ ] } │ │ ◄────────────────────────── │ │ │ │ GET /ProjA/_apis/pipelines │ │ ──────────────────────────► │ │ │ │ 200 OK │ │ { "value": [ │ │ { "name": "ci-build", │ │ "configuration": { │ │ "yaml": "..." │ │ } │ │ } │ │ ] } │ │ ◄────────────────────────── │ │ │ │ GET /ProjA/_apis/ │ │ distributedtask/ │ │ variablegroups │ │ ──────────────────────────► │ │ │ │ 200 OK │ │ { "value": [ │ │ { "name": "prod-vars", │ │ "variables": { │ │ "API_KEY": { │ │ "value": "sk-123", │ │ "isSecret": false │ │ } │ │ } │ │ } │ │ ] } │ │ ◄────────────────────────── │ │ │ │ GET /ProjA/_apis/ │ │ serviceendpoint/endpoints │ │ ──────────────────────────► │ │ │ │ 200 OK │ │ { "value": [ │ │ { "name": "azure-prod", │ │ "type": "azurerm", │ │ "data": { │ │ "subscriptionId": │ │ "12345-67890", │ │ "tenantId": │ │ "tenant-123" │ │ } │ │ } │ │ ] } │ │ ◄────────────────────────── │ │ │ │ ⚠ SENSITIVE DATA EXFILTRATED │ │ • Pipeline YAML configs │ │ • Variable values (plain) │ │ • Azure subscription IDs │ │ • Tenant IDs │ │ • Service connection names │ │ │ ```