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

312 lines
28 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Az - Function Apps
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
**Azure Function Apps** एक **serverless compute service** हैं जो आपको **functions** नामक छोटे कोड के टुकड़े चलाने की अनुमति देती हैं, बिना अंतर्निहित बुनियादी ढांचे का प्रबंधन किए। इन्हें विभिन्न ट्रिगर्स के जवाब में कोड निष्पादित करने के लिए डिज़ाइन किया गया है, जैसे कि **HTTP अनुरोध, टाइमर, या अन्य Azure सेवाओं** से घटनाएँ जैसे Blob Storage या Event Hubs। Function Apps कई प्रोग्रामिंग भाषाओं का समर्थन करते हैं, जिसमें C#, Python, JavaScript, और Java शामिल हैं, जिससे ये **event-driven applications**, वर्कफ़्लो को स्वचालित करने, या सेवाओं को एकीकृत करने के लिए बहुपरकारी बनते हैं। ये लागत-कुशल हैं, क्योंकि आप आमतौर पर केवल उस समय के लिए भुगतान करते हैं जब आपका कोड चलता है।
> [!NOTE]
> ध्यान दें कि **Functions App Services का एक उपसमुच्चय हैं**, इसलिए, यहां चर्चा की गई कई सुविधाएँ Azure Apps (`webapp` in cli) के रूप में बनाए गए अनुप्रयोगों द्वारा भी उपयोग की जाएंगी।
### Different Plans
- **Flex Consumption Plan**: **dynamic, event-driven scaling** के साथ pay-as-you-go मूल्य निर्धारण प्रदान करता है, मांग के आधार पर function उदाहरणों को जोड़ने या हटाने की अनुमति देता है। यह **virtual networking** और **pre-provisioned instances** का समर्थन करता है ताकि ठंडी शुरुआत को कम किया जा सके, जिससे यह **variable workloads** के लिए उपयुक्त है जिन्हें कंटेनर समर्थन की आवश्यकता नहीं है।
- **Traditional Consumption Plan**: डिफ़ॉल्ट serverless विकल्प, जहां आप **केवल तब भुगतान करते हैं जब functions चलते हैं**। यह आने वाली घटनाओं के आधार पर स्वचालित रूप से स्केल करता है और इसमें **cold start optimizations** शामिल हैं, लेकिन यह कंटेनर तैनाती का समर्थन नहीं करता। स्वचालित स्केलिंग की आवश्यकता वाले **intermittent workloads** के लिए आदर्श।
- **Premium Plan**: **consistent performance** के लिए डिज़ाइन किया गया है, जिसमें ठंडी शुरुआत को समाप्त करने के लिए **prewarmed workers** होते हैं। यह **extended execution times, virtual networking** प्रदान करता है, और **custom Linux images** का समर्थन करता है, जिससे यह **mission-critical applications** के लिए आदर्श है जिन्हें उच्च प्रदर्शन और उन्नत सुविधाओं की आवश्यकता होती है।
- **Dedicated Plan**: समर्पित वर्चुअल मशीनों पर चलता है जिसमें **predictable billing** होता है और मैनुअल या स्वचालित स्केलिंग का समर्थन करता है। यह एक ही योजना पर कई ऐप चलाने की अनुमति देता है, **compute isolation** प्रदान करता है, और App Service Environments के माध्यम से **secure network access** सुनिश्चित करता है, जिससे यह **long-running applications** के लिए आदर्श है जिन्हें लगातार संसाधन आवंटन की आवश्यकता होती है।
- **Container Apps**: एक प्रबंधित वातावरण में **containerized function apps** को तैनात करने की अनुमति देता है, माइक्रोसर्विसेज और APIs के साथ। यह कस्टम पुस्तकालयों, विरासती ऐप माइग्रेशन, और **GPU processing** का समर्थन करता है, जिससे Kubernetes क्लस्टर प्रबंधन समाप्त हो जाता है। **event-driven, scalable containerized applications** के लिए आदर्श।
### **Storage Buckets**
जब एक नया Function App बनाया जाता है जो कंटेनर नहीं है (लेकिन चलाने के लिए कोड देता है), तो **कोड और अन्य Function से संबंधित डेटा एक Storage account में संग्रहीत किया जाएगा**। डिफ़ॉल्ट रूप से, वेब कंसोल प्रत्येक फ़ंक्शन के लिए कोड संग्रहीत करने के लिए एक नया बनाएगा।
इसके अलावा, बकेट के अंदर कोड को संशोधित करने पर (जिस विभिन्न प्रारूपों में इसे संग्रहीत किया जा सकता है), **ऐप का कोड नए कोड में संशोधित किया जाएगा और अगली बार जब Function को कॉल किया जाएगा तो इसे निष्पादित किया जाएगा**
> [!CAUTION]
> यह हमलावरों के दृष्टिकोण से बहुत दिलचस्प है क्योंकि **इस बकेट पर लिखने की पहुंच** एक हमलावर को **कोड से समझौता करने और Function App के अंदर प्रबंधित पहचान को बढ़ाने** की अनुमति देगी।
>
> इस पर अधिक जानकारी **privilege escalation section** में है।
यह भी संभव है कि **master और functions keys** को स्टोरेज अकाउंट में **`azure-webjobs-secrets`** कंटेनर में **`<app-name>`** फ़ोल्डर के अंदर JSON फ़ाइलों में संग्रहीत किया गया हो।
ध्यान दें कि Functions को एक दूरस्थ स्थान पर कोड संग्रहीत करने की अनुमति भी है, बस इसके लिए URL निर्दिष्ट करके।
### Networking
HTTP ट्रिगर का उपयोग करते हुए:
- यह संभव है कि **इंटरनेट से एक फ़ंक्शन तक पहुंच प्रदान करें** बिना किसी प्रमाणीकरण की आवश्यकता के या IAM आधारित पहुंच प्रदान करें। हालांकि, इस पहुंच को प्रतिबंधित करना भी संभव है।
- यह भी संभव है कि **एक आंतरिक नेटवर्क (VPC)** से एक Function App को **पहुंच दें या प्रतिबंधित करें**
> [!CAUTION]
> यह हमलावरों के दृष्टिकोण से बहुत दिलचस्प है क्योंकि यह संभव है कि **एक कमजोर Function से आंतरिक नेटवर्क पर पिवट करना**।
### **Function App Settings & Environment Variables**
यह एक ऐप के अंदर पर्यावरण चर को कॉन्फ़िगर करना संभव है, जिसमें संवेदनशील जानकारी हो सकती है। इसके अलावा, डिफ़ॉल्ट रूप से env चर **`AzureWebJobsStorage`** और **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`** (अन्य के बीच) बनाए जाते हैं। ये विशेष रूप से दिलचस्प हैं क्योंकि ये **ऐप्लिकेशन के डेटा को नियंत्रित करने के लिए स्टोरेज अकाउंट की कुंजी** को पूर्ण अनुमतियों के साथ शामिल करते हैं। इन सेटिंग्स की आवश्यकता भी होती है ताकि स्टोरेज अकाउंट से कोड निष्पादित किया जा सके।
ये env चर या कॉन्फ़िगरेशन पैरामीटर यह भी नियंत्रित करते हैं कि Function कोड को कैसे निष्पादित करता है, उदाहरण के लिए यदि **`WEBSITE_RUN_FROM_PACKAGE`** मौजूद है, तो यह उस URL को इंगित करेगा जहां ऐप्लिकेशन का कोड स्थित है।
### **Function Sandbox**
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`** था और यह **groups** का हिस्सा था: `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`
### **Managed Identities & Metadata**
जैसे कि [**VMs**](vms/index.html) में, Functions के पास **Managed Identities** के 2 प्रकार हो सकते हैं: System assigned और User assigned।
**system assigned** एक प्रबंधित पहचान होगी जिसे **केवल वही फ़ंक्शन** उपयोग कर सकेगा जिसे इसे सौंपा गया है, जबकि **user assigned** प्रबंधित पहचानें ऐसी प्रबंधित पहचान हैं जिन्हें **कोई अन्य Azure सेवा उपयोग कर सकेगी**
> [!NOTE]
> जैसे कि [**VMs**](vms/index.html) में, Functions के पास **1 system assigned** प्रबंधित पहचान और **कई user assigned** हो सकते हैं, इसलिए यदि आप फ़ंक्शन से समझौता करते हैं तो सभी को खोजने का प्रयास करना हमेशा महत्वपूर्ण होता है क्योंकि आप केवल एक Function से कई प्रबंधित पहचान को बढ़ा सकते हैं।
>
> यदि कोई system managed identity का उपयोग नहीं किया जाता है लेकिन एक या अधिक user managed identities एक फ़ंक्शन से जुड़ी होती हैं, तो डिफ़ॉल्ट रूप से आप कोई टोकन प्राप्त नहीं कर पाएंगे।
आप [**PEASS scripts**](https://github.com/peass-ng/PEASS-ng) का उपयोग करके मेटाडेटा एंडपॉइंट से डिफ़ॉल्ट प्रबंधित पहचान से टोकन प्राप्त कर सकते हैं। या आप उन्हें **मैन्युअल रूप से** प्राप्त कर सकते हैं जैसा कि समझाया गया है:
{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm
{{#endref}}
ध्यान दें कि आपको यह पता लगाने की आवश्यकता है कि **एक फ़ंक्शन के साथ जुड़ी सभी Managed Identities की जांच कैसे करें** क्योंकि यदि आप इसे निर्दिष्ट नहीं करते हैं, तो मेटाडेटा एंडपॉइंट **केवल डिफ़ॉल्ट एक का उपयोग करेगा** (अधिक जानकारी के लिए पिछले लिंक की जांच करें)।
## Access Keys
> [!NOTE]
> ध्यान दें कि उपयोगकर्ताओं को फ़ंक्शन को सक्रिय करने के लिए पहुंच देने के लिए RBAC अनुमतियाँ नहीं हैं। **फ़ंक्शन सक्रियण उस ट्रिगर पर निर्भर करता है** जो इसे बनाया गया था और यदि एक HTTP ट्रिगर चुना गया था, तो फ़ंक्शन को सक्रिय करने के लिए एक **access key** का उपयोग करना आवश्यक हो सकता है।
एक फ़ंक्शन के अंदर एक एंडपॉइंट बनाते समय **HTTP ट्रिगर** का उपयोग करते हुए, यह संभव है कि **फ़ंक्शन को सक्रिय करने के लिए आवश्यक access key authorization level** को निर्दिष्ट किया जाए। तीन विकल्प उपलब्ध हैं:
- **ANONYMOUS**: **सभी** फ़ंक्शन को URL के माध्यम से एक्सेस कर सकते हैं।
- **FUNCTION**: एंडपॉइंट केवल उन उपयोगकर्ताओं के लिए उपलब्ध है जो **function, host या master key** का उपयोग कर रहे हैं।
- **ADMIN**: एंडपॉइंट केवल उन उपयोगकर्ताओं के लिए उपलब्ध है जिनके पास **master key** है।
**कुंजी के प्रकार:**
- **Function Keys:** Function keys या तो डिफ़ॉल्ट या उपयोगकर्ता-परिभाषित हो सकते हैं और इन्हें विशेष रूप से **Function App के भीतर विशिष्ट फ़ंक्शन एंडपॉइंट्स** तक पहुंच प्रदान करने के लिए डिज़ाइन किया गया है जिससे एंडपॉइंट्स पर अधिक बारीक पहुंच मिलती है।
- **Host Keys:** Host keys, जो डिफ़ॉल्ट या उपयोगकर्ता-परिभाषित भी हो सकते हैं, **Function App के भीतर सभी फ़ंक्शन एंडपॉइंट्स तक FUNCTION access level** के साथ पहुंच प्रदान करते हैं।
- **Master Key:** मास्टर कुंजी (`_master`) एक प्रशासनिक कुंजी के रूप में कार्य करती है जो सभी फ़ंक्शन एंडपॉइंट्स (ADMIN access level शामिल) तक पहुंच प्रदान करती है। यह **कुंजी रद्द नहीं की जा सकती।**
- **System Keys:** System keys **विशिष्ट एक्सटेंशन द्वारा प्रबंधित** होते हैं और आंतरिक घटकों द्वारा उपयोग किए जाने वाले वेबहुक एंडपॉइंट्स तक पहुंच के लिए आवश्यक होते हैं। उदाहरणों में Event Grid ट्रिगर और Durable Functions शामिल हैं, जो अपने संबंधित APIs के साथ सुरक्षित रूप से बातचीत करने के लिए सिस्टम कुंजी का उपयोग करते हैं।
> [!TIP]
> एक कुंजी का उपयोग करके फ़ंक्शन API एंडपॉइंट तक पहुंचने का उदाहरण:
>
> `https://<function_uniq_name>.azurewebsites.net/api/<endpoint_name>?code=<access_key>`
### Basic Authentication
जैसे कि App Services में, Functions भी **SCM** और **FTP** से कनेक्ट करने के लिए बुनियादी प्रमाणीकरण का समर्थन करते हैं ताकि कोड को **Azure द्वारा प्रदान किए गए URL में उपयोगकर्ता नाम और पासवर्ड** का उपयोग करके तैनात किया जा सके। इसके बारे में अधिक जानकारी:
{{#ref}}
az-app-services.md
{{#endref}}
### Github Based Deployments
जब एक फ़ंक्शन एक Github repo से उत्पन्न होता है, तो Azure वेब कंसोल **एक विशिष्ट रिपॉजिटरी में स्वचालित रूप से एक Github Workflow बनाने** की अनुमति देता है ताकि जब भी इस रिपॉजिटरी को अपडेट किया जाए, फ़ंक्शन का कोड अपडेट हो जाए। वास्तव में, एक Python फ़ंक्शन के लिए Github Action yaml इस तरह दिखता है:
<details>
<summary>Github Action Yaml</summary>
```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>
इसके अलावा, एक **Managed Identity** भी बनाई जाती है ताकि रिपॉजिटरी से Github Action इसके साथ Azure में लॉगिन कर सके। यह **Managed Identity** पर एक Federated credential उत्पन्न करके किया जाता है, जो **Issuer** `https://token.actions.githubusercontent.com` और **Subject Identifier** `repo:<org-name>/<repo-name>:ref:refs/heads/<branch-name>` को अनुमति देता है।
> [!CAUTION]
> इसलिए, जो कोई भी उस रिपॉजिटरी को समझौता करेगा, वह फ़ंक्शन और इससे जुड़े Managed Identities को भी समझौता कर सकेगा।
### Container Based Deployments
सभी योजनाएँ कंटेनर को तैनात करने की अनुमति नहीं देती हैं, लेकिन जिनमें अनुमति है, उनके लिए कॉन्फ़िगरेशन में कंटेनर का URL होगा। API में **`linuxFxVersion`** सेटिंग कुछ इस तरह होगी: `DOCKER|mcr.microsoft.com/...`, जबकि वेब कंसोल में, कॉन्फ़िगरेशन **image settings** दिखाएगा।
इसके अलावा, **कोई स्रोत कोड स्टोरेज** खाते में संग्रहीत नहीं किया जाएगा जो फ़ंक्शन से संबंधित है क्योंकि इसकी आवश्यकता नहीं है।
## Enumeration
{{#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" }}
```bash
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 }}
## विशेषाधिकार वृद्धि
{{#ref}}
../az-privilege-escalation/az-functions-app-privesc.md
{{#endref}}
## संदर्भ
- [https://learn.microsoft.com/en-us/azure/azure-functions/functions-openapi-definition](https://learn.microsoft.com/en-us/azure/azure-functions/functions-openapi-definition)
{{#include ../../../banners/hacktricks-training.md}}