Files
NetSPI-MicroBurst/Misc/Get-AzAppConfiguration.ps1
Karl Fosaaen 2b482165b3 App Configuration Updates
Added key gathering for App Configuration resources and a function (Get-AzAppConfiguration) to dump App Configuration values.
2022-11-29 11:01:57 -08:00

106 lines
3.4 KiB
PowerShell

<#
File: Get-AzAppConfiguration.ps1
Author: Karl Fosaaen (@kfosaaen), NetSPI - 2022
Description: PowerShell function for dumping Azure App Configuration key values using the access keys.
Signing Code reused from - https://learn.microsoft.com/en-us/azure/azure-app-configuration/rest-api-authentication-hmac#powershell
#>
function Sign-Request(
[string] $hostname,
[string] $method, # GET, PUT, POST, DELETE
[string] $url, # path+query
[string] $body, # request body
[string] $credential, # access key id
[string] $secret # access key value (base64 encoded)
)
{
$verb = $method.ToUpperInvariant()
$utcNow = (Get-Date).ToUniversalTime().ToString("R", [Globalization.DateTimeFormatInfo]::InvariantInfo)
$contentHash = Compute-SHA256Hash $body
$signedHeaders = "x-ms-date;host;x-ms-content-sha256"; # Semicolon separated header names
$stringToSign = $verb + "`n" +
$url + "`n" +
$utcNow + ";" + $hostname + ";" + $contentHash # Semicolon separated signedHeaders values
$signature = Compute-HMACSHA256Hash $secret $stringToSign
# Return request headers
return @{
"x-ms-date" = $utcNow;
"x-ms-content-sha256" = $contentHash;
"Authorization" = "HMAC-SHA256 Credential=" + $credential + "&SignedHeaders=" + $signedHeaders + "&Signature=" + $signature
}
}
function Compute-SHA256Hash(
[string] $content
)
{
$sha256 = [System.Security.Cryptography.SHA256]::Create()
try {
return [Convert]::ToBase64String($sha256.ComputeHash([Text.Encoding]::ASCII.GetBytes($content)))
}
finally {
$sha256.Dispose()
}
}
function Compute-HMACSHA256Hash(
[string] $secret, # base64 encoded
[string] $content
)
{
$hmac = [System.Security.Cryptography.HMACSHA256]::new([Convert]::FromBase64String($secret))
try {
return [Convert]::ToBase64String($hmac.ComputeHash([Text.Encoding]::ASCII.GetBytes($content)))
}
finally {
$hmac.Dispose()
}
}
function Get-AzAppConfiguration{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,
HelpMessage="App Configuration Endpoint.")]
[string]$AppConfiguration = "",
[parameter(Mandatory=$true,
HelpMessage="Access Key ID.")]
[String]$Id = "",
[parameter(Mandatory=$true,
HelpMessage="Access Key Secret.")]
[String]$Secret = "",
[parameter(Mandatory=$false,
HelpMessage="Next Link for Pagination.")]
[String]$nextLink = $null
)
# nextLink is used for the pagination
if($nextLink){$uri = [System.Uri]::new(-join("https://$AppConfiguration.azconfig.io",$nextLink))}
else{$uri = [System.Uri]::new("https://$AppConfiguration.azconfig.io/kv?api-version=1.0")}
$headers = Sign-Request $uri.Authority GET $uri.PathAndQuery $null $Id $Secret
$itemsList = Invoke-WebRequest -Uri $uri -Method Get -Headers $headers
$configResults = [System.Text.Encoding]::ASCII.GetString($itemsList.Content) | ConvertFrom-Json
# Recurse if there are additional links to follow
if($configResults.'@nextLink'){Get-AzAppConfiguration -AppConfiguration $AppConfiguration -Id $Id -Secret $Secret -nextLink $configResults.'@nextLink'}
$configResults.items | select key,value,label,content_type,tags,locked,last_modified,etag
}