diff --git a/client/app_role_assignments.go b/client/app_role_assignments.go index c2eac7a..09659f0 100644 --- a/client/app_role_assignments.go +++ b/client/app_role_assignments.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -56,6 +57,7 @@ func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, service out := make(chan azure.AppRoleAssignmentResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/apps.go b/client/apps.go index 1091a31..fb60ed5 100644 --- a/client/apps.go +++ b/client/apps.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -105,6 +106,7 @@ func (s *azureClient) ListAzureADApps(ctx context.Context, filter, search, order out := make(chan azure.ApplicationResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -169,6 +171,7 @@ func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, out := make(chan azure.AppOwnerResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -239,6 +242,7 @@ func (s *azureClient) ListAzureADAppMemberObjects(ctx context.Context, objectId out := make(chan azure.MemberObjectResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/automation_accounts.go b/client/automation_accounts.go index 2131acf..512271b 100644 --- a/client/automation_accounts.go +++ b/client/automation_accounts.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureAutomationAccounts(ctx context.Context, subscript out := make(chan azure.AutomationAccountResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/container_registries.go b/client/container_registries.go index 8aeecdc..9e7eebb 100644 --- a/client/container_registries.go +++ b/client/container_registries.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureContainerRegistries(ctx context.Context, subscrip out := make(chan azure.ContainerRegistryResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/devices.go b/client/devices.go index 8b811a2..823ab71 100644 --- a/client/devices.go +++ b/client/devices.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -86,6 +87,7 @@ func (s *azureClient) ListAzureDevices(ctx context.Context, filter, search, orde out := make(chan azure.DeviceResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -150,6 +152,7 @@ func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objec out := make(chan azure.DeviceRegisteredOwnerResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/function_apps.go b/client/function_apps.go index 640acce..3e2e113 100644 --- a/client/function_apps.go +++ b/client/function_apps.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureFunctionApps(ctx context.Context, subscriptionId out := make(chan azure.FunctionAppResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/groups.go b/client/groups.go index 4e205f8..5db0474 100644 --- a/client/groups.go +++ b/client/groups.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -102,6 +103,7 @@ func (s *azureClient) ListAzureADGroups(ctx context.Context, filter, search, ord out := make(chan azure.GroupResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -166,6 +168,7 @@ func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId strin out := make(chan azure.GroupOwnerResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -236,6 +239,7 @@ func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId stri out := make(chan azure.MemberObjectResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/keyvaults.go b/client/keyvaults.go index 991cd6c..56e33f7 100644 --- a/client/keyvaults.go +++ b/client/keyvaults.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId str out := make(chan azure.KeyVaultResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/logic_apps.go b/client/logic_apps.go index 70d1257..54006a5 100644 --- a/client/logic_apps.go +++ b/client/logic_apps.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureLogicApps(ctx context.Context, subscriptionId str out := make(chan azure.LogicAppResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/managed_clusters.go b/client/managed_clusters.go index 13168ac..b1db393 100644 --- a/client/managed_clusters.go +++ b/client/managed_clusters.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscription out := make(chan azure.ManagedClusterResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/management_groups.go b/client/management_groups.go index 673c9b0..f68d866 100644 --- a/client/management_groups.go +++ b/client/management_groups.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -82,6 +83,7 @@ func (s *azureClient) ListAzureManagementGroups(ctx context.Context) <-chan azur out := make(chan azure.ManagementGroupResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -146,6 +148,7 @@ func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, g out := make(chan azure.DescendantInfoResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/resource_groups.go b/client/resource_groups.go index 3164c0f..c693fc4 100644 --- a/client/resource_groups.go +++ b/client/resource_groups.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionI out := make(chan azure.ResourceGroupResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/role_assignments.go b/client/role_assignments.go index fd94cd4..34f7da1 100644 --- a/client/role_assignments.go +++ b/client/role_assignments.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -71,6 +72,7 @@ func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, filter, se out := make(chan azure.UnifiedRoleAssignmentResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -153,6 +155,7 @@ func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resour out := make(chan azure.RoleAssignmentResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -240,6 +243,7 @@ func (s *azureClient) ListResourceRoleAssignments(ctx context.Context, subscript out := make(chan azure.RoleAssignmentResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/roles.go b/client/roles.go index 006c003..1f6fd5a 100644 --- a/client/roles.go +++ b/client/roles.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureADRoles(ctx context.Context, filter, expand strin out := make(chan azure.RoleResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/service_principals.go b/client/service_principals.go index 9c1d39b..9f8642e 100644 --- a/client/service_principals.go +++ b/client/service_principals.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -86,6 +87,7 @@ func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, filter, out := make(chan azure.ServicePrincipalResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -150,6 +152,7 @@ func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, obj out := make(chan azure.ServicePrincipalOwnerResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/storage_accounts.go b/client/storage_accounts.go index 50f40c9..920deb1 100644 --- a/client/storage_accounts.go +++ b/client/storage_accounts.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -64,6 +65,7 @@ func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscription out := make(chan azure.StorageAccountResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( @@ -169,6 +171,7 @@ func (s *azureClient) ListAzureStorageContainers(ctx context.Context, subscripti out := make(chan azure.StorageContainerResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/subscriptions.go b/client/subscriptions.go index c44c17f..877d18b 100644 --- a/client/subscriptions.go +++ b/client/subscriptions.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureSubscriptions(ctx context.Context) <-chan azure.S out := make(chan azure.SubscriptionResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/tenants.go b/client/tenants.go index bd3314e..1584190 100644 --- a/client/tenants.go +++ b/client/tenants.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureADTenants(ctx context.Context, includeAllTenantCa out := make(chan azure.TenantResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/users.go b/client/users.go index 98cec6c..cea543d 100644 --- a/client/users.go +++ b/client/users.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -71,6 +72,7 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc out := make(chan azure.UserResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/virtual_machines.go b/client/virtual_machines.go index ccb810c..1934974 100644 --- a/client/virtual_machines.go +++ b/client/virtual_machines.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscription out := make(chan azure.VirtualMachineResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/vm_scale_sets.go b/client/vm_scale_sets.go index 4158553..94879ad 100644 --- a/client/vm_scale_sets.go +++ b/client/vm_scale_sets.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId s out := make(chan azure.VMScaleSetResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/client/web_apps.go b/client/web_apps.go index 7560d23..d25fdfc 100644 --- a/client/web_apps.go +++ b/client/web_apps.go @@ -25,6 +25,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client/query" "github.com/bloodhoundad/azurehound/v2/client/rest" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -65,6 +66,7 @@ func (s *azureClient) ListAzureWebApps(ctx context.Context, subscriptionId strin out := make(chan azure.WebAppResult) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( diff --git a/cmd/list-app-owners.go b/cmd/list-app-owners.go index 869f03b..5fe7336 100644 --- a/cmd/list-app-owners.go +++ b/cmd/list-app-owners.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -51,6 +52,7 @@ func listAppOwnersCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure app owners...") start := time.Now() stream := listAppOwners(ctx, azClient, listApps(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listAppOwners(ctx context.Context, client client.AzureClient, apps <-chan a for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for app := range stream { var ( diff --git a/cmd/list-app-role-assignments.go b/cmd/list-app-role-assignments.go index 0cb2a52..9e3aa4b 100644 --- a/cmd/list-app-role-assignments.go +++ b/cmd/list-app-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listAppRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) { start := time.Now() servicePrincipals := listServicePrincipals(ctx, azClient) stream := listAppRoleAssignments(ctx, azClient, servicePrincipals) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listAppRoleAssignments(ctx context.Context, client client.AzureClient, serv ) go func() { + defer panicrecovery.PanicRecovery() defer close(filteredSPs) for result := range pipeline.OrDone(ctx.Done(), servicePrincipals) { @@ -87,6 +90,7 @@ func listAppRoleAssignments(ctx context.Context, client client.AzureClient, serv for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for servicePrincipal := range stream { var ( diff --git a/cmd/list-apps.go b/cmd/list-apps.go index 76f7e59..8160eb6 100644 --- a/cmd/list-apps.go +++ b/cmd/list-apps.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listAppsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory applications...") start := time.Now() stream := listApps(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listApps(ctx context.Context, client client.AzureClient) <-chan azureWrappe out := make(chan azureWrapper[models.App]) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureADApps(ctx, "", "", "", "", nil) { diff --git a/cmd/list-automation-account-role-assignments.go b/cmd/list-automation-account-role-assignments.go index f0bbcff..7b25179 100644 --- a/cmd/list-automation-account-role-assignments.go +++ b/cmd/list-automation-account-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listAutomationAccountRoleAssignmentImpl(cmd *cobra.Command, args []string) start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listAutomationAccountRoleAssignments(ctx, azClient, listAutomationAccounts(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -68,6 +70,7 @@ func listAutomationAccountRoleAssignments(ctx context.Context, client client.Azu ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), automationAccounts) { @@ -86,6 +89,7 @@ func listAutomationAccountRoleAssignments(ctx context.Context, client client.Azu for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-automation-accounts.go b/cmd/list-automation-accounts.go index cf38396..bd51f48 100644 --- a/cmd/list-automation-accounts.go +++ b/cmd/list-automation-accounts.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listAutomationAccountsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure automation accounts...") start := time.Now() stream := listAutomationAccounts(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listAutomationAccounts(ctx context.Context, client client.AzureClient, subs ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -83,6 +86,7 @@ func listAutomationAccounts(ctx context.Context, client client.AzureClient, subs for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-azure-ad.go b/cmd/list-azure-ad.go index c53fcaa..bca217d 100644 --- a/cmd/list-azure-ad.go +++ b/cmd/list-azure-ad.go @@ -25,6 +25,7 @@ import ( "time" "github.com/bloodhoundad/azurehound/v2/client" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listAzureADCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure ad objects...") start := time.Now() stream := listAllAD(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) diff --git a/cmd/list-azure-rm.go b/cmd/list-azure-rm.go index de4f186..b377e58 100644 --- a/cmd/list-azure-rm.go +++ b/cmd/list-azure-rm.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,6 +57,7 @@ func listAzureRMCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure resource management objects...") start := time.Now() stream := listAllRM(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) diff --git a/cmd/list-container-registries.go b/cmd/list-container-registries.go index 2ed3e4f..93a0932 100644 --- a/cmd/list-container-registries.go +++ b/cmd/list-container-registries.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,6 +57,7 @@ func listContainerRegistriesCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure container registries...") start := time.Now() stream := listContainerRegistries(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -71,6 +73,7 @@ func listContainerRegistries(ctx context.Context, client client.AzureClient, sub ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -88,6 +91,7 @@ func listContainerRegistries(ctx context.Context, client client.AzureClient, sub for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-container-registry-role-assignments.go b/cmd/list-container-registry-role-assignments.go index 4cfdf12..31c3806 100644 --- a/cmd/list-container-registry-role-assignments.go +++ b/cmd/list-container-registry-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -58,6 +59,7 @@ func listContainerRegistryRoleAssignmentImpl(cmd *cobra.Command, args []string) start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listContainerRegistryRoleAssignments(ctx, azClient, listContainerRegistries(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listContainerRegistryRoleAssignments(ctx context.Context, client client.Azu ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), containerRegistries) { @@ -91,6 +94,7 @@ func listContainerRegistryRoleAssignments(ctx context.Context, client client.Azu for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-device-owners.go b/cmd/list-device-owners.go index 124c646..1d0c2e6 100644 --- a/cmd/list-device-owners.go +++ b/cmd/list-device-owners.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listDeviceOwnersCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure device owners...") start := time.Now() stream := listDeviceOwners(ctx, azClient, listDevices(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listDeviceOwners(ctx context.Context, client client.AzureClient, devices <- ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), devices) { @@ -83,6 +86,7 @@ func listDeviceOwners(ctx context.Context, client client.AzureClient, devices <- for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-devices.go b/cmd/list-devices.go index 37ccbb6..5e68b8b 100644 --- a/cmd/list-devices.go +++ b/cmd/list-devices.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listDevicesCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory devices...") start := time.Now() stream := listDevices(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listDevices(ctx context.Context, client client.AzureClient) <-chan interfac out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureDevices(ctx, "", "", "", "", nil) { diff --git a/cmd/list-function-app-role-assignments.go b/cmd/list-function-app-role-assignments.go index 7433e75..d881936 100644 --- a/cmd/list-function-app-role-assignments.go +++ b/cmd/list-function-app-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listFunctionAppRoleAssignmentImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listFunctionAppRoleAssignments(ctx, azClient, listFunctionApps(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -68,6 +70,7 @@ func listFunctionAppRoleAssignments(ctx context.Context, client client.AzureClie ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), functionApps) { @@ -86,6 +89,7 @@ func listFunctionAppRoleAssignments(ctx context.Context, client client.AzureClie for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-function-apps.go b/cmd/list-function-apps.go index a63e453..d4e9b56 100644 --- a/cmd/list-function-apps.go +++ b/cmd/list-function-apps.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listFunctionAppsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure function apps...") start := time.Now() stream := listFunctionApps(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listFunctionApps(ctx context.Context, client client.AzureClient, subscripti ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -83,6 +86,7 @@ func listFunctionApps(ctx context.Context, client client.AzureClient, subscripti for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-group-members.go b/cmd/list-group-members.go index cfdd203..2f534a0 100644 --- a/cmd/list-group-members.go +++ b/cmd/list-group-members.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -66,6 +67,7 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), groups) { @@ -84,6 +86,7 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-group-owners.go b/cmd/list-group-owners.go index 6bd171d..e24d13b 100644 --- a/cmd/list-group-owners.go +++ b/cmd/list-group-owners.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -66,6 +67,7 @@ func listGroupOwners(ctx context.Context, client client.AzureClient, groups <-ch ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), groups) { @@ -84,6 +86,7 @@ func listGroupOwners(ctx context.Context, client client.AzureClient, groups <-ch for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-groups.go b/cmd/list-groups.go index 21e321a..47b8dde 100644 --- a/cmd/list-groups.go +++ b/cmd/list-groups.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listGroupsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory groups...") start := time.Now() stream := listGroups(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listGroups(ctx context.Context, client client.AzureClient) <-chan interface out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureADGroups(ctx, "securityEnabled eq true", "", "", "", nil) { diff --git a/cmd/list-key-vault-access-policies.go b/cmd/list-key-vault-access-policies.go index a7438e1..31c8d79 100644 --- a/cmd/list-key-vault-access-policies.go +++ b/cmd/list-key-vault-access-policies.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" kinds "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -65,12 +66,14 @@ func listKeyVaultAccessPoliciesCmdImpl(cmd *cobra.Command, args []string) { duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) } + panicrecovery.HandleBubbledPanic(ctx, stop, log) } func listKeyVaultAccessPolicies(ctx context.Context, client client.AzureClient, keyVaults <-chan interface{}, filters []enums.KeyVaultAccessType) <-chan interface{} { out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) for result := range pipeline.OrDone(ctx.Done(), keyVaults) { diff --git a/cmd/list-key-vault-contributors.go b/cmd/list-key-vault-contributors.go index 59bb49d..8bea518 100644 --- a/cmd/list-key-vault-contributors.go +++ b/cmd/list-key-vault-contributors.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listKeyVaultContributorsCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) keyVaults := listKeyVaults(ctx, azClient, subscriptions) kvRoleAssignments := listKeyVaultRoleAssignments(ctx, azClient, keyVaults) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listKeyVaultContributors(ctx, kvRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-key-vault-kvcontributors.go b/cmd/list-key-vault-kvcontributors.go index 46bfdc6..1e8a864 100644 --- a/cmd/list-key-vault-kvcontributors.go +++ b/cmd/list-key-vault-kvcontributors.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listKeyVaultKVContributorsCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) keyVaults := listKeyVaults(ctx, azClient, subscriptions) kvRoleAssignments := listKeyVaultRoleAssignments(ctx, azClient, keyVaults) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listKeyVaultKVContributors(ctx, kvRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-key-vault-owners.go b/cmd/list-key-vault-owners.go index 42ae7db..3adb5d5 100644 --- a/cmd/list-key-vault-owners.go +++ b/cmd/list-key-vault-owners.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listKeyVaultOwnersCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) keyVaults := listKeyVaults(ctx, azClient, subscriptions) kvRoleAssignments := listKeyVaultRoleAssignments(ctx, azClient, keyVaults) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listKeyVaultOwners(ctx, kvRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-key-vault-role-assignments.go b/cmd/list-key-vault-role-assignments.go index ee14b05..05b67d2 100644 --- a/cmd/list-key-vault-role-assignments.go +++ b/cmd/list-key-vault-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listKeyVaultRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listKeyVaultRoleAssignments(ctx, azClient, listKeyVaults(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listKeyVaultRoleAssignments(ctx context.Context, client client.AzureClient, ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), keyVaults) { @@ -85,6 +88,7 @@ func listKeyVaultRoleAssignments(ctx context.Context, client client.AzureClient, for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-key-vault-user-access-admins.go b/cmd/list-key-vault-user-access-admins.go index b19fd2c..e0e2515 100644 --- a/cmd/list-key-vault-user-access-admins.go +++ b/cmd/list-key-vault-user-access-admins.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listKeyVaultUserAccessAdminsCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) keyVaults := listKeyVaults(ctx, azClient, subscriptions) kvRoleAssignments := listKeyVaultRoleAssignments(ctx, azClient, keyVaults) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listKeyVaultUserAccessAdmins(ctx, kvRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-key-vaults.go b/cmd/list-key-vaults.go index dee1bcb..66626d4 100644 --- a/cmd/list-key-vaults.go +++ b/cmd/list-key-vaults.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listKeyVaultsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure key vaults...") start := time.Now() stream := listKeyVaults(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listKeyVaults(ctx context.Context, client client.AzureClient, subscriptions ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { @@ -84,6 +87,7 @@ func listKeyVaults(ctx context.Context, client client.AzureClient, subscriptions for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-logic-app-role-assignments.go b/cmd/list-logic-app-role-assignments.go index ed73508..0dd33aa 100644 --- a/cmd/list-logic-app-role-assignments.go +++ b/cmd/list-logic-app-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -58,6 +59,7 @@ func listLogicAppRoleAssignmentImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listLogicAppRoleAssignments(ctx, azClient, listLogicApps(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listLogicAppRoleAssignments(ctx context.Context, client client.AzureClient, ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), logicapps) { @@ -91,6 +94,7 @@ func listLogicAppRoleAssignments(ctx context.Context, client client.AzureClient, for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-logic-apps.go b/cmd/list-logic-apps.go index a928634..415168d 100644 --- a/cmd/list-logic-apps.go +++ b/cmd/list-logic-apps.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,6 +57,7 @@ func listLogicAppsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure logic apps...") start := time.Now() stream := listLogicApps(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -71,6 +73,7 @@ func listLogicApps(ctx context.Context, client client.AzureClient, subscriptions ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -88,6 +91,7 @@ func listLogicApps(ctx context.Context, client client.AzureClient, subscriptions for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-managed-cluster-role-assignments.go b/cmd/list-managed-cluster-role-assignments.go index 323df75..102db09 100644 --- a/cmd/list-managed-cluster-role-assignments.go +++ b/cmd/list-managed-cluster-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -58,6 +59,7 @@ func listManagedClusterRoleAssignmentImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listManagedClusterRoleAssignments(ctx, azClient, listManagedClusters(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listManagedClusterRoleAssignments(ctx context.Context, client client.AzureC ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), managedClusters) { @@ -91,6 +94,7 @@ func listManagedClusterRoleAssignments(ctx context.Context, client client.AzureC for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-managed-clusters.go b/cmd/list-managed-clusters.go index 3384e61..d186666 100644 --- a/cmd/list-managed-clusters.go +++ b/cmd/list-managed-clusters.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,6 +57,7 @@ func listManagedClustersCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure managed clusters...") start := time.Now() stream := listManagedClusters(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -71,6 +73,7 @@ func listManagedClusters(ctx context.Context, client client.AzureClient, subscri ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -88,6 +91,7 @@ func listManagedClusters(ctx context.Context, client client.AzureClient, subscri for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-management-group-descendants.go b/cmd/list-management-group-descendants.go index 904c11e..404c56e 100644 --- a/cmd/list-management-group-descendants.go +++ b/cmd/list-management-group-descendants.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listManagementGroupDescendantsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure management group descendants...") start := time.Now() stream := listManagementGroupDescendants(ctx, azClient, listManagementGroups(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listManagementGroupDescendants(ctx context.Context, client client.AzureClie ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), managementGroups) { @@ -84,6 +87,7 @@ func listManagementGroupDescendants(ctx context.Context, client client.AzureClie for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-management-group-owners.go b/cmd/list-management-group-owners.go index c28cf6b..b076ed6 100644 --- a/cmd/list-management-group-owners.go +++ b/cmd/list-management-group-owners.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listManagementGroupOwnersCmdImpl(cmd *cobra.Command, args []string) { start := time.Now() managementGroups := listManagementGroups(ctx, azClient) roleAssignments := listManagementGroupRoleAssignments(ctx, azClient, managementGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listManagementGroupOwners(ctx, roleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-management-group-role-assignments.go b/cmd/list-management-group-role-assignments.go index 3d07121..6ef9a51 100644 --- a/cmd/list-management-group-role-assignments.go +++ b/cmd/list-management-group-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listManagementGroupRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string start := time.Now() managementGroups := listManagementGroups(ctx, azClient) stream := listManagementGroupRoleAssignments(ctx, azClient, managementGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listManagementGroupRoleAssignments(ctx context.Context, client client.Azure ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), managementGroups) { @@ -85,6 +88,7 @@ func listManagementGroupRoleAssignments(ctx context.Context, client client.Azure for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-management-group-user-access-admins.go b/cmd/list-management-group-user-access-admins.go index 1235a51..ecb4be0 100644 --- a/cmd/list-management-group-user-access-admins.go +++ b/cmd/list-management-group-user-access-admins.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listManagementGroupUserAccessAdminsCmdImpl(cmd *cobra.Command, args []strin start := time.Now() managementGroups := listManagementGroups(ctx, azClient) roleAssignments := listManagementGroupRoleAssignments(ctx, azClient, managementGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listManagementGroupUserAccessAdmins(ctx, roleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-management-groups.go b/cmd/list-management-groups.go index 2d02e5f..87ddbe0 100644 --- a/cmd/list-management-groups.go +++ b/cmd/list-management-groups.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/config" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,7 +51,9 @@ func listManagementGroupsCmdImpl(cmd *cobra.Command, args []string) { azClient := connectAndCreateClient() log.Info("collecting azure active directory management groups...") start := time.Now() + stream := listManagementGroups(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -60,6 +63,7 @@ func listManagementGroups(ctx context.Context, client client.AzureClient) <-chan out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureManagementGroups(ctx) { diff --git a/cmd/list-resource-group-owners.go b/cmd/list-resource-group-owners.go index 7a07ae0..e049501 100644 --- a/cmd/list-resource-group-owners.go +++ b/cmd/list-resource-group-owners.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listResourceGroupOwnersCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) resourceGroups := listResourceGroups(ctx, azClient, subscriptions) roleAssignments := listResourceGroupRoleAssignments(ctx, azClient, resourceGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listResourceGroupOwners(ctx, roleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-resource-group-role-assignments.go b/cmd/list-resource-group-role-assignments.go index 055d3e0..a6d2fb7 100644 --- a/cmd/list-resource-group-role-assignments.go +++ b/cmd/list-resource-group-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listResourceGroupRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) subscriptions := listSubscriptions(ctx, azClient) resourceGroups := listResourceGroups(ctx, azClient, subscriptions) stream := listResourceGroupRoleAssignments(ctx, azClient, resourceGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -68,6 +70,7 @@ func listResourceGroupRoleAssignments(ctx context.Context, client client.AzureCl ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), resourceGroups) { @@ -86,6 +89,7 @@ func listResourceGroupRoleAssignments(ctx context.Context, client client.AzureCl for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-resource-group-user-access-admins.go b/cmd/list-resource-group-user-access-admins.go index 01f3af1..0762c77 100644 --- a/cmd/list-resource-group-user-access-admins.go +++ b/cmd/list-resource-group-user-access-admins.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listResourceGroupUserAccessAdminsCmdImpl(cmd *cobra.Command, args []string) subscriptions := listSubscriptions(ctx, azClient) resourceGroups := listResourceGroups(ctx, azClient, subscriptions) roleAssignments := listResourceGroupRoleAssignments(ctx, azClient, resourceGroups) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listResourceGroupUserAccessAdmins(ctx, roleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-resource-groups.go b/cmd/list-resource-groups.go index 5f83d56..c3ae948 100644 --- a/cmd/list-resource-groups.go +++ b/cmd/list-resource-groups.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listResourceGroupsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure resource groups...") start := time.Now() stream := listResourceGroups(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listResourceGroups(ctx context.Context, client client.AzureClient, subscrip ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { @@ -84,6 +87,7 @@ func listResourceGroups(ctx context.Context, client client.AzureClient, subscrip for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-role-assignments.go b/cmd/list-role-assignments.go index 0289c9e..cde6422 100644 --- a/cmd/list-role-assignments.go +++ b/cmd/list-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) { start := time.Now() roles := listRoles(ctx, azClient) stream := listRoleAssignments(ctx, azClient, roles) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listRoleAssignments(ctx context.Context, client client.AzureClient, roles < ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), roles) { @@ -85,6 +88,7 @@ func listRoleAssignments(ctx context.Context, client client.AzureClient, roles < for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-roles.go b/cmd/list-roles.go index ab93352..836c9b5 100644 --- a/cmd/list-roles.go +++ b/cmd/list-roles.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listRolesCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory roles...") start := time.Now() stream := listRoles(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listRoles(ctx context.Context, client client.AzureClient) <-chan interface{ out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureADRoles(ctx, "", "") { diff --git a/cmd/list-service-principal-owners.go b/cmd/list-service-principal-owners.go index 5e07aed..7fd4c56 100644 --- a/cmd/list-service-principal-owners.go +++ b/cmd/list-service-principal-owners.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listServicePrincipalOwnersCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure service principal owners...") start := time.Now() stream := listServicePrincipalOwners(ctx, azClient, listServicePrincipals(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listServicePrincipalOwners(ctx context.Context, client client.AzureClient, ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), servicePrincipals) { @@ -84,6 +87,7 @@ func listServicePrincipalOwners(ctx context.Context, client client.AzureClient, for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-service-principals.go b/cmd/list-service-principals.go index 80500e9..57399bd 100644 --- a/cmd/list-service-principals.go +++ b/cmd/list-service-principals.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listServicePrincipalsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory service principals...") start := time.Now() stream := listServicePrincipals(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listServicePrincipals(ctx context.Context, client client.AzureClient) <-cha out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureADServicePrincipals(ctx, "", "", "", "", nil) { diff --git a/cmd/list-storage-account-role-assignments.go b/cmd/list-storage-account-role-assignments.go index 4e5d0bc..71df35a 100644 --- a/cmd/list-storage-account-role-assignments.go +++ b/cmd/list-storage-account-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listStorageAccountRoleAssignmentsImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listStorageAccountRoleAssignments(ctx, azClient, listStorageAccounts(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -68,6 +70,7 @@ func listStorageAccountRoleAssignments(ctx context.Context, client client.AzureC ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), storageAccounts) { @@ -86,6 +89,7 @@ func listStorageAccountRoleAssignments(ctx context.Context, client client.AzureC for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-storage-accounts.go b/cmd/list-storage-accounts.go index 143a645..8c91c71 100644 --- a/cmd/list-storage-accounts.go +++ b/cmd/list-storage-accounts.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listStorageAccountsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure storage accounts...") start := time.Now() stream := listStorageAccounts(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listStorageAccounts(ctx context.Context, client client.AzureClient, subscri ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -83,6 +86,7 @@ func listStorageAccounts(ctx context.Context, client client.AzureClient, subscri for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-storage-containers.go b/cmd/list-storage-containers.go index 08b04d1..322f456 100644 --- a/cmd/list-storage-containers.go +++ b/cmd/list-storage-containers.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -54,6 +55,7 @@ func listStorageContainersCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) storageAccounts := listStorageAccounts(ctx, azClient, subscriptions) stream := listStorageContainers(ctx, azClient, storageAccounts) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listStorageContainers(ctx context.Context, client client.AzureClient, stora ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), storageAccounts) { if storageAccount, ok := result.(AzureWrapper).Data.(models.StorageAccount); !ok { @@ -90,6 +93,7 @@ func listStorageContainers(ctx context.Context, client client.AzureClient, stora for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for stAccount := range stream { count := 0 diff --git a/cmd/list-subscription-owners.go b/cmd/list-subscription-owners.go index af7dd59..b351b8e 100644 --- a/cmd/list-subscription-owners.go +++ b/cmd/list-subscription-owners.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -55,6 +56,7 @@ func listSubscriptionOwnersCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) roleAssignments := listSubscriptionRoleAssignments(ctx, azClient, subscriptions) stream := listSubscriptionOwners(ctx, azClient, roleAssignments) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -64,6 +66,7 @@ func listSubscriptionOwners(ctx context.Context, client client.AzureClient, role out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) for result := range pipeline.OrDone(ctx.Done(), roleAssignments) { diff --git a/cmd/list-subscription-role-assignments.go b/cmd/list-subscription-role-assignments.go index 3f23107..94279e3 100644 --- a/cmd/list-subscription-role-assignments.go +++ b/cmd/list-subscription-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listSubscriptionRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listSubscriptionRoleAssignments(ctx, azClient, subscriptions) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listSubscriptionRoleAssignments(ctx context.Context, client client.AzureCli ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { @@ -85,6 +88,7 @@ func listSubscriptionRoleAssignments(ctx context.Context, client client.AzureCli for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-subscription-user-access-admins.go b/cmd/list-subscription-user-access-admins.go index 9947836..c3f78fa 100644 --- a/cmd/list-subscription-user-access-admins.go +++ b/cmd/list-subscription-user-access-admins.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -55,6 +56,7 @@ func listSubscriptionUserAccessAdminsCmdImpl(cmd *cobra.Command, args []string) subscriptions := listSubscriptions(ctx, azClient) roleAssignments := listSubscriptionRoleAssignments(ctx, azClient, subscriptions) stream := listSubscriptionUserAccessAdmins(ctx, azClient, roleAssignments) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -64,6 +66,7 @@ func listSubscriptionUserAccessAdmins(ctx context.Context, client client.AzureCl out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) for result := range pipeline.OrDone(ctx.Done(), vmRoleAssignments) { diff --git a/cmd/list-subscriptions.go b/cmd/list-subscriptions.go index b2ee039..c1a6f24 100644 --- a/cmd/list-subscriptions.go +++ b/cmd/list-subscriptions.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/models" "github.com/bloodhoundad/azurehound/v2/models/azure" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/bloodhoundad/azurehound/v2/client" @@ -54,6 +55,7 @@ func listSubscriptionsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory subscriptions...") start := time.Now() stream := listSubscriptions(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -63,6 +65,7 @@ func listSubscriptions(ctx context.Context, client client.AzureClient) <-chan in out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) var ( count = 0 diff --git a/cmd/list-tenants.go b/cmd/list-tenants.go index 438cb79..3e02caf 100644 --- a/cmd/list-tenants.go +++ b/cmd/list-tenants.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listTenantsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory tenants...") start := time.Now() stream := listTenants(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listTenants(ctx context.Context, client client.AzureClient) <-chan interfac out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) // Send the fully hydrated tenant that is being collected diff --git a/cmd/list-users.go b/cmd/list-users.go index e02e37a..531b7a3 100644 --- a/cmd/list-users.go +++ b/cmd/list-users.go @@ -26,6 +26,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ func listUsersCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure active directory users...") start := time.Now() stream := listUsers(ctx, azClient) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -59,6 +61,7 @@ func listUsers(ctx context.Context, client client.AzureClient) <-chan interface{ out := make(chan interface{}) go func() { + defer panicrecovery.PanicRecovery() defer close(out) count := 0 for item := range client.ListAzureADUsers(ctx, "", "", "", []string{ diff --git a/cmd/list-virtual-machine-admin-logins.go b/cmd/list-virtual-machine-admin-logins.go index 7223317..3bbcd30 100644 --- a/cmd/list-virtual-machine-admin-logins.go +++ b/cmd/list-virtual-machine-admin-logins.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineAdminLoginsCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineAdminLogins(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machine-avere-contributors.go b/cmd/list-virtual-machine-avere-contributors.go index 6ee9780..577582d 100644 --- a/cmd/list-virtual-machine-avere-contributors.go +++ b/cmd/list-virtual-machine-avere-contributors.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineAvereContributorsCmdImpl(cmd *cobra.Command, args []strin subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineAvereContributors(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machine-contributors.go b/cmd/list-virtual-machine-contributors.go index 5d58f3d..bcc6abf 100644 --- a/cmd/list-virtual-machine-contributors.go +++ b/cmd/list-virtual-machine-contributors.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineContributorsCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineContributors(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machine-owners.go b/cmd/list-virtual-machine-owners.go index 2f5b99b..62edcf3 100644 --- a/cmd/list-virtual-machine-owners.go +++ b/cmd/list-virtual-machine-owners.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineOwnersCmdImpl(cmd *cobra.Command, args []string) { subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineOwners(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machine-role-assignments.go b/cmd/list-virtual-machine-role-assignments.go index d826a3f..097055e 100644 --- a/cmd/list-virtual-machine-role-assignments.go +++ b/cmd/list-virtual-machine-role-assignments.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineRoleAssignmentsCmdImpl(cmd *cobra.Command, args []string) start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listVirtualMachineRoleAssignments(ctx, azClient, listVirtualMachines(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -67,6 +69,7 @@ func listVirtualMachineRoleAssignments(ctx context.Context, client client.AzureC ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), virtualMachines) { @@ -85,6 +88,7 @@ func listVirtualMachineRoleAssignments(ctx context.Context, client client.AzureC for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-virtual-machine-user-access-admins.go b/cmd/list-virtual-machine-user-access-admins.go index 0846c0f..7b37c59 100644 --- a/cmd/list-virtual-machine-user-access-admins.go +++ b/cmd/list-virtual-machine-user-access-admins.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineUserAccessAdminsCmdImpl(cmd *cobra.Command, args []string subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineUserAccessAdmins(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machine-vmcontributors.go b/cmd/list-virtual-machine-vmcontributors.go index fda2b38..b89e04f 100644 --- a/cmd/list-virtual-machine-vmcontributors.go +++ b/cmd/list-virtual-machine-vmcontributors.go @@ -27,6 +27,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/internal" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -53,6 +54,7 @@ func listVirtualMachineVMContributorsCmdImpl(cmd *cobra.Command, args []string) subscriptions := listSubscriptions(ctx, azClient) vms := listVirtualMachines(ctx, azClient, subscriptions) vmRoleAssignments := listVirtualMachineRoleAssignments(ctx, azClient, vms) + panicrecovery.HandleBubbledPanic(ctx, stop, log) stream := listVirtualMachineVMContributors(ctx, vmRoleAssignments) outputStream(ctx, stream) duration := time.Since(start) diff --git a/cmd/list-virtual-machines.go b/cmd/list-virtual-machines.go index ad4b78e..d28d6e5 100644 --- a/cmd/list-virtual-machines.go +++ b/cmd/list-virtual-machines.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -52,6 +53,7 @@ func listVirtualMachinesCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure virtual machines...") start := time.Now() stream := listVirtualMachines(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -66,6 +68,7 @@ func listVirtualMachines(ctx context.Context, client client.AzureClient, subscri ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -83,6 +86,7 @@ func listVirtualMachines(ctx context.Context, client client.AzureClient, subscri for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-vm-scale-set-role-assignments.go b/cmd/list-vm-scale-set-role-assignments.go index 80c5a52..4a82b2e 100644 --- a/cmd/list-vm-scale-set-role-assignments.go +++ b/cmd/list-vm-scale-set-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -58,6 +59,7 @@ func listVMScaleSetRoleAssignmentImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listVMScaleSetRoleAssignments(ctx, azClient, listVMScaleSets(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listVMScaleSetRoleAssignments(ctx context.Context, client client.AzureClien ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), vmScaleSets) { @@ -91,6 +94,7 @@ func listVMScaleSetRoleAssignments(ctx context.Context, client client.AzureClien for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-vm-scale-sets.go b/cmd/list-vm-scale-sets.go index 9623a54..c55f4b2 100644 --- a/cmd/list-vm-scale-sets.go +++ b/cmd/list-vm-scale-sets.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,10 +57,12 @@ func listVMScaleSetsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure virtual machine scale sets...") start := time.Now() stream := listVMScaleSets(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) } + } func listVMScaleSets(ctx context.Context, client client.AzureClient, subscriptions <-chan interface{}) <-chan interface{} { @@ -71,6 +74,7 @@ func listVMScaleSets(ctx context.Context, client client.AzureClient, subscriptio ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -88,6 +92,7 @@ func listVMScaleSets(ctx context.Context, client client.AzureClient, subscriptio for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/list-web-app-role-assignments.go b/cmd/list-web-app-role-assignments.go index 3b45efb..90ce0ef 100644 --- a/cmd/list-web-app-role-assignments.go +++ b/cmd/list-web-app-role-assignments.go @@ -29,6 +29,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -58,6 +59,7 @@ func listWebAppRoleAssignmentImpl(cmd *cobra.Command, args []string) { start := time.Now() subscriptions := listSubscriptions(ctx, azClient) stream := listWebAppRoleAssignments(ctx, azClient, listWebApps(ctx, azClient, subscriptions)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -73,6 +75,7 @@ func listWebAppRoleAssignments(ctx context.Context, client client.AzureClient, w ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), webApps) { @@ -91,6 +94,7 @@ func listWebAppRoleAssignments(ctx context.Context, client client.AzureClient, w for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { var ( diff --git a/cmd/list-web-apps.go b/cmd/list-web-apps.go index ac1bad7..ac2aaec 100644 --- a/cmd/list-web-apps.go +++ b/cmd/list-web-apps.go @@ -28,6 +28,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/client" "github.com/bloodhoundad/azurehound/v2/enums" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" "github.com/spf13/cobra" ) @@ -56,6 +57,7 @@ func listWebAppsCmdImpl(cmd *cobra.Command, args []string) { log.Info("collecting azure web apps...") start := time.Now() stream := listWebApps(ctx, azClient, listSubscriptions(ctx, azClient)) + panicrecovery.HandleBubbledPanic(ctx, stop, log) outputStream(ctx, stream) duration := time.Since(start) log.Info("collection completed", "duration", duration.String()) @@ -71,6 +73,7 @@ func listWebApps(ctx context.Context, client client.AzureClient, subscriptions < ) go func() { + defer panicrecovery.PanicRecovery() defer close(ids) for result := range pipeline.OrDone(ctx.Done(), subscriptions) { if subscription, ok := result.(AzureWrapper).Data.(models.Subscription); !ok { @@ -88,6 +91,7 @@ func listWebApps(ctx context.Context, client client.AzureClient, subscriptions < for i := range streams { stream := streams[i] go func() { + defer panicrecovery.PanicRecovery() defer wg.Done() for id := range stream { count := 0 diff --git a/cmd/start.go b/cmd/start.go index 064fce3..3ea2afd 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -42,6 +42,7 @@ import ( "github.com/bloodhoundad/azurehound/v2/config" "github.com/bloodhoundad/azurehound/v2/constants" "github.com/bloodhoundad/azurehound/v2/models" + "github.com/bloodhoundad/azurehound/v2/panicrecovery" "github.com/bloodhoundad/azurehound/v2/pipeline" ) @@ -112,15 +113,18 @@ func start(ctx context.Context) { } } else if jobQueued.TryLock() { go func() { + defer panicrecovery.PanicRecovery() defer jobQueued.Unlock() defer bheClient.CloseIdleConnections() defer azClient.CloseIdleConnections() + ctx, stop := context.WithCancel(ctx) + panicrecovery.HandleBubbledPanic(ctx, stop, log) + log.V(2).Info("checking for available collection jobs") if jobs, err := getAvailableJobs(ctx, *bheInstance, bheClient); err != nil { log.Error(err, "unable to fetch available jobs for azurehound") } else { - // Get only the jobs that have reached their execution time executableJobs := []models.ClientJob{} now := time.Now() diff --git a/panicrecovery/panic_recovery.go b/panicrecovery/panic_recovery.go new file mode 100644 index 0000000..3cbd757 --- /dev/null +++ b/panicrecovery/panic_recovery.go @@ -0,0 +1,33 @@ +package panicrecovery + +import ( + "context" + "fmt" + "runtime/debug" + + "github.com/go-logr/logr" +) + +var PanicChan = make(chan error) + +// handleBubbledPanic receives errors from panicChan, then it will print them and stop() context. +func HandleBubbledPanic(ctx context.Context, stop context.CancelFunc, log logr.Logger) { + go func() { + for { + select { + case err := <-PanicChan: + log.V(0).Error(err, "") + stop() + case <-ctx.Done(): + return + } + } + }() +} + +// panicRecovery recovers from panics and sends them to panicChan +func PanicRecovery() { + if recovery := recover(); recovery != nil { + PanicChan <- fmt.Errorf("[panic recovery] %s - [stack trace] %s", recovery, debug.Stack()) + } +}