16 KiB
Az - Function Apps
{{#include ../../../banners/hacktricks-training.md}}
Basiese Inligting
Azure Function Apps is 'n serverless compute service wat jou toelaat om klein stukke kode, genoem functions, te loop sonder om die onderliggende infrastruktuur te bestuur. Hulle is ontwerp om kode uit te voer in reaksie op verskeie triggers, soos HTTP versoeke, timers, of gebeurtenisse van ander Azure dienste soos Blob Storage of Event Hubs. Function Apps ondersteun verskeie programmeertale, insluitend C#, Python, JavaScript, en Java, wat hulle veelsydig maak vir die bou van gebeurtenis-gedrewe toepassings, outomatisering van werksvloei, of integrasie van dienste. Hulle is kostedoeltreffend, aangesien jy gewoonlik net betaal vir die rekenaartyd wat gebruik word wanneer jou kode loop.
Note
Let daarop dat Functions 'n substel van die App Services is, daarom sal baie van die funksies wat hier bespreek word ook deur toepassings wat as Azure Apps geskep is (
webappin cli) gebruik word.
Verskillende Planne
- Flex Consumption Plan: Bied dinamiese, gebeurtenis-gedrewe skaalvergroting met 'n betaal-vir-wat-jy-gebruik prysmodel, wat funksie-instanties byvoeg of verwyder op grond van vraag. Dit ondersteun virtuele netwerke en vooraf-geprovisioneerde instansies om koue begin te verminder, wat dit geskik maak vir veranderlike werklas wat nie hou van houerondersteuning vereis nie.
- Traditional Consumption Plan: Die standaard serverless opsie, waar jy net betaal vir rekenaarbronne wanneer funksies loop. Dit skaal outomaties op grond van inkomende gebeurtenisse en sluit kouestart-optimalisering in, maar ondersteun nie houerontplooiings nie. Ideaal vir intermitterende werklas wat outomatiese skaalvergroting vereis.
- Premium Plan: Ontwerp vir konstante prestasie, met voorverhitte werkers om koue begin te elimineer. Dit bied verlengde uitvoertye, virtuele netwerke, en ondersteun aangepaste Linux beelde, wat dit perfek maak vir missie-kritieke toepassings wat hoë prestasie en gevorderde funksies benodig.
- Dedicated Plan: Loop op toegewyde virtuele masjiene met voorspelbare fakturering en ondersteun handmatige of outomatiese skaalvergroting. Dit laat toe om verskeie toepassings op dieselfde plan te loop, bied rekenaarisolering, en verseker veilige netwerktoegang via App Service Omgewings, wat dit ideaal maak vir lanklopende toepassings wat konstante hulpbron toewysing benodig.
- Container Apps: Maak dit moontlik om gecontaineriseerde funksie-apps in 'n bestuurde omgewing te ontplooi, langs mikro-dienste en API's. Dit ondersteun aangepaste biblioteke, erflike app migrasie, en GPU verwerking, wat die bestuur van Kubernetes klusters elimineer. Ideaal vir gebeurtenis-gedrewe, skaalbare gecontaineriseerde toepassings.
Stoor Emmers
Wanneer 'n nuwe Function App geskep word wat nie gecontaineriseerd is nie (maar die kode om te loop gee), sal die kode en ander funksie-verwante data in 'n Stoor rekening gestoor word. Standaard sal die webkonsol 'n nuwe een per funksie skep om die kode te stoor.
Boonop, deur die kode binne die emmer te wysig (in die verskillende formate waarin dit gestoor kan word), sal die kode van die app gewysig word na die nuwe een en uitgevoer word die volgende keer dat die Funksie genoem word.
Caution
Dit is baie interessant vanuit 'n aanvallers perspektief aangesien skrywe toegang oor hierdie emmer 'n aanvaller sal toelaat om die kode te kompromitteer en bevoegdhede te verhoog na die bestuurde identiteite binne die Function App.
Meer hieroor in die bevoegdheid verhoging afdeling.
Dit is ook moontlik om die master en funksies sleutels wat in die stoor rekening gestoor is, in die houer azure-webjobs-secrets binne die gids <app-name> in die JSON-lêers wat jy daarbinne kan vind.
Let daarop dat Funksies ook toelaat om die kode in 'n afgeleë plek te stoor deur net die URL daarna te dui.
Netwerk
Met 'n HTTP-trigger:
- Dit is moontlik om toegang tot 'n funksie van die hele Internet te gee sonder om enige verifikasie te vereis of toegang op IAM-basis te gee. Alhoewel dit ook moontlik is om hierdie toegang te beperk.
- Dit is ook moontlik om toegang te gee of te beperk tot 'n Function App van 'n interne netwerk (VPC).
Caution
Dit is baie interessant vanuit 'n aanvallers perspektief aangesien dit moontlik mag wees om te pivot na interne netwerke vanaf 'n kwesbare Funksie wat aan die Internet blootgestel is.
Function App Instellings & Omgewing Veranderlikes
Dit is moontlik om omgewing veranderlikes binne 'n app te konfigureer, wat sensitiewe inligting kan bevat. Boonop, standaard word die omgewing veranderlikes AzureWebJobsStorage en WEBSITE_CONTENTAZUREFILECONNECTIONSTRING (onder andere) geskep. Hierdie is spesiaal interessant omdat hulle die rekening sleutel bevat om met VOLLE toestemmings die stoor rekening wat die data van die toepassing bevat, te beheer. Hierdie instellings is ook nodig om die kode van die Stoor Rekening uit te voer.
Hierdie omgewing veranderlikes of konfigurasie parameters beheer ook hoe die Funksie die kode uitvoer, byvoorbeeld as WEBSITE_RUN_FROM_PACKAGE bestaan, sal dit die URL aandui waar die kode van die toepassing geleë is.
Function Sandbox
Binne die linux sandbox is die bronkode geleë in /home/site/wwwroot in die lêer function_app.py (as python gebruik word) die gebruiker wat die kode loop is app (sonder sudo toestemmings).
In 'n Windows funksie wat NodeJS gebruik, was die kode geleë in C:\home\site\wwwroot\HttpTrigger1\index.js, die gebruikersnaam was mawsFnPlaceholder8_f_v4_node_20_x86 en was deel van die groepe: 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.
Bestuurde Identiteite & Metadata
Net soos VMs, kan Funksies Bestuurde Identiteite van 2 tipes hê: Stelsel toegeken en Gebruiker toegeken.
Die stelsel toegeken een sal 'n bestuurde identiteit wees wat net die funksie wat dit toegeken het, kan gebruik, terwyl die gebruiker toegeken bestuurde identiteite bestuurde identiteite is wat enige ander Azure diens kan gebruik.
Note
Net soos in VMs, kan Funksies 1 stelsel toegeken bestuurde identiteit en verskeie gebruiker toegeken hê, so dit is altyd belangrik om te probeer om al hulle te vind as jy die funksie kompromitteer omdat jy dalk bevoegdhede kan verhoog na verskeie bestuurde identiteite vanaf net een Funksie.
As 'n geen stelsel bestuurde identiteit gebruik word nie, maar een of meer gebruiker bestuurde identiteite aan 'n funksie geheg is, sal jy standaard nie in staat wees om enige token te kry nie.
Dit is moontlik om die PEASS skripte te gebruik om tokens van die standaard bestuurde identiteit van die metadata eindpunt te kry. Of jy kan dit handmatig kry soos verduidelik in:
{% embed url="https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm" %}
Let daarop dat jy 'n manier moet vind om alle Bestuurde Identiteite wat 'n funksie het, te kontroleer aangesien as jy dit nie aandui nie, die metadata eindpunt net die standaard een sal gebruik (kyk na die vorige skakel vir meer inligting).
Toegang Sleutels
Note
Let daarop dat daar geen RBAC toestemmings is om toegang aan gebruikers te gee om die funksies aan te roep nie. Die funksie aanroep hang af van die trigger wat gekies is toe dit geskep is en as 'n HTTP Trigger gekies is, mag dit nodig wees om 'n toegang sleutel te gebruik.
Wanneer 'n eindpunt binne 'n funksie geskep word met 'n HTTP trigger is dit moontlik om die toegang sleutel outorisatienvlak aan te dui wat nodig is om die funksie te trigger. Drie opsies is beskikbaar:
- ANONYMOUS: Enigiemand kan toegang tot die funksie verkry deur die URL.
- FUNCTION: Eindpunt is slegs toeganklik vir gebruikers wat 'n funksie, gasheer of meester sleutel gebruik.
- ADMIN: Eindpunt is slegs toeganklik vir gebruikers met 'n meester sleutel.
Tipe sleutels:
- Funksie Sleutels: Funksie sleutels kan of standaard of gebruiker-gedefinieerd wees en is ontwerp om toegang eksklusief tot spesifieke funksie eindpunte binne 'n Function App te verleen wat 'n meer fyngekorreleerde toegang oor die eindpunte toelaat.
- Gasheer Sleutels: Gasheer sleutels, wat ook standaard of gebruiker-gedefinieerd kan wees, bied toegang tot alle funksie eindpunte binne 'n Function App met FUNKSIE toegang vlak.
- Meester Sleutel: Die meester sleutel (
_master) dien as 'n administratiewe sleutel wat verhoogde toestemmings bied, insluitend toegang tot alle funksie eindpunte (ADMIN toegang vlak ingesluit). Hierdie sleutel kan nie herroep word nie. - Stelsel Sleutels: Stelsel sleutels word bestuur deur spesifieke uitbreidings en is nodig vir toegang tot webhook eindpunte wat deur interne komponente gebruik word. Voorbeelde sluit die Event Grid trigger en Durable Functions in, wat stelsel sleutels gebruik om veilig met hul onderskeie API's te kommunikeer.
Tip
Voorbeeld om toegang tot 'n funksie API eindpunt te verkry met 'n sleutel:
https://<function_uniq_name>.azurewebsites.net/api/<endpoint_name>?code=<access_key>
Basiese Verifikasie
Net soos in App Services, ondersteun Funksies ook basiese verifikasie om te verbind met SCM en FTP om kode te ontplooi met 'n gebruikersnaam en wagwoord in 'n URL wat deur Azure verskaf word. Meer inligting daaroor in:
{{#ref}} az-app-services.md {{#endref}}
Github Gebaseerde Ontplooiings
Wanneer 'n funksie gegenereer word uit 'n Github repo, laat die Azure webkonsol toe om automaties 'n Github Workflow in 'n spesifieke repository te skep sodat wanneer hierdie repository opgedateer word, die kode van die funksie opgedateer word. Trouens, die Github Action yaml vir 'n python funksie lyk soos volg:
Github Action Yaml
```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>
Boonop, 'n **Gemanagte Identiteit** word ook geskep sodat die Github Aksie van die repository in Azure kan aanmeld. Dit word gedoen deur 'n Federated credential oor die **Gemanagte Identiteit** te genereer wat die **Issuer** `https://token.actions.githubusercontent.com` en die **Subject Identifier** `repo:<org-name>/<repo-name>:ref:refs/heads/<branch-name>` toelaat.
> [!CAUTION]
> Daarom sal enigeen wat daardie repo kompromitteer, in staat wees om die funksie en die Gemanagte Identiteite wat daaraan gekoppel is, te kompromitteer.
### Hou gebaseerde Ontplooiings
Nie al die planne laat toe om houers te ontplooi nie, maar vir diegene wat dit doen, sal die konfigurasie die URL van die houer bevat. In die API sal die **`linuxFxVersion`** instelling iets soos hê: `DOCKER|mcr.microsoft.com/...`, terwyl die webkonsol die **beeldinstellings** sal wys.
Boonop sal **geen bronkode in die stoor** rekening wat met die funksie verband hou, gestoor word nie, aangesien dit nie nodig is nie.
## Enumerasie
{% tabs %}
{% tab title="az cli" %}
{% code overflow="wrap" %}
```bash
# List all the functions
az functionapp list
# Get info of 1 funciton (although in the list you already get this info)
az functionapp show --name <app-name> --resource-group <res-group>
## If "linuxFxVersion" has something like: "DOCKER|mcr.microsoft.com/..."
## This is using a container
# 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>
# 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 more info about a function (invoke_url_template is the URL to invoke and script_href allows to see the code)
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions?api-version=2024-04-01"
# Get source code with Master Key of the function
curl "<script_href>?code=<master-key>"
## Python example
curl "https://newfuncttest123.azurewebsites.net/admin/vfs/home/site/wwwroot/function_app.py?code=<master-key>" -v
# Get source code
az rest --url "https://management.azure.com/<subscription>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01"
{% endcode %} {% endtab %}
{% tab title="Az PowerShell" %} {% code overflow="wrap" %}
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>
{% endcode %} {% endtab %} {% endtabs %}
Privilege Escalation
{{#ref}} ../az-privilege-escalation/az-functions-app-privesc.md {{#endref}}
References
{{#include ../../../banners/hacktricks-training.md}}