mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-31 07:00:38 -08:00
Translated ['src/pentesting-cloud/azure-security/az-services/az-app-serv
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
# Az - App Services
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## App Service Basic Information
|
||||
|
||||
Azure App Services consente agli sviluppatori di **creare, distribuire e scalare applicazioni web, backend di app mobili e API senza soluzione di continuità**. Supporta più linguaggi di programmazione e si integra con vari strumenti e servizi Azure per funzionalità e gestione migliorate.
|
||||
|
||||
Ogni app viene eseguita all'interno di un sandbox, ma l'isolamento dipende dai piani App Service:
|
||||
|
||||
- Le app nei livelli Free e Shared vengono eseguite su **VM condivisi**
|
||||
- Le app nei livelli Standard e Premium vengono eseguite su **VM dedicate condivise solo da app** nello stesso piano App Service.
|
||||
- I livelli Isolated vengono eseguiti su **VM dedicate su reti virtuali dedicate**, migliorando l'isolamento delle app.
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che **nessuno** di questi isolamenti **previene** altre comuni **vulnerabilità web** (come il caricamento di file o le iniezioni). E se viene utilizzata un'**identità di gestione**, potrebbe essere in grado di **escalare i privilegi su di esse**.
|
||||
|
||||
Le app hanno alcune configurazioni interessanti:
|
||||
|
||||
- **Always On**: Garantisce che l'app sia sempre in esecuzione. Se non abilitato, l'app smetterà di funzionare dopo 20 minuti di inattività e riprenderà quando viene ricevuta una richiesta.
|
||||
- Questo è essenziale se hai un webjob che deve funzionare continuamente, poiché il webjob si fermerà se l'app si ferma.
|
||||
- **SSH**: Se abilitato, un utente con permessi sufficienti può connettersi all'app utilizzando SSH.
|
||||
- **Debugging**: Se abilitato, un utente con permessi sufficienti può eseguire il debug dell'app. Tuttavia, questo viene disabilitato automaticamente ogni 48 ore.
|
||||
- **Web App + Database**: La console web consente di creare un'app con un database. In questo caso è possibile selezionare il database da utilizzare (SQLAzure, PostgreSQL, MySQL, MongoDB) e consente anche di creare una Cache Azure per Redis.
|
||||
- L'URL contenente le credenziali per il database e Redis sarà memorizzato nelle **appsettings**.
|
||||
- **Container**: È possibile distribuire un container nel App Service indicando l'URL del container e le credenziali per accedervi.
|
||||
- **Mounts**: È possibile creare 5 mount da account di archiviazione, essendo questi Azure Blob (Sola lettura) o Azure Files. La configurazione memorizzerà la chiave di accesso sull'Account di Archiviazione.
|
||||
|
||||
## Basic Authentication
|
||||
|
||||
Quando si crea un'app web (e una funzione Azure di solito) è possibile indicare se si desidera **abilitare l'autenticazione di base** (disabilitata per impostazione predefinita). Questo abilita fondamentalmente **SCM (Source Control Manager) e FTP (File Transfer Protocol)** per l'applicazione, quindi sarà possibile distribuire l'applicazione utilizzando queste tecnologie.
|
||||
|
||||
Per accedere ai server SCM e FTP, è richiesta una **username e password**. Pertanto, Azure fornisce alcune **API per ottenere gli URL** per queste piattaforme e le credenziali.
|
||||
|
||||
Il **server FTP non ha alcuna magia speciale**, basta avere l'URL valido, username e password per connettersi e ottenere permessi di lettura e scrittura sull'ambiente dell'app.
|
||||
|
||||
Lo SCM
|
||||
È possibile connettersi allo SCM utilizzando un browser web in `https://<SMC-URL>/BasicAuth` e controllare tutti i file e le distribuzioni lì.
|
||||
|
||||
### Kudu
|
||||
|
||||
Kudu è la piattaforma che **gestisce sia lo SCM che un'interfaccia web e API** per gestire un App Service, e fornisce distribuzioni basate su Git, debug remoto e capacità di gestione dei file. È accessibile tramite l'URL SCM definito nell'app web.
|
||||
|
||||
Nota che le versioni di Kudu utilizzate da App Services e da Function Apps sono diverse, con la versione delle Function apps molto più limitata.
|
||||
|
||||
Alcuni endpoint interessanti che puoi trovare in Kudu sono:
|
||||
- `/BasicAuth`: Devi accedere a questo percorso per **accedere a Kudu**.
|
||||
- `/DebugConsole`: Una console che consente di eseguire comandi nell'ambiente in cui Kudu è in esecuzione.
|
||||
- Nota che questo ambiente **non ha accesso** al servizio di metadata per ottenere token.
|
||||
- `/webssh/host`: Un client SSH basato su web che consente di connettersi all'interno del container in cui l'app è in esecuzione.
|
||||
- Questo ambiente **ha accesso al servizio di metadata** per ottenere token dalle identità gestite assegnate.
|
||||
- `/Env`: Ottieni informazioni sul sistema, impostazioni dell'app, variabili d'ambiente, stringhe di connessione e intestazioni HTTP.
|
||||
- `/wwwroot/`: La directory radice dell'app web. Puoi scaricare tutti i file da qui.
|
||||
|
||||
Inoltre, Kudu era open source in [https://github.com/projectkudu/kudu](https://github.com/projectkudu/kudu) ma il progetto è stato deprecato e confrontando il comportamento dell'attuale Kudu in Azure con quello precedente è possibile vedere che **diverse cose sono già cambiate**.
|
||||
|
||||
## Sources
|
||||
|
||||
App Services consentono di caricare il codice come file zip per impostazione predefinita, ma consentono anche di connettersi a un servizio di terze parti e ottenere il codice da lì.
|
||||
|
||||
- Le fonti di terze parti attualmente supportate sono **Github** e **Bitbucket**.
|
||||
- Puoi ottenere i token di autenticazione eseguendo `az rest --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01"`
|
||||
- Azure per impostazione predefinita configurerà un **Github Action** per distribuire il codice all'App Service ogni volta che il codice viene aggiornato.
|
||||
- È anche possibile indicare un **repository git remoto** (con username e password) per ottenere il codice da lì.
|
||||
- Puoi ottenere le credenziali per il repository remoto eseguendo `az webapp deployment source show --name <app-name> --resource-group <res-group>` o `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"`
|
||||
- È anche possibile utilizzare un **Azure Repository**.
|
||||
- È anche possibile configurare un **repository git locale**.
|
||||
- Puoi ottenere l'URL del repository git con `az webapp deployment source show --name <app-name> --resource-group <res-group>` e sarà l'URL SCM dell'app.
|
||||
- Per clonarlo avrai bisogno delle credenziali SCM che puoi ottenere con `az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>`
|
||||
|
||||
## Webjobs
|
||||
|
||||
Azure WebJobs sono **compiti in background che vengono eseguiti nell'ambiente Azure App Service**. Consentono agli sviluppatori di eseguire script o programmi insieme alle loro applicazioni web, facilitando la gestione di operazioni asincrone o intensive nel tempo come l'elaborazione di file, la gestione dei dati o compiti programmati.
|
||||
Ci sono 2 tipi di web jobs:
|
||||
- **Continuous**: Esegue indefinitamente in un ciclo ed è attivato non appena viene creato. È ideale per compiti che richiedono un'elaborazione costante. Tuttavia, se l'app smette di funzionare perché Always On è disabilitato e non ha ricevuto una richiesta negli ultimi 20 minuti, il web job si fermerà anche.
|
||||
- **Triggered**: Esegue su richiesta o in base a un programma. È più adatto per compiti periodici, come aggiornamenti batch dei dati o routine di manutenzione.
|
||||
|
||||
I webjobs sono molto interessanti da una prospettiva di attacco poiché potrebbero essere utilizzati per **eseguire codice** nell'ambiente e **escalare privilegi** alle identità gestite collegate.
|
||||
|
||||
Inoltre, è sempre interessante controllare i **log** generati dai Webjobs poiché potrebbero contenere **informazioni sensibili**.
|
||||
|
||||
## Slots
|
||||
|
||||
Gli Azure App Service Slots vengono utilizzati per **distribuire diverse versioni dell'applicazione** nello stesso App Service. Questo consente agli sviluppatori di testare nuove funzionalità o modifiche in un ambiente separato prima di distribuirle nell'ambiente di produzione.
|
||||
|
||||
Inoltre, è possibile instradare una **percentuale del traffico** a uno slot specifico, utile per test A/B e per **scopi di backdoor**.
|
||||
|
||||
## Azure Function Apps
|
||||
|
||||
Fondamentalmente **le Azure Function apps sono un sottoinsieme di Azure App Service** nella console web e se vai alla console web e elenchi tutti i servizi app o esegui `az webapp list` in az cli sarai in grado di **vedere anche le Function apps elencate lì**.
|
||||
|
||||
Pertanto, entrambi i servizi hanno in realtà per lo più le **stesse configurazioni, funzionalità e opzioni nell'az cli**, anche se potrebbero configurarle in modo leggermente diverso (come i valori predefiniti delle appsettings o l'uso di un Account di Archiviazione nelle Function apps).
|
||||
|
||||
## Enumeration
|
||||
|
||||
{{#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 (contains access key)
|
||||
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 }}
|
||||
|
||||
#### Ottenere credenziali e accedere al codice dell'app web
|
||||
```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}}
|
||||
|
||||
## Esempi per generare Web Apps
|
||||
|
||||
### Python da locale
|
||||
|
||||
Questo tutorial si basa su quello di [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
|
||||
```
|
||||
Accedendo al portale SCM o accedendo tramite FTP è possibile vedere in `/wwwroot` il file compresso `output.tar.gz` che contiene il codice dell'app web.
|
||||
|
||||
> [!TIP]
|
||||
> Basta connettersi tramite FTP e modificare il file `output.tar.gz` non è sufficiente per cambiare il codice eseguito dall'app web.
|
||||
|
||||
**Un attaccante potrebbe scaricare questo file, modificarlo e caricarlo di nuovo per eseguire codice arbitrario nell'app web.**
|
||||
|
||||
### Python da Github
|
||||
|
||||
Questo tutorial si basa sul precedente ma utilizza un repository Github.
|
||||
|
||||
1. Forka il repo msdocs-python-flask-webapp-quickstart nel tuo account Github.
|
||||
2. Crea una nuova Web App Python in Azure.
|
||||
3. Nel `Deployment Center` cambia la sorgente, accedi con Github, seleziona il repo forkato e clicca su `Salva`.
|
||||
|
||||
Come nel caso precedente, accedendo al portale SCM o accedendo tramite FTP è possibile vedere in `/wwwroot` il file compresso `output.tar.gz` che contiene il codice dell'app web.
|
||||
|
||||
> [!TIP]
|
||||
> Basta connettersi tramite FTP e modificare il file `output.tar.gz` e riattivare un deployment non è sufficiente per cambiare il codice eseguito dall'app web.
|
||||
|
||||
## Privilege Escalation
|
||||
|
||||
{{#ref}}
|
||||
../az-privilege-escalation/az-app-services-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
|
||||
- [https://learn.microsoft.com/en-in/azure/app-service/overview](https://learn.microsoft.com/en-in/azure/app-service/overview)
|
||||
- [https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans](https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user