# Az - App Services

{{#include ../../../banners/hacktricks-training.md}}

## Informazioni di base sui servizi App

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 essere eseguito 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 di Azure per Redis.
- L'URL contenente le credenziali per il database e Redis sarà memorizzato in **appsettings**.
- **Container**: È possibile distribuire un container nel servizio App 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.
- **Networking**: Può essere pubblicamente disponibile o accessibile solo tramite endpoint privati da una VNet.

## Autenticazione di base

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 sostanzialmente **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 servizio App, 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 dai servizi App e dalle 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**.

## Fonti

I servizi App 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 nel servizio App 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 in termini di 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 servizio App. 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 nella 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 di appsettings o l'uso di un Account di Archiviazione nelle Function apps).

## Enumerazione

{{#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 git URL to access the code
az webapp deployment source config-local-git --resource-group <res-group> -n <name>

# 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>

# Get configured SMC users by your account
az webapp deployment user show
## If any user is created, the username should appear in the "publishingUserName" field
```
{{#endtab }}

{{#tab name="Az Powershell" }}
```bash
Get-Command -Module Az.Websites

# Get App Services and Function Apps
Get-AzWebApp
# Get only App Services
Get-AzWebApp | ?{$_.Kind -notmatch "functionapp"}

# Retrieves details of a specific App Service Environment in the specified resource group.
Get-AzAppServiceEnvironment -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the access restriction configuration for a specified Web App.
Get-AzWebAppAccessRestrictionConfig -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the SSL certificates for a specified resource group.
Get-AzWebAppCertificate -ResourceGroupName <ResourceGroupName>
# Retrieves the continuous deployment URL for a containerized Web App.
Get-AzWebAppContainerContinuousDeploymentUrl -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the list of continuous WebJobs for a specified Web App.
Get-AzWebAppWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName>
# Retrieves the list of triggered WebJobs for a specified Web App.
Get-AzWebAppTriggeredWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName>

# Retrieves details of a deleted Web App in the specified resource group.
Get-AzDeletedWebApp -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves a list of snapshots for a specified Web App.
Get-AzWebAppSnapshot -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the history of a specific triggered WebJob for a Web App.
Get-AzWebAppTriggeredWebJobHistory -ResourceGroupName <ResourceGroupName> -AppName <AppName> -Name <Name>

# Retrieves information about deployment slots for a specified Web App.
Get-AzWebAppSlot -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the continuous WebJobs for a specific deployment slot of a Web App.
Get-AzWebAppSlotWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName> -SlotName <SlotName>
# Retrieves the triggered WebJobs for a specific deployment slot of a Web App.
Get-AzWebAppSlotTriggeredWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName> -SlotName <SlotName>
# Retrieves the history of a specific triggered WebJob for a deployment slot of a Web App.
Get-AzWebAppSlotTriggeredWebJobHistory -ResourceGroupName <ResourceGroupName> -AppName <AppName> -SlotName <SlotName> -Name <Name>
# Retrieves the continuous WebJobs for a Web App.
Get-AzWebAppContinuousWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName>
# Retrieves the continuous WebJobs for a specific deployment slot of a Web App.
Get-AzWebAppSlotContinuousWebJob -ResourceGroupName <ResourceGroupName> -AppName <AppName> -SlotName <SlotName>

# Retrieves the traffic routing rules for a Web App.
Get-AzWebAppTrafficRouting -ResourceGroupName <ResourceGroupName> -WebAppName <WebAppName> -RuleName <RuleName>

# Retrieves details of a specific backup for a Web App.
Get-AzWebAppBackup -ResourceGroupName <ResourceGroupName> -Name <Name> -BackupId <BackupId>
# Retrieves the backup configuration for a Web App.
Get-AzWebAppBackupConfiguration -ResourceGroupName <ResourceGroupName> -Name <Name>
# Retrieves the list of all backups for a Web App.
Get-AzWebAppBackupList -ResourceGroupName <ResourceGroupName> -Name <Name>
```
{{#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 }}


{{#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]
> Collegarsi semplicemente 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]
> Collegarsi semplicemente 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}}
