Files
hacktricks-cloud/src/pentesting-cloud/azure-security/az-services/az-function-apps.md

16 KiB
Raw Blame History

Az - Function Apps

{{#include ../../../banners/hacktricks-training.md}}

Temel Bilgiler

Azure Function Apps, temel altyapıyı yönetmeden fonksiyon adı verilen küçük kod parçalarını çalıştırmanıza olanak tanıyan bir sunucusuz hesaplama hizmetidir. HTTP istekleri, zamanlayıcılar veya Blob Depolama veya Olay Hub'ları gibi diğer Azure hizmetlerinden gelen olaylar gibi çeşitli tetikleyicilere yanıt olarak kod çalıştırmak için tasarlanmıştır. Function Apps, C#, Python, JavaScript ve Java gibi birden fazla programlama dilini destekleyerek olay odaklı uygulamalar, iş akışlarını otomatikleştirme veya hizmetleri entegre etme için çok yönlü hale getirir. Genellikle kodunuz çalıştığında yalnızca kullanılan hesaplama süresi için ödeme yapmanız gerektiğinden maliyet açısından etkilidir.

Note

Fonksiyonlar, Uygulama Hizmetlerinin bir alt kümesidir, bu nedenle burada tartışılan birçok özellik, Azure Uygulamaları (webapp cli'de) olarak oluşturulan uygulamalar tarafından da kullanılacaktır.

Farklı Planlar

  • Flex Tüketim Planı: Talebe göre fonksiyon örneklerini ekleyip kaldırarak dinamik, olay odaklı ölçekleme sunar ve kullanım başına ödeme modeli ile çalışır. Sanal ağ ve önceden sağlanmış örnekler ile soğuk başlangıçları azaltarak, konteyner desteği gerektirmeyen değişken iş yükleri için uygundur.
  • Geleneksel Tüketim Planı: Fonksiyonlar çalıştığında yalnızca hesaplama kaynakları için ödeme yaptığınız varsayılan sunucusuz seçenektir. Gelen olaylara göre otomatik olarak ölçeklenir ve soğuk başlangıç optimizasyonları içerir, ancak konteyner dağıtımlarını desteklemez. Otomatik ölçekleme gerektiren kesintili iş yükleri için idealdir.
  • Premium Plan: Tutarlı performans için tasarlanmıştır, soğuk başlangıçları ortadan kaldırmak için önceden ısıtılmış işçiler sunar. Uzun süreli yürütme süreleri, sanal ağ sunar ve özel Linux görüntülerini destekler, bu da yüksek performans ve gelişmiş özellikler gerektiren misyon kritik uygulamalar için mükemmeldir.
  • Özel Plan: Öngörülebilir faturalama ile özel sanal makinelerde çalışır ve manuel veya otomatik ölçeklemeyi destekler. Aynı planda birden fazla uygulama çalıştırmaya olanak tanır, hesaplama izolasyonu sağlar ve App Service Environments aracılığıyla güvenli ağ erişimi sağlar, bu da tutarlı kaynak tahsisi gerektiren uzun süreli uygulamalar için idealdir.
  • Konteyner Uygulamaları: Konteynerleştirilmiş fonksiyon uygulamalarını yönetilen bir ortamda, mikro hizmetler ve API'lerle birlikte dağıtmayı sağlar. Özel kütüphaneleri, eski uygulama geçişini ve GPU işleme destekler, Kubernetes küme yönetimini ortadan kaldırır. Olay odaklı, ölçeklenebilir konteynerleştirilmiş uygulamalar için idealdir.

Depolama Kovalari

Yeni bir konteynerleştirilmemiş Function App oluşturduğunuzda (ancak çalıştırılacak kodu veriyorsanız), kod ve diğer Fonksiyon ile ilgili veriler bir Depolama hesabında saklanacaktır. Varsayılan olarak, web konsolu her fonksiyon için kodu saklamak üzere yeni bir tane oluşturur.

Ayrıca, kova içindeki kodu (saklanabileceği farklı formatlarda) değiştirdiğinizde, uygulamanın kodu yeni olanla değiştirilir ve bir sonraki fonksiyon çağrıldığında çalıştırılır.

Caution

Bu, bir saldırganın bu kovaya yazma erişimi olması durumunda kodun tehlikeye atılmasına ve Fonksiyon Uygulamasındaki yönetilen kimliklere yetki yükseltmesine olanak tanıdığı için saldırganlar açısından çok ilginçtir.

Bununla ilgili daha fazla bilgi yetki yükseltme bölümünde.

Ayrıca, azure-webjobs-secrets konteynerinde depolama hesabında saklanan master ve fonksiyon anahtarlarını bulmak da mümkündür; bu anahtarlar <app-name> klasöründeki JSON dosyalarında bulunabilir.

Fonksiyonlar ayrıca kodu uzaktan bir konumda saklamanıza da olanak tanır; sadece URL'yi belirtmeniz yeterlidir.

HTTP tetikleyicisi kullanarak:

  • Tüm İnternet'ten bir fonksiyona erişim vermek mümkündür; bu, herhangi bir kimlik doğrulama gerektirmeden veya IAM tabanlı erişim vermeden yapılabilir. Ancak bu erişimi kısıtlamak da mümkündür.
  • Bir iç ağdan (VPC) bir Function App'a erişim vermek veya kısıtlamak da mümkündür.

Caution

Bu, bir saldırganın İnternete açık bir zayıf Fonksiyondan iç ağlara geçiş yapma olasılığı olduğu için saldırganlar açısından çok ilginçtir.

Function App Ayarları & Ortam Değişkenleri

Bir uygulama içinde ortam değişkenlerini yapılandırmak mümkündür; bu değişkenler hassas bilgiler içerebilir. Ayrıca, varsayılan olarak AzureWebJobsStorage ve WEBSITE_CONTENTAZUREFILECONNECTIONSTRING (diğerleri arasında) gibi env değişkenleri oluşturulur. Bu değişkenler, uygulamanın verilerini içeren depolama hesabını kontrol etmek için TAM izinlere sahip hesap anahtarını içerdiği için özellikle ilginçtir. Bu ayarlar, Depolama Hesabından kodu çalıştırmak için de gereklidir.

Bu env değişkenleri veya yapılandırma parametreleri, Fonksiyonun kodu nasıl çalıştırdığını da kontrol eder; örneğin, WEBSITE_RUN_FROM_PACKAGE varsa, bu, uygulamanın kodunun bulunduğu URL'yi belirtir.

Function Sandbox

Linux sandbox içinde kaynak kodu /home/site/wwwroot dizininde function_app.py dosyasında (Python kullanılıyorsa) bulunur; kodu çalıştıran kullanıcı app'dir (sudo izinleri olmadan).

Bir Windows fonksiyonunda NodeJS kullanıldığında kod C:\home\site\wwwroot\HttpTrigger1\index.js dizininde bulunuyordu; kullanıcı adı mawsFnPlaceholder8_f_v4_node_20_x86 idi ve grupların bir parçasıydı: 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.

Yönetilen Kimlikler & Meta Veriler

VM'ler gibi, Fonksiyonların 2 tür Yönetilen Kimliği olabilir: Sistem atanan ve Kullanıcı atanan.

Sistem atanan olan, yalnızca atandığı fonksiyon tarafından kullanılabilen bir yönetilen kimliktir; kullanıcı atanan yönetilen kimlikler ise herhangi bir diğer Azure hizmeti tarafından kullanılabilen yönetilen kimliklerdir.

Note

VM'ler gibi, Fonksiyonların 1 sistem atanan yönetilen kimliği ve birden fazla kullanıcı atanan yönetilen kimliği olabilir, bu nedenle fonksiyonu tehlikeye attığınızda hepsini bulmaya çalışmak her zaman önemlidir; çünkü bir Fonksiyondan birden fazla yönetilen kimliğe yetki yükseltebilirsiniz.

Eğer bir sistem yönetilen kimliği kullanılmıyorsa ancak bir veya daha fazla kullanıcı yönetilen kimliği bir fonksiyona bağlıysa, varsayılan olarak herhangi bir token alamazsınız.

PEASS scriptlerini kullanarak, varsayılan yönetilen kimlikten token alabilirsiniz. Ya da bunları manuel olarak alabilirsiniz; bu konuda daha fazla bilgi için:

{% embed url="https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf#azure-vm" %}

Bir fonksiyonun bağlı olduğu tüm Yönetilen Kimlikleri kontrol etmenin bir yolunu bulmanız gerektiğini unutmayın; çünkü belirtmezseniz, meta veri uç noktası yalnızca varsayılan olanı kullanacaktır (daha fazla bilgi için önceki bağlantıya bakın).

Erişim Anahtarları

Note

Kullanıcılara fonksiyonları çağırma erişimi vermek için RBAC izinleri yoktur. Fonksiyon çağrısı, oluşturulurken seçilen tetikleyiciye bağlıdır ve bir HTTP Tetikleyici seçildiyse, bir erişim anahtarı kullanmanız gerekebilir.

Bir fonksiyon içinde bir HTTP tetikleyici kullanarak bir uç nokta oluşturduğunuzda, fonksiyonu tetiklemek için gereken erişim anahtarı yetkilendirme seviyesini belirtmek mümkündür. Üç seçenek mevcuttur:

  • ANONYMOUS: Herkes, URL aracılığıyla fonksiyona erişebilir.
  • FUNCTION: Uç nokta yalnızca fonksiyon, ana bilgisayar veya master anahtar kullanan kullanıcılara açıktır.
  • ADMIN: Uç nokta yalnızca master anahtar kullanan kullanıcılara açıktır.

Anahtar türleri:

  • Fonksiyon Anahtarları: Fonksiyon anahtarları varsayılan veya kullanıcı tanımlı olabilir ve yalnızca bir Function App içindeki belirli fonksiyon uç noktalarına erişim sağlamak için tasarlanmıştır; bu, uç noktalar üzerinde daha ince ayarlı bir erişim sağlar.
  • Ana Bilgisayar Anahtarları: Ana bilgisayar anahtarları, varsayılan veya kullanıcı tanımlı olabilir ve FUNCTION erişim seviyesine sahip bir Function App içindeki tüm fonksiyon uç noktalarına erişim sağlar.
  • Master Anahtar: Master anahtar (_master), tüm fonksiyon uç noktalarına (ADMIN erişim seviyesi dahil) erişim sağlayan yönetim anahtarıdır. Bu anahtar iptal edilemez.
  • Sistem Anahtarları: Sistem anahtarları, belirli uzantılar tarafından yönetilir ve iç bileşenler tarafından kullanılan webhook uç noktalarına erişim için gereklidir. Örnekler arasında sistem anahtarlarını güvenli bir şekilde kendi API'leriyle etkileşimde bulunmak için kullanan Olay Grid tetikleyicisi ve Dayanıklı Fonksiyonlar bulunur.

Tip

Bir anahtar kullanarak bir fonksiyon API uç noktasına erişim örneği:

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

Temel Kimlik Doğrulama

Uygulama Hizmetlerinde olduğu gibi, Fonksiyonlar da SCM ve FTP ile bağlanmak için temel kimlik doğrulamayı destekler; bu, Azure tarafından sağlanan bir kullanıcı adı ve şifre ile URL kullanarak kod dağıtımına olanak tanır. Bununla ilgili daha fazla bilgi için:

{{#ref}} az-app-services.md {{#endref}}

Github Tabanlı Dağıtımlar

Bir fonksiyon bir Github reposundan oluşturulduğunda, Azure web konsolu, bu depo güncellendiğinde fonksiyonun kodunu otomatik olarak güncellemek için belirli bir depoda bir Github İş Akışı oluşturmayı sağlar. Aslında, bir Python fonksiyonu için Github Action yaml'ı şöyle görünür:

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

</details>

Ayrıca, bir **Managed Identity** de oluşturulur, böylece depodaki Github Action Azure'a bu kimlik ile giriş yapabilir. Bu, **Managed Identity** üzerinde bir Federated kimlik bilgisi oluşturarak yapılır ve **Issuer** `https://token.actions.githubusercontent.com` ile **Subject Identifier** `repo:<org-name>/<repo-name>:ref:refs/heads/<branch-name>` belirlenir.

> [!CAUTION]
> Bu nedenle, o depoyu ele geçiren herkes, işlevi ve ona bağlı Managed Identities'i ele geçirebilir.

### Konteyner Tabanlı Dağıtımlar

Tüm planlar konteyner dağıtımına izin vermez, ancak izin verenler için yapılandırma konteynerin URL'sini içerecektir. API'de **`linuxFxVersion`** ayarı şöyle bir şey olacaktır: `DOCKER|mcr.microsoft.com/...`, web konsolunda ise yapılandırma **image settings** olarak gösterilecektir.

Ayrıca, **kaynak kodu işlevle ilgili depolama** hesabında saklanmayacaktır çünkü bu gerekli değildir.

## Enumeration
```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"

Yetki Yükseltme

{{#ref}} ../az-privilege-escalation/az-functions-app-privesc.md {{#endref}}

Referanslar

{{#include ../../../banners/hacktricks-training.md}}