ID | Technique | Tactic |
---|---|---|
T1562 | Impair Defenses | Defense Evasion |
Detection: M365 Copilot Non Compliant Devices Accessing M365 Copilot
Description
Detects M365 Copilot access from non-compliant or unmanaged devices that violate corporate security policies, indicating potential shadow IT usage, BYOD policy violations, or compromised endpoint access. The detection filters M365 Copilot Graph API events where deviceDetail.isCompliant=false or deviceDetail.isManaged=false, then aggregates by user, operating system, and browser to calculate metrics including event counts, unique IPs and locations, and compliance/management status over time. Users accessing Copilot from non-compliant or unmanaged devices are flagged and sorted by activity volume and geographic spread, enabling security teams to identify unauthorized endpoints that may lack proper security controls, encryption, or MDM enrollment.
Search
1`m365_copilot_graph_api` (appDisplayName="*Copilot*" OR appDisplayName="M365ChatClient") deviceDetail.isCompliant=false OR deviceDetail.isManaged=false
2| eval user = userPrincipalName
3| stats count as events, dc(ipAddress) as unique_ips, values(ipAddress) as ip_addresses, dc(location.city) as unique_cities, values(location.city) as cities, dc(location.countryOrRegion) as unique_countries, values(location.countryOrRegion) as countries, values(deviceDetail.isCompliant) as compliance_status, values(deviceDetail.isManaged) as management_status, min(_time) as first_seen, max(_time) as last_seen by user, deviceDetail.operatingSystem, deviceDetail.browser
4| eval days_active = round((last_seen - first_seen)/86400, 1)
5| eval first_seen = strftime(first_seen, "%Y-%m-%d %H:%M:%S")
6| eval last_seen = strftime(last_seen, "%Y-%m-%d %H:%M:%S")
7| sort -events, -unique_countries
8| `m365_copilot_non_compliant_devices_accessing_m365_copilot_filter`
Data Source
Name | Platform | Sourcetype | Source |
---|---|---|---|
M365 Copilot Graph API | N/A | 'o365:graph:api' |
'AuditLogs.SignIns' |
Macros Used
Name | Value |
---|---|
m365_copilot_graph_api | (sourcetype="o365:graph:api" OR source="AuditLogs.SignIns") |
m365_copilot_non_compliant_devices_accessing_m365_copilot_filter | search * |
m365_copilot_non_compliant_devices_accessing_m365_copilot_filter
is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.
Annotations
Default Configuration
This detection is configured by default in Splunk Enterprise Security to run with the following settings:
Setting | Value |
---|---|
Disabled | true |
Cron Schedule | 0 * * * * |
Earliest Time | -70m@m |
Latest Time | -10m@m |
Schedule Window | auto |
Creates Risk Event | True |
Implementation
This detection requires ingesting M365 Copilot access logs via the Splunk Add-on for Microsoft Office 365. Configure the add-on to collect Azure AD Sign-in logs (AuditLogs.SignIns) through the Graph API data input. Ensure proper authentication and permissions are configured to access sign-in audit logs. The m365_copilot_graph_api
macro should be defined to filter for sourcetype o365:graph:api data containing Copilot application activity.
Known False Positives
Legitimate employees using personal devices during emergencies, new hires awaiting device provisioning, temporary workers with unmanaged equipment, or users accessing Copilot from approved but temporarily non-compliant devices may trigger false positives.
Associated Analytic Story
Risk Based Analytics (RBA)
Risk Message:
User $user$ accessed M365 Copilot from non-compliant or unmanaged devices accross $unique_countries$ countries, violating corporate security policies and creating potential data exposure risks.
Risk Object | Risk Object Type | Risk Score | Threat Objects |
---|---|---|---|
user | user | 50 | No Threat Objects |
References
Detection Testing
Test Type | Status | Dataset | Source | Sourcetype |
---|---|---|---|---|
Validation | ✅ Passing | N/A | N/A | N/A |
Unit | ✅ Passing | Dataset | AuditLogs.SignIns |
o365:graph:api |
Integration | ✅ Passing | Dataset | AuditLogs.SignIns |
o365:graph:api |
Replay any dataset to Splunk Enterprise by using our replay.py
tool or the UI.
Alternatively you can replay a dataset into a Splunk Attack Range
Source: GitHub | Version: 1