Az - Function Apps
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Informations de base
Azure Function Apps sont un service de calcul sans serveur qui vous permet dâexĂ©cuter de petits morceaux de code, appelĂ©s fonctions, sans gĂ©rer lâinfrastructure sous-jacente. Elles sont conçues pour exĂ©cuter du code en rĂ©ponse Ă divers dĂ©clencheurs, tels que des requĂȘtes HTTP, des minuteries ou des Ă©vĂ©nements dâautres services Azure comme Blob Storage ou Event Hubs. Les Function Apps prennent en charge plusieurs langages de programmation, y compris C#, Python, JavaScript et Java, ce qui les rend polyvalentes pour crĂ©er des applications basĂ©es sur des Ă©vĂ©nements, automatiser des flux de travail ou intĂ©grer des services. Elles sont rentables, car vous ne payez gĂ©nĂ©ralement que pour le temps de calcul utilisĂ© lorsque votre code sâexĂ©cute.
Note
Notez que les fonctions sont un sous-ensemble des App Services, par consĂ©quent, de nombreuses fonctionnalitĂ©s discutĂ©es ici seront Ă©galement utilisĂ©es par les applications créées en tant quâAzure Apps (
webappdans cli).
Différents Plans
- Flex Consumption Plan : Offre un scalabilitĂ© dynamique et basĂ©e sur les Ă©vĂ©nements avec un tarif Ă lâutilisation, ajoutant ou supprimant des instances de fonction en fonction de la demande. Il prend en charge le rĂ©seau virtuel et les instances prĂ©-provisionnĂ©es pour rĂ©duire les dĂ©marrages Ă froid, ce qui le rend adaptĂ© aux charges de travail variables qui ne nĂ©cessitent pas de support de conteneur.
- Traditional Consumption Plan : Lâoption sans serveur par dĂ©faut, oĂč vous ne payez que pour les ressources de calcul lorsque les fonctions sâexĂ©cutent. Il sâadapte automatiquement en fonction des Ă©vĂ©nements entrants et inclut des optimisations de dĂ©marrage Ă froid, mais ne prend pas en charge les dĂ©ploiements de conteneurs. IdĂ©al pour les charges de travail intermittentes nĂ©cessitant une mise Ă lâĂ©chelle automatique.
- Premium Plan : Conçu pour des performances constantes, avec des travailleurs prĂ©chauffĂ©s pour Ă©liminer les dĂ©marrages Ă froid. Il offre des temps dâexĂ©cution prolongĂ©s, un rĂ©seau virtuel, et prend en charge des images Linux personnalisĂ©es, ce qui le rend parfait pour des applications critiques nĂ©cessitant des performances Ă©levĂ©es et des fonctionnalitĂ©s avancĂ©es.
- Dedicated Plan : Fonctionne sur des machines virtuelles dĂ©diĂ©es avec une facturation prĂ©visible et prend en charge la mise Ă lâĂ©chelle manuelle ou automatique. Il permet dâexĂ©cuter plusieurs applications sur le mĂȘme plan, fournit une isolation de calcul, et garantit un accĂšs rĂ©seau sĂ©curisĂ© via des environnements de services dâapplication, ce qui le rend idĂ©al pour des applications de longue durĂ©e nĂ©cessitant une allocation de ressources constante.
- Container Apps : Permet de dĂ©ployer des applications de fonction conteneurisĂ©es dans un environnement gĂ©rĂ©, aux cĂŽtĂ©s de microservices et dâAPIs. Il prend en charge des bibliothĂšques personnalisĂ©es, la migration dâapplications hĂ©ritĂ©es, et le traitement GPU, Ă©liminant la gestion des clusters Kubernetes. IdĂ©al pour des applications conteneurisĂ©es Ă©volutives basĂ©es sur des Ă©vĂ©nements.
Buckets de stockage
Lors de la crĂ©ation dâune nouvelle Function App non conteneurisĂ©e (mais en fournissant le code Ă exĂ©cuter), le code et dâautres donnĂ©es liĂ©es Ă la fonction seront stockĂ©s dans un compte de stockage. Par dĂ©faut, la console web crĂ©era un nouveau compte par fonction pour stocker le code.
De plus, en modifiant le code Ă lâintĂ©rieur du bucket (dans les diffĂ©rents formats dans lesquels il pourrait ĂȘtre stockĂ©), le code de lâapplication sera modifiĂ© pour le nouveau et exĂ©cutĂ© la prochaine fois que la fonction est appelĂ©e.
Caution
Cela est trĂšs intĂ©ressant du point de vue des attaquants car lâaccĂšs en Ă©criture sur ce bucket permettra Ă un attaquant de compromettre le code et dâescalader les privilĂšges aux identitĂ©s gĂ©rĂ©es Ă lâintĂ©rieur de la Function App.
Plus dâinformations Ă ce sujet dans la section sur lâescalade de privilĂšges.
Il est Ă©galement possible de trouver les clĂ©s maĂźtre et fonctions stockĂ©es dans le compte de stockage dans le conteneur azure-webjobs-secrets Ă lâintĂ©rieur du dossier <app-name> dans les fichiers JSON que vous pouvez y trouver.
Notez que les fonctions permettent Ă©galement de stocker le code dans un emplacement distant en indiquant simplement lâURL.
Réseautique
En utilisant un déclencheur HTTP :
- Il est possible de donner accĂšs Ă une fonction depuis tout Internet sans nĂ©cessiter dâauthentification ou de donner un accĂšs basĂ© sur IAM. Bien quâil soit Ă©galement possible de restreindre cet accĂšs.
- Il est Ă©galement possible de donner ou restreindre lâaccĂšs Ă une Function App depuis un rĂ©seau interne (VPC).
Caution
Cela est trĂšs intĂ©ressant du point de vue des attaquants car il pourrait ĂȘtre possible de pivoter vers des rĂ©seaux internes depuis une fonction vulnĂ©rable exposĂ©e Ă Internet.
ParamĂštres de lâapplication de fonction et variables dâenvironnement
Il est possible de configurer des variables dâenvironnement Ă lâintĂ©rieur dâune application, qui pourraient contenir des informations sensibles. De plus, par dĂ©faut, les variables dâenvironnement AzureWebJobsStorage et WEBSITE_CONTENTAZUREFILECONNECTIONSTRING (entre autres) sont créées. Celles-ci sont particuliĂšrement intĂ©ressantes car elles contiennent la clĂ© de compte pour contrĂŽler avec des permissions COMPLETES le compte de stockage contenant les donnĂ©es de lâapplication. Ces paramĂštres sont Ă©galement nĂ©cessaires pour exĂ©cuter le code depuis le compte de stockage.
Ces variables dâenvironnement ou paramĂštres de configuration contrĂŽlent Ă©galement comment la fonction exĂ©cute le code, par exemple si WEBSITE_RUN_FROM_PACKAGE existe, cela indiquera lâURL oĂč le code de lâapplication est situĂ©.
Sandbox de fonction
Ă lâintĂ©rieur de la sandbox linux, le code source est situĂ© dans /home/site/wwwroot dans le fichier function_app.py (si Python est utilisĂ©) lâutilisateur exĂ©cutant le code est app (sans permissions sudo).
Dans une fonction Windows utilisant NodeJS, le code Ă©tait situĂ© dans C:\home\site\wwwroot\HttpTrigger1\index.js, le nom dâutilisateur Ă©tait mawsFnPlaceholder8_f_v4_node_20_x86 et faisait partie des groupes : Mandatory Label\High Mandatory Level Label, Everyone, BUILTIN\Users, NT AUTHORITY\INTERACTIVE, CONSOLE LOGON, NT AUTHORITY\Authenticated Users, NT AUTHORITY\This Organization, BUILTIN\IIS_IUSRS, LOCAL, 10-30-4-99\Dwas Site Users.
Identités gérées et métadonnées
Tout comme VMs, les fonctions peuvent avoir des IdentitĂ©s GĂ©rĂ©es de 2 types : assignĂ©es par le systĂšme et assignĂ©es par lâutilisateur.
LâidentitĂ© assignĂ©e par le systĂšme sera une identitĂ© gĂ©rĂ©e que seule la fonction qui lâa assignĂ©e pourra utiliser, tandis que les identitĂ©s gĂ©rĂ©es assignĂ©es par lâutilisateur sont des identitĂ©s gĂ©rĂ©es que tout autre service Azure pourra utiliser.
Note
Tout comme dans VMs, les fonctions peuvent avoir 1 identitĂ© gĂ©rĂ©e assignĂ©e par le systĂšme et plusieurs identitĂ©s assignĂ©es par lâutilisateur, il est donc toujours important dâessayer de trouver toutes celles-ci si vous compromettez la fonction car vous pourriez ĂȘtre en mesure dâescalader les privilĂšges Ă plusieurs identitĂ©s gĂ©rĂ©es Ă partir dâune seule fonction.
Si aucune identitĂ© gĂ©rĂ©e par le systĂšme nâest utilisĂ©e mais quâune ou plusieurs identitĂ©s gĂ©rĂ©es par lâutilisateur sont attachĂ©es Ă une fonction, par dĂ©faut, vous ne pourrez pas obtenir de jeton.
Il est possible dâutiliser les scripts PEASS pour obtenir des jetons de lâidentitĂ© gĂ©rĂ©e par dĂ©faut Ă partir du point de terminaison des mĂ©tadonnĂ©es. Ou vous pourriez les obtenir manuellement comme expliquĂ© dans :
Notez que vous devez trouver un moyen de vĂ©rifier toutes les identitĂ©s gĂ©rĂ©es quâune fonction a attachĂ©es car si vous ne lâindiquez pas, le point de terminaison des mĂ©tadonnĂ©es nâutilisera que la par dĂ©faut (voir le lien prĂ©cĂ©dent pour plus dâinformations).
ClĂ©s dâaccĂšs
Note
Notez quâil nây a pas de permissions RBAC pour donner accĂšs aux utilisateurs pour invoquer les fonctions. Lâinvocation de la fonction dĂ©pend du dĂ©clencheur sĂ©lectionnĂ© lors de sa crĂ©ation et si un dĂ©clencheur HTTP a Ă©tĂ© sĂ©lectionnĂ©, il pourrait ĂȘtre nĂ©cessaire dâutiliser une clĂ© dâaccĂšs.
Lors de la crĂ©ation dâun point de terminaison Ă lâintĂ©rieur dâune fonction utilisant un dĂ©clencheur HTTP, il est possible dâindiquer le niveau dâautorisation de clĂ© dâaccĂšs nĂ©cessaire pour dĂ©clencher la fonction. Trois options sont disponibles :
- ANONYMOUS : Tout le monde peut accĂ©der Ă la fonction par lâURL.
- FUNCTION : Le point de terminaison nâest accessible quâaux utilisateurs utilisant une clĂ© de fonction, dâhĂŽte ou maĂźtre.
- ADMIN : Le point de terminaison nâest accessible quâaux utilisateurs avec une clĂ© maĂźtre.
Type de clés :
- ClĂ©s de fonction : Les clĂ©s de fonction peuvent ĂȘtre soit par dĂ©faut soit dĂ©finies par lâutilisateur et sont conçues pour accorder un accĂšs exclusivement Ă des points de terminaison de fonction spĂ©cifiques au sein dâune Function App permettant un accĂšs plus granulaire sur les points de terminaison.
- ClĂ©s dâhĂŽte : Les clĂ©s dâhĂŽte, qui peuvent Ă©galement ĂȘtre par dĂ©faut ou dĂ©finies par lâutilisateur, fournissent un accĂšs Ă tous les points de terminaison de fonction au sein dâune Function App avec un niveau dâaccĂšs FUNCTION.
- Clé maßtre : La clé maßtre (
_master) sert de clĂ© administrative qui offre des permissions Ă©levĂ©es, y compris lâaccĂšs Ă tous les points de terminaison de fonction (niveau dâaccĂšs ADMIN inclus). Cette clĂ© ne peut pas ĂȘtre rĂ©voquĂ©e. - ClĂ©s systĂšme : Les clĂ©s systĂšme sont gĂ©rĂ©es par des extensions spĂ©cifiques et sont nĂ©cessaires pour accĂ©der aux points de terminaison webhook utilisĂ©s par des composants internes. Des exemples incluent le dĂ©clencheur Event Grid et les Durable Functions, qui utilisent des clĂ©s systĂšme pour interagir en toute sĂ©curitĂ© avec leurs API respectives.
Tip
Exemple pour accéder à un point de terminaison API de fonction en utilisant une clé :
https://<function_uniq_name>.azurewebsites.net/api/<endpoint_name>?code=<access_key>
Authentification de base
Tout comme dans les App Services, les fonctions prennent Ă©galement en charge lâauthentification de base pour se connecter Ă SCM et FTP pour dĂ©ployer du code en utilisant un nom dâutilisateur et un mot de passe dans une URL fournie par Azure. Plus dâinformations Ă ce sujet dans :
Déploiements basés sur Github
Lorsquâune fonction est gĂ©nĂ©rĂ©e Ă partir dâun dĂ©pĂŽt Github, la console web Azure permet de crĂ©er automatiquement un Workflow Github dans un dĂ©pĂŽt spĂ©cifique afin que chaque fois que ce dĂ©pĂŽt est mis Ă jour, le code de la fonction soit mis Ă jour. En fait, le fichier yaml de lâaction Github pour une fonction Python ressemble Ă ceci :
Yaml d'action Github
```yaml # Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action # More GitHub Actions for Azure: https://github.com/Azure/actions # More info on Python, GitHub Actions, and Azure Functions: https://aka.ms/python-webapps-actionsname: Build and deploy Python project to Azure Function App - funcGithub
on: push: branches:
- main workflow_dispatch:
env: AZURE_FUNCTIONAPP_PACKAGE_PATH: â.â # set this to the path to your web app project, defaults to the repository root PYTHON_VERSION: â3.11â # set this to the python version to use (supports 3.6, 3.7, 3.8)
jobs: build: runs-on: ubuntu-latest steps:
-
name: Checkout repository uses: actions/checkout@v4
-
name: Setup Python version uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }}
-
name: Create and start virtual environment run: | python -m venv venv source venv/bin/activate
-
name: Install dependencies run: pip install -r requirements.txt
Optional: Add step to run tests here
-
name: Zip artifact for deployment run: zip release.zip ./* -r
-
name: Upload artifact for deployment job uses: actions/upload-artifact@v4 with: name: python-app path: | release.zip !venv/
deploy: runs-on: ubuntu-latest needs: build
permissions: id-token: write #This is required for requesting the JWT
steps:
-
name: Download artifact from build job uses: actions/download-artifact@v4 with: name: python-app
-
name: Unzip artifact for deployment run: unzip release.zip
-
name: Login to Azure uses: azure/login@v2 with: client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_6C3396368D954957BC58E4C788D37FD1 }} tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_7E50AEF6222E4C3DA9272D27FB169CCD }} subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_905358F484A74277BDC20978459F26F4 }}
-
name: âDeploy to Azure Functionsâ uses: Azure/functions-action@v1 id: deploy-to-function with: app-name: âfuncGithubâ slot-name: âProductionâ package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
</details>
De plus, une **IdentitĂ© GĂ©rĂ©e** est Ă©galement créée afin que l'Action Github du dĂ©pĂŽt puisse se connecter Ă Azure avec elle. Cela se fait en gĂ©nĂ©rant une crĂ©dential fĂ©dĂ©rĂ©e sur l'**IdentitĂ© GĂ©rĂ©e** permettant Ă l'**Ămetteur** `https://token.actions.githubusercontent.com` et Ă l'**Identifiant de Sujet** `repo:<org-name>/<repo-name>:ref:refs/heads/<branch-name>`.
> [!CAUTION]
> Par conséquent, quiconque compromettant ce dépÎt pourra compromettre la fonction et les Identités Gérées qui y sont attachées.
### Déploiements Basés sur des Conteneurs
Tous les plans ne permettent pas de déployer des conteneurs, mais pour ceux qui le font, la configuration contiendra l'URL du conteneur. Dans l'API, le paramÚtre **`linuxFxVersion`** aura quelque chose comme : `DOCKER|mcr.microsoft.com/...`, tandis que dans la console web, la configuration affichera les **paramÚtres d'image**.
De plus, **aucun code source ne sera stocké dans le compte de stockage** lié à la fonction car cela n'est pas nécessaire.
## ĂnumĂ©ration
{{#tabs }}
{{#tab name="az cli" }}
```bash
# List all the functions
az functionapp list
# List functions in an function-app (endpoints)
az functionapp function list \
--name <app-name> \
--resource-group <res-group>
# Get details about the source of the function code
az functionapp deployment source show \
--name <app-name> \
--resource-group <res-group>
## If error like "This is currently not supported."
## Then, this is probalby using a container
# Get more info if a container is being used
az functionapp config container show \
--name <name> \
--resource-group <res-group>
# Get settings (and privesc to the sorage account)
az functionapp config appsettings list --name <app-name> --resource-group <res-group>
# Get access restrictions
az functionapp config access-restriction show --name <app-name> --resource-group <res-group>
# Check if a domain was assigned to a function app
az functionapp config hostname list --webapp-name <app-name> --resource-group <res-group>
# Get SSL certificates
az functionapp config ssl list --resource-group <res-group>
# Get network restrictions
az functionapp config access-restriction show --name <app-name> --resource-group <res-group>
# Get acess restrictions
az functionapp config access-restriction show --name <app-name> --resource-group <res-group>
# Get connection strings
az rest --method POST --uri "https://management.azure.com/subscriptions/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/connectionstrings/list?api-version=2022-03-01"
az rest --method GET --uri "https://management.azure.com/subscriptions/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/configreferences/connectionstrings?api-version=2022-03-01"
# Get SCM credentials
az functionapp deployment list-publishing-credentials --name <app-name> --resource-group <res-group>
# Get function, system and master keys
az functionapp keys list --name <app-name> --resource-group <res-group>
#Â Get Host key
az rest --method POST --uri "https://management.azure.com/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions/<function-endpoint-name>/listKeys?api-version=2022-03-01"
# Get source code with Master Key of the function
curl "<script_href>?code=<master-key>"
curl "https://<func-app-name>.azurewebsites.net/admin/vfs/home/site/wwwroot/function_app.py?code=<master-key>" -v
# Get source code using SCM access (Azure permissions or SCM creds)
az rest --method GET \
--url "https://<func-app-name>.azurewebsites.net/admin/vfs/home/site/wwwroot/function_app.py?code=<master-key>" \
--resource "https://management.azure.com/"
# Get source code with Azure permissions
az rest --url "https://management.azure.com/subscriptions/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01"
## Another example
az rest --url "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Web/sites/ConsumptionExample/hostruntime/admin/vfs/HttpExample/index.js?relativePath=1&api-version=2022-03-01"
{{#endtab }}
{{#tab name=âAz Powershellâ }}
Get-Command -Module Az.Functions
# Lists all Function Apps in the current subscription or in a specific resource group.
Get-AzFunctionApp -ResourceGroupName <String>
# Displays the regions where Azure Function Apps are available for deployment.
Get-AzFunctionAppAvailableLocation
# Retrieves details about Azure Function App plans in a subscription or resource group.
Get-AzFunctionAppPlan -ResourceGroupName <String> -Name <String>
# Retrieves the app settings for a specific Azure Function App.
Get-AzFunctionAppSetting -Name <FunctionAppName> -ResourceGroupName <ResourceGroupName>
{{#endtab }} {{#endtabs }}
Escalade de privilĂšges
Références
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
HackTricks Cloud

