A PowerShell function to call Azure rest APIs using a VM Managed Identity to list available Storage Account access keys
Function get-MIStorageKeys{ | |
# Author: Karl Fosaaen (@kfosaaen), NetSPI - 2020 | |
# Description: PowerShell function for enumerating available storage account keys from a VM Managed Identity. | |
# Pipe to "Export-Csv -NoTypeInformation" for easier exporting | |
# Use the subID and ArmToken parameters to specify bearer tokens and subscriptions, handy for compromised bearer tokens from other services (CloudShell/AutomationAccounts) | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory=$false, | |
HelpMessage="Subscription ID")] | |
[string]$subID, | |
[Parameter(Mandatory=$false, | |
HelpMessage="ArmToken")] | |
[string]$ArmToken | |
) | |
#---------Get OAuth Token---------# | |
if ($ArmToken -eq ''){ | |
$response = 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 | |
$content = $response.Content | ConvertFrom-Json | |
$ArmToken = $content.access_token | |
} | |
#---------Query MetaData for SubscriptionID---------# | |
if ($subID -eq ''){ | |
$response2 = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/instance?api-version=2018-02-01' -Method GET -Headers @{Metadata="true"} -UseBasicParsing | |
$subID = ($response2.Content | ConvertFrom-Json).compute.subscriptionId | |
} | |
#---------Get List of Storage Accounts and RGs---------# | |
$responseKeys = Invoke-WebRequest -Uri (-join ('https://management.azure.com/subscriptions/',$subID,'/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01')) -Method GET -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing | |
$storageACCTS = ($responseKeys.Content | ConvertFrom-Json).value | |
# Create data table to house results | |
$TempTbl = New-Object System.Data.DataTable | |
$TempTbl.Columns.Add("StorageAccount") | Out-Null | |
$TempTbl.Columns.Add("Key1") | Out-Null | |
$TempTbl.Columns.Add("Key2") | Out-Null | |
$TempTbl.Columns.Add("Key1-Permissions") | Out-Null | |
$TempTbl.Columns.Add("Key2-Permissions") | Out-Null | |
#---------Request access keys for all storage accounts---------# | |
$storageACCTS | ForEach-Object { | |
# Do some split magic on the list of Storage accounts | |
$accountName = $_.name | |
$split1 = ($_.id -split "resourceGroups/") | |
$split2 = ($split1 -Split "/") | |
$SARG = $split2[4] | |
#https://docs.microsoft.com/en-us/rest/api/storagerp/storageaccounts/listkeys# | |
$responseKeys = (Invoke-WebRequest -Uri (-join ('https://management.azure.com/subscriptions/',$subID,'/resourceGroups/',$SARG,'/providers/Microsoft.Storage/storageAccounts/',$accountName,'/listKeys?api-version=2019-06-01')) -Method POST -Headers @{ Authorization ="Bearer $ArmToken"} -UseBasicParsing).content | |
$keylist = ($responseKeys| ConvertFrom-Json).keys | |
# Write the keys to the table | |
$TempTbl.Rows.Add($accountName, $keylist[0].value, $keylist[1].value, $keylist[0].permissions, $keylist[1].permissions) | Out-Null | |
} | |
Write-Output $TempTbl | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment