28 KiB
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 (
webappin 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 में, Functions के पास Managed Identities के 2 प्रकार हो सकते हैं: System assigned और User assigned।
system assigned एक प्रबंधित पहचान होगी जिसे केवल वही फ़ंक्शन उपयोग कर सकेगा जिसे इसे सौंपा गया है, जबकि user assigned प्रबंधित पहचानें ऐसी प्रबंधित पहचान हैं जिन्हें कोई अन्य Azure सेवा उपयोग कर सकेगी।
Note
जैसे कि VMs में, Functions के पास 1 system assigned प्रबंधित पहचान और कई user assigned हो सकते हैं, इसलिए यदि आप फ़ंक्शन से समझौता करते हैं तो सभी को खोजने का प्रयास करना हमेशा महत्वपूर्ण होता है क्योंकि आप केवल एक Function से कई प्रबंधित पहचान को बढ़ा सकते हैं।
यदि कोई system managed identity का उपयोग नहीं किया जाता है लेकिन एक या अधिक user managed identities एक फ़ंक्शन से जुड़ी होती हैं, तो डिफ़ॉल्ट रूप से आप कोई टोकन प्राप्त नहीं कर पाएंगे।
आप PEASS scripts का उपयोग करके मेटाडेटा एंडपॉइंट से डिफ़ॉल्ट प्रबंधित पहचान से टोकन प्राप्त कर सकते हैं। या आप उन्हें मैन्युअल रूप से प्राप्त कर सकते हैं जैसा कि समझाया गया है:
{{#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 इस तरह दिखता है:
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>
इसके अलावा, एक **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" }}
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}}
संदर्भ
{{#include ../../../banners/hacktricks-training.md}}