Files
hacktricks-cloud/src/pentesting-cloud/azure-security/az-services/az-app-services.md

18 KiB

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

Azure App Service Slots vengono utilizzati per distribuire diverse versioni dell'applicazione allo 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 di appsettings o l'uso di un Account di Archiviazione nelle Function apps).

Enumeration

{{#tabs }} {{#tab name="az" }}

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

{{#endtab }}

{{#tab name="Az Powershell" }}

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" }}

#!/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.

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

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