mirror of
https://dev.azure.com/effectory/Survey%20Software/_git/Cloud%20Engineering
synced 2026-02-28 03:02:19 +01:00
First version of subdomain takeover runbook
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
function Get-BlobEffectoryDomainResources {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves the stored domain resources list
|
||||
.DESCRIPTION
|
||||
Retrieves the newest domain resources list from the CSV in Azure storage.
|
||||
.PARAMETER connectionString
|
||||
Connection string of the storage account to retrieve from.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $connectionString
|
||||
)
|
||||
|
||||
[EffectoryDomainNameCheck[]] $loadedResources = @()
|
||||
$context = New-AzStorageContext -ConnectionString $connectionString
|
||||
|
||||
$blob = Get-AzStorageBlob -Container "dangling-dns" -Context $context | Sort-Object -Property Name | Select-Object -Last 1
|
||||
if ($null -ne $blob) {
|
||||
Get-AzStorageBlobContent -Context $context -CloudBlob $blob.ICloudBlob -Destination "$Env:temp/$($blob.Name).history.csv" -Force >$null
|
||||
$loadedResources = Import-CSV "$Env:temp/$($blob.Name).history.csv"
|
||||
Remove-Item -Path "$Env:temp/$($blob.Name).history.csv"
|
||||
}
|
||||
|
||||
$loadedResources
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# $context = New-AzStorageContext -ConnectionString "DefaultEndpointsProtocol=https;AccountName=runbookseffectory;AccountKey=PIyewEcppMcm8imMhpUUOgrOUbWyFPK0o8PfdwPnEiNvEQqUvTDzjuV4W18z2sBuRzspGs5pV/Fz96umfePviw==;EndpointSuffix=core.windows.net"
|
||||
# Get-AzTrafficManagerProfile | Export-Csv "$Env:temp/test4.csv"
|
||||
# Set-AzStorageBlobContent -Context $context -Container "dangling-dns" -File "$Env:temp/test4.csv" -Blob "test2.csv" -Force >$null
|
||||
|
||||
# Get-AzStorageBlobContent -Context $context -Container "dangling-dns" -Blob "test2.csv" -Destination "$Env:temp/test3.csv" -Force
|
||||
# $foo = Import-CSV "$Env:temp/test3.csv"
|
||||
|
||||
# $foo
|
||||
@@ -1,134 +0,0 @@
|
||||
#Requires -Modules Az.Accounts,Az.Websites,Az.FrontDoor,Az.Storage,Az.Cdn,Az.Network,Az.TrafficManager,Az.ContainerInstance
|
||||
function Get-EffectoryDomainResources {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Find resources in Azure that have DNS records
|
||||
.DESCRIPTION
|
||||
Gets all resources that have hostnames.
|
||||
.PARAMETER subscriptionId
|
||||
Optional Subscription Id to set the context to. Otherwise uses the current context.
|
||||
#>
|
||||
param(
|
||||
[Parameter()]
|
||||
[string] $subscriptionId
|
||||
)
|
||||
|
||||
# Initialize
|
||||
[EffectoryDomainNameCheck[]]$result = @()
|
||||
[string]$effectoryDomainPattern = "*.effectory.com"
|
||||
|
||||
# Get subscription info
|
||||
[Microsoft.Azure.Commands.Profile.Models.Core.PSAzureContext]$currentContext = $null
|
||||
if (![string]::IsNullOrWhitespace($subscriptionId)) {
|
||||
$currentContext = Set-AzContext -SubscriptionId $subscriptionId
|
||||
}
|
||||
else {
|
||||
$currentContext = Get-AzContext
|
||||
$subscriptionId = $currentContext.Subscription
|
||||
}
|
||||
|
||||
Write-Host "Processing subscription $($currentContext.Name)"
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking WebApps and WebApp Slots for subscription $($currentContext.Name)"
|
||||
# $webApps = Get-AzWebApp
|
||||
# [int]$webAppCounter = 0
|
||||
# [int]$webAppSlotCounter = 0
|
||||
|
||||
# if ($null -ne $webApps) {
|
||||
# # check webapps
|
||||
# $itemsWebApps = CheckWebApps -subscription $currentContext -webApps $webApps -effectoryDomainPattern $effectoryDomainPattern
|
||||
# $webAppCounter += $itemsWebApps.Count
|
||||
# $result += $itemsWebApps
|
||||
|
||||
# # check webapp slots
|
||||
# foreach ($webApp in $webApps) {
|
||||
# $slot = Get-AzWebAppSlot -WebApp $webApp
|
||||
# if ($null -ne $slot) {
|
||||
# $itemsWebAppSlots = CheckWebApps -subscription $currentContext -webApps $slot -effectoryDomainPattern $effectoryDomainPattern
|
||||
# $webAppSlotCounter += $itemsWebAppSlots.Count
|
||||
# $result += $itemsWebAppSlots
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# Write-Host "Found $($webAppCounter) WebApps and $($webAppSlotsCounter) WebApp Slots for subscription $($currentContext.Name)"
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
Write-Host "Checking FrontDoor Endpoints for subscription $($currentContext.Name)"
|
||||
$frontDoors = Get-AzFrontDoor
|
||||
[int]$frontDoorEndPointCounter = 0
|
||||
|
||||
if ($null -ne $frontDoors) {
|
||||
$itemsFrontDoors = CheckFrontDoorEndPoints -subscription $currentContext -frontDoors $frontDoors -effectoryDomainPattern $effectoryDomainPattern
|
||||
$frontDoorEndPointCounter += $itemsFrontDoors.Count
|
||||
$result += $itemsFrontDoors
|
||||
}
|
||||
Write-Host "Found $($frontDoorEndPointCounter) FrontDoor Endpoints for subscription $($currentContext.Name)"
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
Write-Host "Checking Storage Accounts for subscription $($currentContext.Name)"
|
||||
$storageAccounts = Get-AzStorageAccount | Where-Object { $_.CustomDomain.Name -like $effectoryDomainPattern } # storage accounts
|
||||
[int]$storageCounter = 0
|
||||
|
||||
if ($null -ne $storageAccounts) {
|
||||
$itemsStorage = CheckStorageAccounts -subscription $currentContext -storageAccounts $storageAccounts -effectoryDomainPattern $effectoryDomainPattern
|
||||
$storageCounter += $itemsStorage.Count
|
||||
$result += $itemsStorage
|
||||
}
|
||||
Write-Host "Found $($storageCounter) Storage Accounts for subscription $($currentContext.Name)"
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking Cdn Endpoints for subscription $($currentContext.Name)"
|
||||
# $cdnProfiles = Get-AzCdnProfile
|
||||
# [int]$cdnCounter = 0
|
||||
|
||||
# if ($null -ne $cdnProfiles) {
|
||||
# $itemsCdn = CheckCdnEndpoints -subscription $currentContext -cdnProfiles $cdnProfiles -effectoryDomainPattern $effectoryDomainPattern
|
||||
# $cdnCounter += $itemsCdn.Count
|
||||
# $result += $itemsCdn
|
||||
# }
|
||||
# Write-Host "Found $($cdnCounter) Cdn Endpoints for subscription $($currentContext.Name)"
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking public IP addresses for subscription $($currentContext.Name)"
|
||||
# $ipAddresses = Get-AzPublicIpAddress | Where-Object DnsSettings -ne $null | Where-Object { $_.DnsSettings.DomainNameLabel -ne "" }
|
||||
# [int]$ipCounter = 0
|
||||
|
||||
# if ($null -ne $ipAddresses) {
|
||||
# $itemsIpAddresses = CheckIpAddresses -subscription $currentContext -ipAddresses $ipAddresses -effectoryDomainPattern $effectoryDomainPattern
|
||||
# $ipCounter += $itemsIpAddresses.Count
|
||||
# $result += $itemsIpAddresses
|
||||
# }
|
||||
# Write-Host "Found $($ipCounter) public IP addresses for subscription $($currentContext.Name)"
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking Traffic Managers for subscription $($currentContext.Name)"
|
||||
# $trafficManagers = Get-AzTrafficManagerProfile
|
||||
# [int]$trafficManagerCounter = 0
|
||||
|
||||
# if ($null -ne $trafficManagers) {
|
||||
# $itemsTrafficManagers = CheckTrafficManagers -subscription $currentContext -trafficManagers $trafficManagers -effectoryDomainPattern $effectoryDomainPattern
|
||||
# $trafficManagerCounter += $itemsTrafficManagers.Count
|
||||
# $result += $itemsTrafficManagers
|
||||
# }
|
||||
# Write-Host "Found $($trafficManagerCounter) Traffic Managers for subscription $($currentContext.Name)"
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking Container groups for subscription $($currentContext.Name)"
|
||||
# $containerInstances = Get-AzContainerGroup
|
||||
|
||||
# if ($null -ne $containerInstances) {
|
||||
# throw "Container groups are not implemented yet."
|
||||
# }
|
||||
|
||||
# # ------------------------------------------------------------------------------------------------------------------
|
||||
# Write-Host "Checking API Management for subscription $($currentContext.Name)"
|
||||
# $apiManagementServices = Get-AzApiManagement
|
||||
|
||||
# if ($null -ne $apiManagementServices) {
|
||||
# throw "API Management services are not implemented yet."
|
||||
# }
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
$result
|
||||
}
|
||||
@@ -17,47 +17,22 @@ function Set-BlobEffectoryDomainResources {
|
||||
[string] $connectionString
|
||||
)
|
||||
|
||||
[string] $fileName = "$((Get-Date).ToString("yyyy-MM-dd hh-mm")) - resources.csv"
|
||||
[string] $fileName = "$((Get-Date).ToString("yyyy-MM-dd HH-mm-ss")) - resources.csv"
|
||||
Write-Host "Storing resources to $($fileName)"
|
||||
|
||||
$context = New-AzStorageContext -ConnectionString $connectionString
|
||||
|
||||
# move to history
|
||||
$blobs = Get-AzStorageBlob -Container "dangling-dns" -Context $context
|
||||
$blobs = Get-AzStorageBlob -Container "dangling-dns" -Context $context
|
||||
if ($null -ne $blobs) {
|
||||
foreach ($blob in $blobs) {
|
||||
Start-AzStorageBlobCopy -CloudBlob $blob.ICloudBlob -DestContainer "dangling-dns-history" -DestBlob $blob.Name -Context $context
|
||||
Remove-AzStorageBlob -Container "dangling-dns" -Blob $blob.Name -Context $context
|
||||
Start-AzStorageBlobCopy -CloudBlob $blob.ICloudBlob -DestContainer "dangling-dns-history" -DestBlob $blob.Name -Context $context -Force >$null
|
||||
Remove-AzStorageBlob -Container "dangling-dns" -Blob $blob.Name -Context $context -Force >$null
|
||||
}
|
||||
}
|
||||
|
||||
# store as current
|
||||
$effectoryResources | Export-Csv "$Env:temp/$($fileName)"
|
||||
Set-AzStorageBlobContent -Context $context -Container "dangling-dns" -File "$Env:temp/$($fileName)" -Blob $fileName -Force
|
||||
}
|
||||
|
||||
# function Get-BlobEffectoryDomainResources {
|
||||
# <#
|
||||
# .SYNOPSIS
|
||||
# -
|
||||
# .DESCRIPTION
|
||||
# -
|
||||
# .PARAMETER subscriptionId
|
||||
# -
|
||||
# #>
|
||||
|
||||
# [EffectoryDomainNameCheck[]] $effectoryResources
|
||||
|
||||
|
||||
# }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# $context = New-AzStorageContext -ConnectionString "DefaultEndpointsProtocol=https;AccountName=runbookseffectory;AccountKey=PIyewEcppMcm8imMhpUUOgrOUbWyFPK0o8PfdwPnEiNvEQqUvTDzjuV4W18z2sBuRzspGs5pV/Fz96umfePviw==;EndpointSuffix=core.windows.net"
|
||||
# Get-AzTrafficManagerProfile | Export-Csv "$Env:temp/test4.csv"
|
||||
# Set-AzStorageBlobContent -Context $context -Container "dangling-dns" -File "$Env:temp/test4.csv" -Blob "test2.csv" -Force >$null
|
||||
|
||||
# Get-AzStorageBlobContent -Context $context -Container "dangling-dns" -Blob "test2.csv" -Destination "$Env:temp/test3.csv" -Force
|
||||
# $foo = Import-CSV "$Env:temp/test3.csv"
|
||||
|
||||
# $foo
|
||||
Set-AzStorageBlobContent -Context $context -Container "dangling-dns" -File "$Env:temp/$($fileName)" -Blob $fileName -Force >$null
|
||||
Remove-Item -Path "$Env:temp/$($fileName)"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
function VerifyEffectoryDomainResources {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Find resources in Azure that no longer exist, but have DNS records.
|
||||
.DESCRIPTION
|
||||
Gets all resources that have hostnames.
|
||||
.PARAMETER effectoryDomainPattern
|
||||
The domain pattern to look for when enumerating hosts, e.g. '*.effectory.com'
|
||||
.PARAMETER effectoryResources
|
||||
The resources that currently exist.
|
||||
.PARAMETER effectoryResourcesPrevious
|
||||
The resources that existed previously.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $effectoryDomainPattern,
|
||||
[Parameter(Mandatory)]
|
||||
[AllowNull()]
|
||||
[EffectoryDomainNameCheck[]] $effectoryResources,
|
||||
[Parameter(Mandatory)]
|
||||
[AllowNull()]
|
||||
[EffectoryDomainNameCheck[]] $effectoryResourcesPrevious
|
||||
)
|
||||
|
||||
[bool] $hasErrors = $false
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------
|
||||
Write-Information "Comparing found resources with previously stored resources to find records that should've been deleted."
|
||||
foreach ($oldResource in $effectoryResourcesPrevious) {
|
||||
$currentItem = $effectoryResources.Where({$_.DomainName -eq $oldResource.DomainName}, 'First')
|
||||
|
||||
if (($null -eq $currentItem) -or ($currentItem.Count -eq 0)) {
|
||||
# Host name no longer exists, so there should be no DNS record
|
||||
# check
|
||||
Write-Warning "Host name '$($oldResource.DomainName)' no longer exists. Checking DNS record for '$($oldResource.ResourceName)' ($($oldResource.ResourceType))."
|
||||
$CName = DnsResolveHost -domainName $oldResource.DomainName -effectoryDomainPattern $effectoryDomainPattern -externalDNSServer "8.8.8.8"
|
||||
if (($null -ne $CName) -and ($CName -ne "")) {
|
||||
Write-Error "Host name '$($oldResource.DomainName)' no longer exists, but found DNS record '$($CName)' for '$($oldResource.ResourceName)' ($($oldResource.ResourceType))."
|
||||
$hasErrors = $true
|
||||
}
|
||||
}
|
||||
elseif (($oldResource.ResourceName -ne $currentItem.ResourceName) -or ($oldResource.ResourceId -ne $currentItem.ResourceId)) {
|
||||
# found, but does not point to the same resource
|
||||
# verify the DNS record to make sure it points to this resource
|
||||
Write-Warning "Host name '$($oldResource.DomainName)' was found, but points to another resource. Assuming this was intentional."
|
||||
}
|
||||
}
|
||||
|
||||
$hasErrors
|
||||
}
|
||||
Reference in New Issue
Block a user