Az - Function Apps

Reading time: 13 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Основна інформація

Azure Function Apps - це безсерверна обчислювальна служба, яка дозволяє запускати невеликі фрагменти коду, звані функціями, без управління підлягаючою інфраструктурою. Вони призначені для виконання коду у відповідь на різні тригери, такі як HTTP запити, таймери або події з інших служб Azure, таких як Blob Storage або Event Hubs. Function Apps підтримують кілька мов програмування, включаючи C#, Python, JavaScript та Java, що робить їх універсальними для створення додатків, орієнтованих на події, автоматизації робочих процесів або інтеграції служб. Вони економічні, оскільки зазвичай ви платите лише за час обчислень, коли ваш код виконується.

note

Зверніть увагу, що Functions є підмножиною App Services, тому багато функцій, обговорюваних тут, також будуть використовуватися додатками, створеними як Azure Apps (webapp в cli).

Різні плани

  • Flex Consumption Plan: Пропонує динамічне, орієнтоване на події масштабування з оплатою за фактом використання, додаючи або видаляючи екземпляри функцій залежно від попиту. Підтримує віртуальну мережу та попередньо підготовлені екземпляри, щоб зменшити холодні старти, що робить його підходящим для змінних навантажень, які не потребують підтримки контейнерів.
  • Traditional Consumption Plan: За замовчуванням безсерверний варіант, де ви платите лише за обчислювальні ресурси, коли функції виконуються. Автоматично масштабується на основі вхідних подій і включає оптимізації холодного старту, але не підтримує розгортання контейнерів. Ідеально підходить для перемінних навантажень, які потребують автоматичного масштабування.
  • Premium Plan: Призначений для послідовної продуктивності, з попередньо прогрітими працівниками, щоб усунути холодні старти. Пропонує подовжені часи виконання, віртуальну мережу та підтримує кастомізовані образи Linux, що робить його ідеальним для додатків критичного призначення, які потребують високої продуктивності та розширених функцій.
  • Dedicated Plan: Виконується на виділених віртуальних машинах з передбачуваним білінгом і підтримує ручне або автоматичне масштабування. Дозволяє запускати кілька додатків на одному плані, забезпечує ізоляцію обчислень і гарантує безпечний доступ до мережі через App Service Environments, що робить його ідеальним для додатків з тривалим виконанням, які потребують постійного виділення ресурсів.
  • Container Apps: Дозволяє розгортати контейнеризовані функціональні додатки в керованому середовищі, поряд з мікросервісами та API. Підтримує кастомні бібліотеки, міграцію спадкових додатків та обробку GPU, усуваючи управління кластерами Kubernetes. Ідеально підходить для додатків, орієнтованих на події, масштабованих контейнеризованих.

Сховища

При створенні нового Function App, не контейнеризованого (але з наданим кодом для виконання), код та інші дані, пов'язані з функцією, будуть зберігатися в обліковому записі сховища. За замовчуванням веб-консоль створить новий обліковий запис для кожної функції для зберігання коду.

Більше того, модифікуючи код всередині сховища (в різних форматах, в яких він може бути збережений), код програми буде змінено на новий і виконано наступного разу, коли функція буде викликана.

caution

Це дуже цікаво з точки зору атакуючого, оскільки доступ на запис до цього сховища дозволить атакуючому компрометувати код і підвищити привілеї до керованих ідентичностей всередині Function App.

Більше про це в розділі підвищення привілеїв.

Також можливо знайти ключі майстра та функцій, збережені в обліковому записі сховища в контейнері azure-webjobs-secrets всередині папки <app-name> у JSON-файлах, які ви можете знайти всередині.

Зверніть увагу, що Functions також дозволяють зберігати код у віддаленому місці, просто вказуючи URL на нього.

Мережа

Використовуючи HTTP тригер:

  • Можливо надати доступ до функції з усієї Інтернету без вимоги будь-якої аутентифікації або надати доступ на основі IAM. Хоча також можливо обмежити цей доступ.
  • Також можливо надати або обмежити доступ до Function App з внутрішньої мережі (VPC).

caution

Це дуже цікаво з точки зору атакуючого, оскільки може бути можливим переходити до внутрішніх мереж з вразливої функції, виставленої в Інтернет.

Налаштування Function App та змінні середовища

Можливо налаштувати змінні середовища всередині програми, які можуть містити чутливу інформацію. Більше того, за замовчуванням змінні середовища AzureWebJobsStorage та WEBSITE_CONTENTAZUREFILECONNECTIONSTRING (серед інших) створюються. Ці змінні особливо цікаві, оскільки містять ключ облікового запису для контролю з ПОВНИМИ правами доступу до облікового запису сховища, що містить дані програми. Ці налаштування також потрібні для виконання коду з облікового запису сховища.

Ці змінні середовища або параметри конфігурації також контролюють, як функція виконує код, наприклад, якщо WEBSITE_RUN_FROM_PACKAGE існує, це вказує на URL, де розташований код програми.

Пісочниця функцій

Всередині пісочниці Linux вихідний код розташований у /home/site/wwwroot у файлі function_app.py (якщо використовується Python), користувач, що виконує код, - app (без прав sudo).

