Detection rules › Splunk
O365 Multiple OS Vendors Authenticating From User
The following analytic identifies when multiple operating systems are used to authenticate to Azure/EntraID/Office 365 by the same user account over a short period of time. This activity could be indicative of attackers enumerating various logon capabilities of Azure/EntraID/Office 365 and attempting to discover weaknesses in the organizational MFA or conditional access configurations. Usage of the tools like "MFASweep" will trigger this detection.
Known false positives
- IP or users where the usage of multiple Operating systems is expected, filter accordingly.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | UserLoggedIn |
| Microsoft 365 | UserLoginFailed |
Rules detecting the same action
These rules filter on the same operation.
- Azure Login Bypassing Conditional Access Policies (Sigma)
- Hunt for suspicious sign-in to Entra ID Using Extrnal Call Method (YARA-L)
- M365 Identity OAuth Flow by First-Party Microsoft App from Multiple IPs (Elastic)
- M365 Identity OAuth Flow by User Sign-in to Device Registration (Elastic)
- M365 Identity OAuth Phishing via First-Party Microsoft Application (Elastic)
- M365 Identity OAuth ROPC Grant via Legacy Authentication Client (Elastic)
- M365 Potential AiTM UserLoggedIn via Office App (Tycoon2FA) (Elastic)
- Microsoft365 Brute Force Login by User (Panther)
Rule body
name: O365 Multiple OS Vendors Authenticating From User
id: 3451e58a-9457-4985-a600-b616b0cbfda1
version: 7
creation_date: '2025-01-06'
modification_date: '2026-05-13'
author: Steven Dick
status: production
type: TTP
description: The following analytic identifies when multiple operating systems are used to authenticate to Azure/EntraID/Office 365 by the same user account over a short period of time. This activity could be indicative of attackers enumerating various logon capabilities of Azure/EntraID/Office 365 and attempting to discover weaknesses in the organizational MFA or conditional access configurations. Usage of the tools like "MFASweep" will trigger this detection.
data_source:
- Office 365 Universal Audit Log
search: |-
`o365_management_activity` Operation IN (UserLoginFailed,UserLoggedIn)
| eval -time = _time
| bin _time span=15m
| fillnull
| stats values(Operation) as signature, values(ErrorNumber) as signature_id, values(OS) as os_name, dc(OS) as os_count, count, min(-time) as firstTime, max(-time) as lastTime by ClientIP, UserId, _time, dest, vendor_account, vendor_product
| where os_count >= 4
| eval src = ClientIP, user = UserId
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_multiple_os_vendors_authenticating_from_user_filter`
how_to_implement: You must install the Splunk Microsoft Office 365 Add-on and ingest Office 365 management activity events. The thresholds set within the analytic (such as unique OS) are initial guidelines and should be customized based on the organization's user behavior and risk profile. Security teams are encouraged to adjust these thresholds to optimize the balance between detecting genuine threats and minimizing false positives, ensuring the detection is tailored to their specific environment.
known_false_positives: IP or users where the usage of multiple Operating systems is expected, filter accordingly.
references:
- https://attack.mitre.org/techniques/T1110
- https://www.blackhillsinfosec.com/exploiting-mfa-inconsistencies-on-microsoft-services/
- https://sra.io/blog/msspray-wait-how-many-endpoints-dont-have-mfa/
- https://github.com/dafthack/MFASweep/tree/master
finding:
title: The user account $user$ authenticated with $os_count$ unique operating system types over a short period from $src$.
entity:
field: user
type: user
score: 50
threat_objects:
- field: src
type: ip_address
analytic_story:
- Office 365 Account Takeover
asset_type: O365 Tenant
mitre_attack_id:
- T1110
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
category: cloud
security_domain: threat
Stages and Predicates
Stage 1: search
`o365_management_activity` Operation IN (UserLoginFailed,UserLoggedIn)
Stage 2: eval
| eval -time = _time
Stage 3: bucket
| bin _time span=15m
Stage 4: fillnull
| fillnull
Stage 5: stats
| stats values(Operation) as signature, values(ErrorNumber) as signature_id, values(OS) as os_name, dc(OS) as os_count, count, min(-time) as firstTime, max(-time) as lastTime by ClientIP, UserId, _time, dest, vendor_account, vendor_product
Stage 6: where
| where os_count >= 4
Stage 7: eval
| eval src = ClientIP, user = UserId
Stage 8: search
| `security_content_ctime(firstTime)`
Stage 9: search
| `security_content_ctime(lastTime)`
Stage 10: search
| `o365_multiple_os_vendors_authenticating_from_user_filter`
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Operation | in |
| field:"Operation" kind:in |
os_count | ge |
| field:"os_count" kind:ge value:"4" |
sourcetype | eq |
| field:"sourcetype" kind:eq value:"o365:management:activity" |