Az - Automation Accounts

Reading time: 11 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

Basic Information

Azure Automation Accounts는 Microsoft Azure의 클라우드 기반 서비스로, Azure 및 온프레미스 환경에서 리소스 관리, 구성 및 업데이트와 같은 작업을 자동화하는 데 도움을 줍니다. 이들은 Runbooks(실행되는 자동화 스크립트), 일정, 및 하이브리드 작업자 그룹을 제공하여 자동화 작업을 실행하고, 코드로서의 인프라(IaC) 및 프로세스 자동화를 통해 클라우드 리소스 관리의 효율성과 일관성을 향상시킵니다.

Settings

  • Credentials: 비밀번호는 자동화 계정 내의 runbook에서만 접근할 수 있으며, 사용자 이름과 비밀번호를 안전하게 저장하는 데 사용됩니다.
  • Variables: runbooks에서 사용할 수 있는 구성 데이터를 저장하는 데 사용됩니다. 여기에는 API 키와 같은 민감한 정보도 포함될 수 있습니다. 변수가 암호화되어 저장되면, 자동화 계정 내의 runbook에서만 사용할 수 있습니다.
  • Certificates: runbooks에서 사용할 수 있는 인증서를 저장하는 데 사용됩니다.
  • Connections: 외부 서비스에 대한 연결 정보를 저장하는 데 사용됩니다. 여기에는 민감한 정보가 포함될 수 있습니다.
  • Network Access: 공개 또는 비공개로 설정할 수 있습니다.

Runbooks & Jobs

Azure Automation의 Runbook은 클라우드 환경 내에서 작업을 자동으로 수행하는 스크립트입니다. Runbooks는 PowerShell, Python 또는 그래픽 편집기에서 작성할 수 있습니다. 이들은 VM 관리, 패치 적용 또는 준수 검사와 같은 관리 작업을 자동화하는 데 도움을 줍니다.

Runbooks 내의 코드민감한 정보(예: 자격 증명)를 포함할 수 있습니다.

Job은 Runbook 실행의 인스턴스입니다. Runbook을 실행하면 해당 실행을 추적하기 위해 Job이 생성됩니다. 각 job에는 다음이 포함됩니다:

  • Status: 대기 중, 실행 중, 완료, 실패, 일시 중지.
  • Output: Runbook 실행의 결과.
  • Start and End Time: 작업이 시작되고 완료된 시간.

Job은 Runbook 실행의 출력을 포함합니다. jobs읽을 수 있다면, run출력(잠재적 민감한 정보)을 포함하고 있으므로 읽어보세요.

Schedules & Webhooks

Runbook을 실행하는 주요 방법은 3가지입니다:

  • Schedules: 특정 시간 또는 간격에 Runbooks를 트리거하는 데 사용됩니다.
  • Webhooks: 외부 서비스에서 Runbooks를 트리거하는 데 사용할 수 있는 HTTP 엔드포인트입니다. 웹후크 URL은 생성 후 보이지 않습니다.
  • Manual Trigger: Azure Portal 및 CLI에서 Runbook을 수동으로 트리거할 수 있습니다.

Source Control

Runbooks를 **Github, Azure Devops (Git) 및 Azure Devops (TFVC)**에서 가져올 수 있습니다. 리포지토리의 Runbooks를 Azure Automation 계정에 게시하도록 지정할 수 있으며, 리포지토리의 변경 사항을 Azure Automation 계정에 동기화하도록 지정할 수도 있습니다.

동기화가 활성화되면, Github 리포지토리에서 웹후크가 생성되어 푸시 이벤트가 발생할 때마다 동기화를 트리거합니다. 웹후크 URL의 예: https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=DRjQyFiOrUtz%2fw7o23XbDpOlTe1%2bUqPQm4pQH2WBfJg%3d

이 웹후크는 Github 리포에 연결된 runbooks에서 웹후크를 나열할 때 보이지 않습니다. 또한, 생성된 후에는 소스 제어의 리포 URL을 변경할 수 없습니다.

구성된 소스 제어가 작동하려면, Azure Automation AccountContributor 역할을 가진 관리형 ID(시스템 또는 사용자)가 필요합니다. 또한, Automation Account에 사용자 관리형 ID를 할당하려면, 변수 **AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID**에 사용자 MI의 클라이언트 ID를 지정해야 합니다.

Runtime Environments

Runbook을 생성할 때 런타임 환경을 선택할 수 있습니다. 기본적으로 다음 런타임 환경이 제공됩니다:

  • Powershell 5.1
  • Powershell 7.1
  • PowerShell 7.2
  • Python 3.10
  • Python 3.8
  • Python 2.7

그러나 이러한 환경 중 하나를 기반으로 자신의 환경을 생성할 수도 있습니다. Python의 경우, 사용할 환경에 .whl 패키지를 업로드할 수 있습니다. PowerShell의 경우, 런타임에 포함할 모듈이 있는 .zip 패키지를 업로드할 수 있습니다.

Hybrid Worker Groups

Azure Automation에서 Runbooks의 기본 실행 환경은 Azure Sandbox로, Azure에서 관리하는 클라우드 기반 플랫폼으로 Azure 리소스와 관련된 작업에 적합합니다. 그러나 이 샌드박스에는 온프레미스 리소스에 대한 제한된 접근 및 실행 시간과 리소스 사용에 대한 제약과 같은 제한이 있습니다. 이러한 제한을 극복하기 위해 하이브리드 작업자 그룹이 사용됩니다. 하이브리드 작업자 그룹은 자신의 머신에 설치된 하나 이상의 하이브리드 Runbook Worker로 구성되며, 온프레미스, 다른 클라우드 환경 또는 Azure VM에서 실행될 수 있습니다. 이 설정을 통해 Runbooks는 이러한 머신에서 직접 실행되어 로컬 리소스에 직접 접근하고, 더 긴 시간과 더 많은 리소스를 소모하는 작업을 실행할 수 있으며, Azure의 즉각적인 범위를 넘어서는 환경과 상호작용할 수 있는 유연성을 제공합니다.

하이브리드 작업자 그룹을 생성할 때 사용할 자격 증명을 지정해야 합니다. 두 가지 옵션이 있습니다:

  • 기본 자격 증명: 자격 증명을 제공할 필요가 없으며, Runbooks는 System으로 VM 내에서 실행됩니다.
  • 특정 자격 증명: 자동화 계정 내의 자격 증명 객체의 이름을 제공해야 하며, 이는 VM 내에서 Runbooks를 실행하는 데 사용됩니다. 따라서 이 경우, VM에 대한 유효한 자격 증명을 훔칠 수 있습니다.

따라서 하이브리드 작업자에서 Runbook을 실행하도록 선택할 수 있다면, System으로 외부 머신 내에서 임의의 명령을 실행하게 됩니다(좋은 피벗 기술).

또한, 하이브리드 작업자가 Azure에서 다른 관리형 ID와 함께 실행되고 있다면, Runbook은 Runbook의 관리형 ID와 VM의 모든 관리형 ID에 접근할 수 있습니다.

tip

메타데이터 서비스의 URL은 http://169.254.169.254로, 자동화 계정의 관리형 ID 토큰을 가져오는 서비스의 URL(IDENTITY_ENDPOINT)과 다릅니다.

State Configuration (SC)

warning

문서에 명시된 바와 같이, Azure Automation State Configuration은 2027년 9월 30일에 종료되며 Azure Machine Configuration으로 대체됩니다.

Automation Accounts는 **State Configuration (SC)**도 지원하며, 이는 VM의 상태를 구성하고 유지하는 데 도움을 주는 기능입니다. WindowsLinux 머신에 DSC 구성을 생성하고 적용할 수 있습니다.

공격자의 관점에서 이는 구성된 모든 VM에서 임의의 PS 코드를 실행할 수 있게 해주어, 이러한 VM의 관리형 ID로 권한 상승을 가능하게 하며, 잠재적으로 새로운 네트워크로 피벗할 수 있게 합니다... 또한, 구성에는 민감한 정보가 포함될 수 있습니다.

Enumeration

bash
# List Automation Accounts
az automation account list --output table

# Get Automation Account details
# Check the network access in `privateEndpointConnections` and `publicNetworkAccess`
# Check the managed identities in `identity`
az automation account show --name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get keys of automation account
## These are used for the DSC
az automation account list-keys --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get schedules of automation account
az automation schedule list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get connections of automation account
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/connections?api-version=2023-11-01"

# Get connection details
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/connections/<connection-name>?api-version=2023-11-01"

# Get credentials of automation account
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/credentials?api-version=2023-11-01"

# Get credential details
## Note that you will only be able to access the password from inside a Runbook
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/credentials/<credential-name>?api-version=2023-11-01"

# Get certificates of automation account
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/certificates?api-version=2023-11-01"

# Get certificate details
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/certificates/<certificate-name>?api-version=2023-11-01"

# Get variables of automation account
## It's possible to get the value of unencrypted variables but not the encrypted ones
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables?api-version=2023-11-01"

# Get variable details
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/variables/<variable-name>?api-version=2023-11-01"

# Get runbooks of an automation account
az automation runbook list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get runbook details
az automation runbook show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <RUNBOOK-NAME>

# Get runbook content
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/runbooks/<runbook-name>/content?api-version=2023-11-01"

# Get jobs of an automation account
az automation job list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get job details
az automation job show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <JOB-NAME>

# Get job output
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"

# Get the Runbook content when the job was executed
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>/runbookContent?api-version=2023-11-01"

# Get webhooks inside an automation account
## It's possible to see to which runbook it belongs in the given data
## For security reasons it's not possible to see the URL of the webhook after creating it, here is a URL example: https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=dOdnxk6z7ugAxiuyUMKgPuDMav2Jw5EJediMdiN4jLo%3d
## Generating a webhook can be useful from a persistence perspective
az rest --method GET \
--url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/webhooks?api-version=2018-06-30"

# Get the source control setting of an automation account (if any)
## inside the output it's possible to see if the autoSync is enabled, if the publishRunbook is enabled and the repo URL
az automation source-control list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get custom runtime environments
## Check in defaultPackages for custom ones, by default Python envs won't have anything here and PS1 envs will have "az" and "azure cli"
az automation runtime-environment list \
--resource-group <res-group>> \
--automation-account-name <account-name> \
--query "[?!(starts_with(description, 'System-generated'))]"

# Get State Configurations (SC) of an automation account
az automation dsc configuration list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get State Configuration details
az automation dsc configuration show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <DSC-CONFIG-NAME>

# Get State Configuration content
az automation dsc configuration show-content --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <DSC-CONFIG-NAME>

# Get hybrid worker groups for an automation account
az automation hrwg list --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME>

# Get hybrid worker group details
az automation hrwg show --automation-account-name <AUTOMATION-ACCOUNT> --resource-group <RG-NAME> --name <HYBRID-WORKER-GROUP>

# Get more details about a hybrid worker group (like VMs inside it)
az rest --method GET --url "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<res-group>>/providers/Microsoft.Automation/automationAccounts/<automation-account-name>/hybridRunbookWorkerGroups/<hybrid-worker-group-name>/hybridRunbookWorkers?&api-version=2021-06-22"
bash
# Check user right for automation
az extension add --upgrade -n automation
az automation account list # if it doesn't return anything the user is not a part of an Automation group

# Gets Azure Automation accounts in a resource group
Get-AzAutomationAccount

# List & get DSC configs
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration
Get-AzAutomationAccount | Get-AzAutomationDscConfiguration | where {$_.name -match '<name>'} | Export-AzAutomationDscConfiguration -OutputFolder . -Debug
## Automation Accounts named SecurityBaselineConfigurationWS... are there by default (not interesting)

# List & get Run books code
Get-AzAutomationAccount | Get-AzAutomationRunbook
Get-AzAutomationAccount | Get-AzAutomationRunbook | Export-AzAutomationRunbook -OutputFolder /tmp

# List credentials & variables & others
Get-AzAutomationAccount | Get-AzAutomationCredential
Get-AzAutomationAccount | Get-AzAutomationVariable
Get-AzAutomationAccount | Get-AzAutomationConnection
Get-AzAutomationAccount | Get-AzAutomationCertificate
Get-AzAutomationAccount | Get-AzAutomationSchedule
Get-AzAutomationAccount | Get-AzAutomationModule
Get-AzAutomationAccount | Get-AzAutomationPython3Package
## Exfiltrate credentials & variables and the other info loading them in a Runbook and printing them

# List hybrid workers
Get-AzAutomationHybridWorkerGroup -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME>

권한 상승 및 포스트 익스플로잇

Az - Automation Accounts Privesc

지속성

Az - Automation Accounts Persistence

참조

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기