From 1be3aa2ffbcbf015e5a9465d02b7245422cb9fbf Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Fri, 8 Mar 2024 12:21:07 -0300 Subject: [PATCH] improve MDM detection with enrollment state checks (#17494) for #17489 --- changes/17489-win-mdm | 1 + server/service/osquery_utils/queries.go | 19 +++++++++++++++++-- server/service/osquery_utils/queries_test.go | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 changes/17489-win-mdm diff --git a/changes/17489-win-mdm b/changes/17489-win-mdm new file mode 100644 index 0000000000..82167d8b78 --- /dev/null +++ b/changes/17489-win-mdm @@ -0,0 +1 @@ +* Improve osquery queries for MDM detection to take into account the enrollment state of the rows fetched from the registry. diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index a7d6d7d40e..39e4fa30d0 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -455,7 +455,17 @@ var extraDetailQueries = map[string]DetailQuery{ // the `mdm_bridge` table is used, the `mdmlocalmanagement.dll` // registers an MDM with ProviderID = `Local_Management` // - // For more information, refer to issue #15362 + // Entries also need to be filtered by their enrollment status, described [here][1] + // + // Member Value Description + // unknown 0 Device enrollment state is unknown + // enrolled 1 Device is Enrolled. + // pendingReset 2 Enrolled but it's enrolled via enrollment profile and the enrolled profile is different from the assigned profile. + // failed 3 Not enrolled and there is enrollment failure record. + // notContacted 4 Device is imported but not enrolled. + // blocked 5 Device is enrolled as userless, but is blocked from moving to user enrollment because the app failed to install. + // + // [1]: https://learn.microsoft.com/en-us/graph/api/resources/intune-shared-enrollmentstate Query: ` WITH registry_keys AS ( SELECT * @@ -467,7 +477,8 @@ var extraDetailQueries = map[string]DetailQuery{ MAX(CASE WHEN name = 'UPN' THEN data END) AS upn, MAX(CASE WHEN name = 'IsFederated' THEN data END) AS is_federated, MAX(CASE WHEN name = 'DiscoveryServiceFullURL' THEN data END) AS discovery_service_url, - MAX(CASE WHEN name = 'ProviderID' THEN data END) AS provider_id + MAX(CASE WHEN name = 'ProviderID' THEN data END) AS provider_id, + MAX(CASE WHEN name = 'EnrollmentState' THEN data END) AS state FROM registry_keys GROUP BY key ), @@ -484,6 +495,10 @@ var extraDetailQueries = map[string]DetailQuery{ i.installation_type FROM installation_info i LEFT JOIN enrollment_info e ON e.upn IS NOT NULL + -- coalesce to 'unknown' and keep that state in the list + -- in order to account for hosts that might not have this + -- key, and servers + WHERE COALESCE(e.state, '0') IN ('0', '1', '2') LIMIT 1; `, DirectIngestFunc: directIngestMDMWindows, diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index c6c626eb07..41ffc5013a 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -25,7 +25,7 @@ import ( "github.com/fleetdm/fleet/v4/server/mock" "github.com/fleetdm/fleet/v4/server/ptr" "github.com/fleetdm/fleet/v4/server/service/async" - "github.com/go-kit/kit/log" + "github.com/go-kit/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/exp/maps"