У Windows функції, що використовує NodeJS, код розташовувався у C:\home\site\wwwroot\HttpTrigger1\index.js, ім'я користувача було mawsFnPlaceholder8_f_v4_node_20_x86 і він був частиною груп: 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.

Керовані ідентичності та метадані

Так само, як і VMs, функції можуть мати керовані ідентичності двох типів: системно призначені та призначені користувачем.

Системно призначена ідентичність буде керованою ідентичністю, яку тільки функція, якій вона призначена, зможе використовувати, тоді як призначені користувачем керовані ідентичності - це керовані ідентичності, які будь-яка інша служба Azure зможе використовувати.

note

Так само, як і в VMs, функції можуть мати 1 системно призначену керовану ідентичність і кілька призначених користувачем, тому завжди важливо намагатися знайти всі з них, якщо ви компрометуєте функцію, оскільки ви можете підвищити привілеї до кількох керованих ідентичностей з однієї функції.

Якщо не використовується системно призначена ідентичність, але одна або кілька призначених користувачем ідентичностей прикріплені до функції, за замовчуванням ви не зможете отримати жоден токен.

Можливо використовувати PEASS скрипти для отримання токенів з за замовчуванням керованої ідентичності з кінцевої точки метаданих. Або ви можете отримати їх вручну, як пояснено в:

Cloud SSRF - HackTricks

Зверніть увагу, що вам потрібно знайти спосіб перевірити всі керовані ідентичності, прикріплені до функції, оскільки якщо ви цього не вкажете, кінцева точка метаданих використовуватиме лише за замовчуванням (перевірте попереднє посилання для отримання додаткової інформації).

Ключі доступу

note

Зверніть увагу, що немає прав RBAC для надання доступу користувачам для виклику функцій. Виклик функції залежить від тригера, вибраного під час її створення, і якщо був вибраний HTTP тригер, можливо, знадобиться використовувати ключ доступу.

При створенні кінцевої точки всередині функції, використовуючи HTTP тригер, можливо вказати рівень авторизації ключа доступу, необхідний для виклику функції. Доступні три варіанти:

  • ANONYMOUS: Кожен може отримати доступ до функції за URL.
  • FUNCTION: Кінцева точка доступна лише користувачам, які використовують ключ функції, хоста або майстра.
  • ADMIN: Кінцева точка доступна лише користувачам з ключем майстра.

Типи ключів:

  • Ключі функцій: Ключі функцій можуть бути або за замовчуванням, або визначеними користувачем і призначені для надання доступу виключно до конкретних кінцевих точок функцій в рамках Function App, що дозволяє більш детально контролювати доступ до кінцевих точок.
  • Ключі хоста: Ключі хоста, які також можуть бути за замовчуванням або визначеними користувачем, надають доступ до всіх кінцевих точок функцій в рамках Function App з рівнем доступу FUNCTION.
  • Ключ майстра: Ключ майстра (_master) слугує адміністративним ключем, який пропонує підвищені права, включаючи доступ до всіх кінцевих точок функцій (включаючи рівень доступу ADMIN). Цей ключ не може бути відкликаний.
  • Системні ключі: Системні ключі керуються конкретними розширеннями і потрібні для доступу до кінцевих точок вебхуків, які використовуються внутрішніми компонентами. Прикладами є тригер Event Grid та Durable Functions, які використовують системні ключі для безпечної взаємодії з їхніми відповідними API.

tip

Приклад доступу до кінцевої точки API функції, використовуючи ключ:

https://<function_uniq_name>.azurewebsites.net/api/<endpoint_name>?code=<access_key>

Основна аутентифікація

Так само, як і в App Services, функції також підтримують основну аутентифікацію для підключення до SCM та FTP для розгортання коду, використовуючи ім'я користувача та пароль в URL, наданому Azure. Більше інформації про це в:

Az - Azure App Services

Розгортання на основі Github

Коли функція генерується з репозиторію Github, веб-консоль Azure дозволяє автоматично створити робочий процес Github у конкретному репозиторії, тому що щоразу, коли цей репозиторій оновлюється, код функції оновлюється. Насправді YAML дії Github для функції Python виглядає так:

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

name: 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 }}

Більше того, Managed Identity також створюється, щоб Github Action з репозиторію міг увійти в Azure з його допомогою. Це робиться шляхом генерації федеративних облікових даних через Managed Identity, що дозволяє Issuer https://token.actions.githubusercontent.com та Subject Identifier repo:<org-name>/<repo-name>:ref:refs/heads/<branch-name>.

caution

Отже, будь-хто, хто скомпрометує цей репозиторій, зможе скомпрометувати функцію та пов'язані з нею Managed Identities.

Деплойменти на основі контейнерів

Не всі плани дозволяють розгортати контейнери, але для тих, що дозволяють, конфігурація міститиме URL контейнера. В API налаштування linuxFxVersion матиме щось на зразок: DOCKER|mcr.microsoft.com/..., тоді як у веб-консолі конфігурація відображатиме налаштування зображення.

Більше того, жоден вихідний код не буде зберігатися в обліковому записі зберігання, пов'язаному з функцією, оскільки це не потрібно.

Перерахування

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"

Підвищення Привілеїв

Az - Functions App Privesc

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks