19 KiB
Az - App Services
{{#include ../../../banners/hacktricks-training.md}}
Información Básica del Servicio de Aplicaciones
Azure App Services permite a los desarrolladores crear, implementar y escalar aplicaciones web, backends de aplicaciones móviles y APIs sin problemas. Soporta múltiples lenguajes de programación e integra diversas herramientas y servicios de Azure para mejorar la funcionalidad y gestión.
Cada aplicación se ejecuta dentro de un sandbox, pero la aislamiento depende de los planes de App Service:
- Las aplicaciones en los niveles Gratuito y Compartido se ejecutan en VMs compartidas
- Las aplicaciones en los niveles Estándar y Premium se ejecutan en VMs dedicadas compartidas solo por aplicaciones en el mismo plan de App Service.
- Los niveles Aislados se ejecutan en VMs dedicadas en redes virtuales dedicadas, mejorando el aislamiento de las aplicaciones.
Warning
Tenga en cuenta que ninguno de esos aislamientos previene otras vulnerabilidades web comunes (como la carga de archivos o inyecciones). Y si se utiliza una identidad de gestión, podría ser capaz de escalar privilegios a ellas.
Las aplicaciones tienen algunas configuraciones interesantes:
- Siempre Activo: Asegura que la aplicación esté siempre en ejecución. Si no está habilitado, la aplicación dejará de ejecutarse después de 20 minutos de inactividad y se reiniciará cuando se reciba una solicitud.
- Esto es esencial si tiene un webjob que necesita ejecutarse continuamente, ya que el webjob se detendrá si la aplicación se detiene.
- SSH: Si está habilitado, un usuario con suficientes permisos puede conectarse a la aplicación usando SSH.
- Depuración: Si está habilitado, un usuario con suficientes permisos puede depurar la aplicación. Sin embargo, esto se desactiva automáticamente cada 48 horas.
- Aplicación Web + Base de Datos: La consola web permite crear una aplicación con una base de datos. En este caso, es posible seleccionar la base de datos a utilizar (SQLAzure, PostgreSQL, MySQL, MongoDB) y también permite crear un Azure Cache para Redis.
- La URL que contiene las credenciales para la base de datos y Redis se almacenará en los appsettings.
- Contenedor: Es posible implementar un contenedor en el App Service indicando la URL del contenedor y las credenciales para acceder a él.
- Montajes: Es posible crear 5 montajes desde cuentas de almacenamiento, siendo estas Azure Blob (Solo Lectura) o Azure Files. La configuración almacenará la clave de acceso sobre la Cuenta de Almacenamiento.
Autenticación Básica
Al crear una aplicación web (y una función de Azure generalmente), es posible indicar si desea que la Autenticación Básica esté habilitada (deshabilitada por defecto). Esto básicamente habilita SCM (Source Control Manager) y FTP (File Transfer Protocol) para la aplicación, por lo que será posible implementar la aplicación utilizando esas tecnologías.
Para acceder a los servidores SCM y FTP, se requiere un nombre de usuario y contraseña. Por lo tanto, Azure proporciona algunas APIs para obtener las URLs a estas plataformas y las credenciales.
El servidor FTP no tiene ninguna magia especial, solo con la URL válida, nombre de usuario y contraseña es posible conectarse y obtener permisos de lectura y escritura sobre el entorno de la aplicación.
El SCM
Es posible conectarse al SCM usando un navegador web en https://<SMC-URL>/BasicAuth y verificar todos los archivos y despliegues allí.
Kudu
Kudu es la plataforma que gestiona tanto el SCM como una interfaz web y API para gestionar un App Service, y proporciona implementaciones basadas en Git, depuración remota y capacidades de gestión de archivos. Es accesible a través de la URL SCM definida en la aplicación web.
Tenga en cuenta que las versiones de Kudu utilizadas por App Services y por Function Apps son diferentes, siendo la versión de las Function Apps mucho más limitada.
Algunos puntos finales interesantes que puede encontrar en Kudu son:
/BasicAuth: Necesita acceder a esta ruta para iniciar sesión dentro de Kudu./DebugConsole: Una consola que permite ejecutar comandos en el entorno donde se está ejecutando Kudu.- Tenga en cuenta que este entorno no tiene acceso al servicio de metadatos para obtener tokens.
/webssh/host: Un cliente SSH basado en web que permite conectarse dentro del contenedor donde se está ejecutando la aplicación.- Este entorno tiene acceso al servicio de metadatos para obtener tokens de las identidades gestionadas asignadas.
/Env: Obtiene información sobre el sistema, configuraciones de la aplicación, variables de entorno, cadenas de conexión y encabezados HTTP./wwwroot/: El directorio raíz de la aplicación web. Puede descargar todos los archivos desde aquí.
Además, Kudu solía ser de código abierto en https://github.com/projectkudu/kudu pero el proyecto fue descontinuado y comparando el comportamiento del Kudu actual en Azure con el antiguo, es posible ver que varias cosas ya han cambiado.
Fuentes
App Services permite cargar el código como un archivo zip por defecto, pero también permite conectarse a un servicio de terceros y obtener el código desde allí.
- Las fuentes de terceros actualmente soportadas son Github y Bitbucket.
- Puede obtener los tokens de autenticación ejecutando
az rest --url "https://management.azure.com/providers/Microsoft.Web/sourcecontrols?api-version=2024-04-01" - Azure por defecto configurará una Acción de Github para implementar el código en el App Service cada vez que se actualice el código.
- También es posible indicar un repositorio git remoto (con nombre de usuario y contraseña) para obtener el código desde allí.
- Puede obtener las credenciales del repositorio remoto ejecutando
az webapp deployment source show --name <app-name> --resource-group <res-group>oaz 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" - También es posible usar un Repositorio de Azure.
- También es posible configurar un repositorio git local.
- Puede obtener la URL del repositorio git con
az webapp deployment source show --name <app-name> --resource-group <res-group>y será la URL SCM de la aplicación. - Para clonarlo necesitará las credenciales SCM que puede obtener con
az webapp deployment list-publishing-profiles --resource-group <res-group> -n <name>
Webjobs
Azure WebJobs son tareas en segundo plano que se ejecutan en el entorno de Azure App Service. Permiten a los desarrolladores ejecutar scripts o programas junto a sus aplicaciones web, facilitando el manejo de operaciones asíncronas o intensivas en tiempo, como el procesamiento de archivos, manejo de datos o tareas programadas. Hay 2 tipos de web jobs:
- Continuos: Se ejecutan indefinidamente en un bucle y se activan tan pronto como se crean. Son ideales para tareas que requieren procesamiento constante. Sin embargo, si la aplicación deja de ejecutarse porque Siempre Activo está deshabilitado y no ha recibido una solicitud en los últimos 20 minutos, el web job también se detendrá.
- Activados: Se ejecutan bajo demanda o según un horario. Son más adecuados para tareas periódicas, como actualizaciones de datos por lotes o rutinas de mantenimiento.
Los webjobs son muy interesantes desde la perspectiva de un atacante, ya que podrían usarse para ejecutar código en el entorno y escalar privilegios a las identidades gestionadas adjuntas.
Además, siempre es interesante revisar los registros generados por los Webjobs, ya que podrían contener información sensible.
Slots
Los Slots de Azure App Service se utilizan para implementar diferentes versiones de la aplicación en el mismo App Service. Esto permite a los desarrolladores probar nuevas características o cambios en un entorno separado antes de implementarlos en el entorno de producción.
Además, es posible dirigir un porcentaje del tráfico a un slot específico, lo cual es útil para pruebas A/B y para fines de puerta trasera.
Azure Function Apps
Básicamente, las aplicaciones de Azure Function son un subconjunto de Azure App Service en la consola web y si va a la consola web y lista todos los servicios de aplicaciones o ejecuta az webapp list en az cli, podrá ver las aplicaciones de Function también listadas allí.
Por lo tanto, ambos servicios en realidad tienen mayormente las mismas configuraciones, características y opciones en el az cli, aunque pueden configurarlas de manera un poco diferente (como los valores predeterminados de appsettings o el uso de una Cuenta de Almacenamiento en las aplicaciones de Function).
Enumeración
{{#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}}
Ejemplos para generar aplicaciones web
Python desde local
Este tutorial se basa en el de 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
Iniciar sesión en el portal SCM o iniciar sesión a través de FTP permite ver en /wwwroot el archivo comprimido output.tar.gz que contiene el código de la aplicación web.
Tip
Simplemente conectarse a través de FTP y modificar el archivo
output.tar.gzno es suficiente para cambiar el código ejecutado por la aplicación web.
Un atacante podría descargar este archivo, modificarlo y volver a subirlo para ejecutar código arbitrario en la aplicación web.
Python desde Github
Este tutorial se basa en el anterior pero utilizando un repositorio de Github.
- Haz un fork del repositorio msdocs-python-flask-webapp-quickstart en tu cuenta de Github.
- Crea una nueva aplicación web de Python en Azure.
- En
Deployment Center, cambia la fuente, inicia sesión con Github, selecciona el repositorio forkeado y haz clic enSave.
Al igual que en el caso anterior, iniciar sesión en el portal SCM o iniciar sesión a través de FTP permite ver en /wwwroot el archivo comprimido output.tar.gz que contiene el código de la aplicación web.
Tip
Simplemente conectarse a través de FTP y modificar el archivo
output.tar.gzy volver a activar un despliegue no es suficiente para cambiar el código ejecutado por la aplicación web.
Escalamiento de Privilegios
{{#ref}} ../az-privilege-escalation/az-app-services-privesc.md {{#endref}}
Referencias
- https://learn.microsoft.com/en-in/azure/app-service/overview
- https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans
{{#include ../../../banners/hacktricks-training.md}}