From 07ca5183318863faed0286f50f14488ff3c7112a Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 25 May 2023 10:30:27 +0200 Subject: [PATCH 1/4] Update users.go Added an array containing "onPremisesSecurityIdentifier" and onPremisesSyncEnabled" to fill the $select variable when querying the Graph API at /v1.0/users As both, Microsoft and the AzureHound, document and state, both datasets are not included in the "default" query and need to be specified as a GET parameter of $select. Please refer to here: https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=http#optional-query-parameters And here: https://github.com/BloodHoundAD/AzureHound/blob/main/models/azure/user.go?plain=1#L323 So this was not fetched, as AzureHound is currently only doing the "default" fetch without $select. But BloodHound and the ingestor part are already taken both values into consideration. Please see: https://github.com/BloodHoundAD/BloodHound/blob/69786fa46fa18090e7641e086cd2aed70a530748/src/js/ingestion_types.js?plain=1#L523 and: https://github.com/BloodHoundAD/BloodHound/blob/69786fa46fa18090e7641e086cd2aed70a530748/src/js/newingestion.js?plain=1#L2896 --- client/users.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/users.go b/client/users.go index bbbf43f..6ebc859 100644 --- a/client/users.go +++ b/client/users.go @@ -76,7 +76,10 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc errResult = azure.UserResult{} nextLink string ) - + selectCols := []string{ + "onPremisesSecurityIdentifier", + "onPremisesSyncEnabled", + } if users, err := s.GetAzureADUsers(ctx, filter, search, orderBy, selectCols, 999, false); err != nil { errResult.Error = err out <- errResult From c54bf440453ceffcb01216bb3504b91d4a9db7f5 Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 25 May 2023 10:43:27 +0200 Subject: [PATCH 2/4] Update users.go --- client/users.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/users.go b/client/users.go index 6ebc859..2d7e721 100644 --- a/client/users.go +++ b/client/users.go @@ -77,6 +77,11 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc nextLink string ) selectCols := []string{ + "id", + "displayName", + "jobTitle", + "lastPasswordChangeDateTime", + "mail", "onPremisesSecurityIdentifier", "onPremisesSyncEnabled", } From 9501192e5f40a8b2b1e03da44d9a1daefd6df194 Mon Sep 17 00:00:00 2001 From: LuemmelSec <58529760+LuemmelSec@users.noreply.github.com> Date: Thu, 25 May 2023 14:49:32 +0200 Subject: [PATCH 3/4] Update users.go The account enabled info slot was also included per default in BloodHound, but the actual data was never fetched by AzureHound as it also is an optional feature via the $select parameter. --- client/users.go | 1 + 1 file changed, 1 insertion(+) diff --git a/client/users.go b/client/users.go index 2d7e721..49ebbb1 100644 --- a/client/users.go +++ b/client/users.go @@ -82,6 +82,7 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc "jobTitle", "lastPasswordChangeDateTime", "mail", + "accountEnabled", "onPremisesSecurityIdentifier", "onPremisesSyncEnabled", } From f92070ee398ecdc8cb4ff9b81f9252c58c95dc3f Mon Sep 17 00:00:00 2001 From: Dillon Lees Date: Thu, 31 Aug 2023 11:17:04 -0400 Subject: [PATCH 4/4] fix: select properties that are used in bloodhound ingest --- client/users.go | 10 ---------- cmd/list-users.go | 14 +++++++++++++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client/users.go b/client/users.go index 49ebbb1..a84713a 100644 --- a/client/users.go +++ b/client/users.go @@ -76,16 +76,6 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc errResult = azure.UserResult{} nextLink string ) - selectCols := []string{ - "id", - "displayName", - "jobTitle", - "lastPasswordChangeDateTime", - "mail", - "accountEnabled", - "onPremisesSecurityIdentifier", - "onPremisesSyncEnabled", - } if users, err := s.GetAzureADUsers(ctx, filter, search, orderBy, selectCols, 999, false); err != nil { errResult.Error = err out <- errResult diff --git a/cmd/list-users.go b/cmd/list-users.go index e3f06d4..7a71eca 100644 --- a/cmd/list-users.go +++ b/cmd/list-users.go @@ -60,7 +60,19 @@ func listUsers(ctx context.Context, client client.AzureClient) <-chan interface{ go func() { defer close(out) count := 0 - for item := range client.ListAzureADUsers(ctx, "", "", "", nil) { + for item := range client.ListAzureADUsers(ctx, "", "", "", []string{ + "accountEnabled", + "createdDateTime", + "displayName", + "jobTitle", + "lastPasswordChangeDateTime", + "mail", + "onPremisesSecurityIdentifier", + "onPremisesSyncEnabled", + "userPrincipalName", + "userType", + "id", + }) { if item.Error != nil { log.Error(item.Error, "unable to continue processing users") return