18 KiB
Az - Function Apps
{{#include ../../../banners/hacktricks-training.md}}
基本情報
Azure Function Apps は サーバーレスコンピューティングサービス であり、基盤となるインフラストラクチャを管理することなく、関数と呼ばれる小さなコードの断片を実行することを可能にします。これらは、HTTPリクエスト、タイマー、またはBlob StorageやEvent Hubsなどの他のAzureサービスからのイベントに応じてコードを実行するように設計されています。Function AppsはC#、Python、JavaScript、Javaなど複数のプログラミング言語をサポートしており、イベント駆動型アプリケーションの構築、ワークフローの自動化、サービスの統合に適しています。通常、コードが実行されるときに使用されたコンピューティング時間に対してのみ支払うため、コスト効率が高いです。
Note
FunctionsはApp Servicesのサブセットであるため、ここで説明される多くの機能はAzure Apps(cliでは
webapp)として作成されたアプリケーションでも使用されます。
異なるプラン
- Flex Consumption Plan: 動的でイベント駆動型のスケーリングを提供し、需要に応じて関数インスタンスを追加または削除する従量課金制です。仮想ネットワーキングと事前プロビジョニングされたインスタンスをサポートし、コールドスタートを減少させ、コンテナサポートを必要としない変動するワークロードに適しています。
- Traditional Consumption Plan: デフォルトのサーバーレスオプションで、関数が実行されるときのみコンピューティングリソースに対して支払います。受信イベントに基づいて自動的にスケールし、コールドスタートの最適化が含まれていますが、コンテナデプロイメントはサポートしていません。自動スケーリングを必要とする断続的なワークロードに最適です。
- Premium Plan: 一貫したパフォーマンスを提供するように設計されており、コールドスタートを排除するための事前ウォームされたワーカーを備えています。拡張実行時間、仮想ネットワーキングを提供し、カスタムLinuxイメージをサポートしており、高パフォーマンスと高度な機能を必要とするミッションクリティカルなアプリケーションに最適です。
- Dedicated Plan: 専用の仮想マシン上で実行され、予測可能な請求を提供し、手動または自動スケーリングをサポートします。同じプランで複数のアプリを実行でき、コンピューティングの隔離を提供し、App Service Environmentsを介して安全なネットワークアクセスを確保し、一貫したリソース割り当てを必要とする長時間実行されるアプリケーションに最適です。
- Container Apps: コンテナ化された関数アプリを管理された環境でデプロイすることを可能にし、マイクロサービスやAPIと共に使用できます。カスタムライブラリ、レガシーアプリの移行、GPU処理をサポートし、Kubernetesクラスターの管理を排除します。イベント駆動型でスケーラブルなコンテナ化されたアプリケーションに最適です。
ストレージバケット
新しいFunction Appをコンテナ化せずに作成する場合(実行するコードを提供する場合)、コードおよびその他のFunction関連データはストレージアカウントに保存されます。デフォルトでは、Webコンソールはコードを保存するために関数ごとに新しいものを作成します。
さらに、バケット内のコードを変更すると(保存されるさまざまな形式で)、アプリのコードは新しいものに変更され、次回Functionが呼び出されると実行されます。
Caution
これは攻撃者の視点から非常に興味深いものであり、このバケットに対する書き込みアクセスがあれば、攻撃者はコードを妥協し、Function App内の管理されたIDの権限を昇格させることができます。
これについては権限昇格セクションで詳しく説明します。
ストレージアカウント内のコンテナ azure-webjobs-secrets に、フォルダ <app-name> 内のJSONファイルに保存されたマスターキーと関数キーを見つけることも可能です。
Functionsは、リモートロケーションにコードを保存することも可能で、URLを指定するだけで済みます。
ネットワーキング
HTTPトリガーを使用する場合:
- インターネット全体から関数へのアクセスを提供することが可能で、認証を必要としないか、IAMベースのアクセスを提供することができます。ただし、このアクセスを制限することも可能です。
- 内部ネットワーク(VPC)からFunction Appへのアクセスを提供または制限することも可能です。
Caution
これは攻撃者の視点から非常に興味深いものであり、インターネットに公開された脆弱なFunctionから内部ネットワークにピボットすることが可能かもしれません。
Function Appの設定と環境変数
アプリ内で環境変数を構成することが可能で、これには機密情報が含まれる可能性があります。さらに、デフォルトで環境変数 AzureWebJobsStorage と WEBSITE_CONTENTAZUREFILECONNECTIONSTRING(他にもいくつか)が作成されます。これらは特に興味深いもので、アプリケーションのデータを含むストレージアカウントを完全に制御するためのアカウントキーを含んでいます。これらの設定は、ストレージアカウントからコードを実行するためにも必要です。
これらの環境変数や構成パラメータは、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 で、グループには 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 が含まれていました。
管理されたIDとメタデータ
VMsと同様に、Functionsは2種類の管理されたIDを持つことができます:システム割り当てとユーザー割り当て。
システム割り当てのものは、そのIDが割り当てられた関数のみが使用できる管理されたIDであり、ユーザー割り当ての管理されたIDは、他のAzureサービスが使用できる管理されたIDです。
Note
VMsと同様に、Functionsは1つのシステム割り当ての管理されたIDと複数のユーザー割り当ての管理されたIDを持つことができるため、関数を妥協した場合は、すべての管理されたIDを見つけることが常に重要です。1つのFunctionから複数の管理されたIDに権限を昇格させることができるかもしれません。
システム管理されたIDが使用されていないが、1つ以上のユーザー管理されたIDが関数に添付されている場合、デフォルトではトークンを取得することはできません。
PEASSスクリプトを使用して、メタデータエンドポイントからデフォルトの管理されたIDのトークンを取得することが可能です。また、以下のように手動で取得することもできます:
{% embed url="https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#azure-vm" %}
関数に添付されたすべての管理されたIDを確認する方法を見つける必要があることに注意してください。指定しない場合、メタデータエンドポイントはデフォルトのもののみを使用します(詳細については前のリンクを確認してください)。
アクセスキー
Note
ユーザーが関数を呼び出すためのアクセスを与えるRBAC権限は存在しないことに注意してください。関数の呼び出しは、作成時に選択されたトリガーに依存します。HTTPトリガーが選択された場合、アクセスキーを使用する必要があるかもしれません。
HTTPトリガーを使用して関数内にエンドポイントを作成する際、関数をトリガーするために必要なアクセスキーの認証レベルを指定することが可能です。3つのオプションがあります:
- ANONYMOUS: 誰でもURLを通じて関数にアクセスできます。
- FUNCTION: エンドポイントは関数、ホスト、またはマスターキーを使用するユーザーのみがアクセスできます。
- ADMIN: エンドポイントはマスターキーを持つユーザーのみがアクセスできます。
キーの種類:
- 関数キー: 関数キーはデフォルトまたはユーザー定義のいずれかであり、Function App内の特定の関数エンドポイントへのアクセスを独占的に付与するように設計されています。
- ホストキー: ホストキーもデフォルトまたはユーザー定義のいずれかであり、FUNCTIONアクセスレベルを持つFunction App内のすべての関数エンドポイントへのアクセスを提供します。
- マスターキー: マスターキー(
_master)は、すべての関数エンドポイントへのアクセスを含む管理キーであり、権限が昇格されます。このキーは取り消すことができません。 - システムキー: システムキーは特定の拡張機能によって管理され、内部コンポーネントによって使用されるWebhookエンドポイントにアクセスするために必要です。例としては、Event GridトリガーやDurable Functionsがあり、システムキーを使用してそれぞれのAPIと安全に対話します。
Tip
キーを使用して関数APIエンドポイントにアクセスする例:
https://<function_uniq_name>.azurewebsites.net/api/<endpoint_name>?code=<access_key>
基本認証
App Servicesと同様に、FunctionsもSCMおよびFTPに接続してコードをデプロイするための基本認証をサポートしています。これは、Azureが提供するユーザー名とパスワードを含むURLを使用します。詳細については以下を参照してください:
{{#ref}} az-app-services.md {{#endref}}
Githubベースのデプロイメント
関数がGithubリポジトリから生成されると、Azure Webコンソールは特定のリポジトリにGithubワークフローを自動的に作成することを許可します。これにより、このリポジトリが更新されるたびに関数のコードが更新されます。実際、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**上に連邦資格情報を生成することによって行われ、**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/...`、一方、ウェブコンソールでは、構成に**image settings**が表示されます。
さらに、**ソースコードは関数に関連するストレージ**アカウントに保存されません。必要ないためです。
## 列挙
{{#tabs }}
{{#tab name="az cli" }}
```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"
{{#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}}