Tool
Splunk ESCU
2,101 vendor-native detections · ready to paste into your SIEM · cross-linked to ATT&CK
◈
Detections
50 shown of 2,101O365 Application Available To Other Tenants
The following analytic identifies the configuration of Azure Active Directory Applications in a manner that allows authentication from external tenants or personal accounts. This configuration can lead to inappropriate or malicious access of any data or capabilities the application is allowed to access. This detection leverages the O365 Universal Audit Log data source.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation IN ("Add application.","Update application.") ModifiedProperties{}.Name=AvailableToOtherTenants | eval result = case(match(mvindex('ModifiedProperties{}.NewValue',mvfind('ModifiedProperties{}.Name',"AvailableToOtherTenants")),"false"),"removed",true(),"added"), object_name=mvindex('Target{}.ID', 3), signature=Operation, object_attrs = "AvailableToOtherTenants", user = case(match(mvindex('Actor{}.ID',-1),"User"),mvindex('Actor{}.ID',0),match(mvindex('Actor{}.ID',-1),"ServicePrincipal"),mvindex('Actor{}.ID',3),true(),mvindex('Actor{}.ID',0)) | search result = "added" | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by signature dest user src vendor_account vendor_product object_attrs object_name | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_application_available_to_other_tenants_filter`O365 Application Registration Owner Added
The following analytic identifies instances where a new owner is assigned to an application registration within an Azure AD and Office 365 tenant. It leverages O365 audit logs, specifically events related to changes in owner assignments within the AzureActiveDirectory workload. This activity is significant because assigning a new owner to an application registration can grant significant control over the application's configuration, permissions, and behavior. If confirmed malicious, an attacker could modify the application's settings, permissions, and behavior, leading to unauthorized data access, privilege escalation, or the introduction of malicious behavior within the application's operations.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Add owner to application." | eval app_id=mvindex('ModifiedProperties{}.NewValue', 0) | eval app_displayName=mvindex('ModifiedProperties{}.NewValue', 1) | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by signature dest user src vendor_account vendor_product app_id app_displayName object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_application_registration_owner_added_filter`O365 ApplicationImpersonation Role Assigned
The following analytic detects the assignment of the ApplicationImpersonation role in Office 365 to a user or application. It uses the Office 365 Management Activity API to monitor Azure Active Directory audit logs for role assignment events. This activity is significant because the ApplicationImpersonation role allows impersonation of any user, enabling access to and modification of their mailbox. If confirmed malicious, an attacker could gain unauthorized access to sensitive information, manipulate mailbox data, and perform actions as a legitimate user, posing a severe security risk to the organization.
Show query
`o365_management_activity` Workload=Exchange Operation="New-ManagementRoleAssignment" Role=ApplicationImpersonation
| rename User as target_user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
target_user
| `security_content_ctime(lastTime)`
| `o365_applicationimpersonation_role_assigned_filter`O365 BEC Email Hiding Rule Created
This analytic detects mailbox rule creation, a common technique used in Business Email Compromise. It uses a scoring mechanism to identify a combination of attributes often featured in mailbox rules created by attackers. This may indicate that an attacker has gained access to the account.
Show query
`o365_management_activity` Workload=Exchange Operation IN ("New-InboxRule", "Set-InboxRule")
| stats min(_time) as firstTime, max(_time) as lastTime, values(Operation) as Operation, latest(Name) as Name, latest(MarkAsRead) as MarkAsRead, latest(MoveToFolder) as MoveToFolder by object_id user
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| lookup ut_shannon_lookup word as Name
| eval entropy_score=if(ut_shannon<=2, 1, 0)
| eval len_score=if(len(Name)<=3, 1,0)
| eval read_score=if(MarkAsRead="True", 1, 0)
| eval folder_score=if(match(MoveToFolder, "^(RSS|Conversation History|Archive)"), 1, 0)
| eval suspicious_score=entropy_score+len_score+read_score+folder_score
| where suspicious_score>2
| `o365_bec_email_hiding_rule_created_filter`O365 Block User Consent For Risky Apps Disabled
The following analytic detects when the "risk-based step-up consent" security setting in Microsoft 365 is disabled. It monitors Azure Active Directory logs for the "Update authorization policy" operation, specifically changes to the "AllowUserConsentForRiskyApps" setting. This activity is significant because disabling this feature can expose the organization to OAuth phishing threats, allowing users to grant consent to malicious applications. If confirmed malicious, attackers could gain unauthorized access to user data and sensitive information, leading to data breaches and further compromise within the organization.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Update authorization policy." | eval index_number = if(mvfind('ModifiedProperties{}.Name',"AllowUserConsentForRiskyApps") >= 0, mvfind('ModifiedProperties{}.Name',"AllowUserConsentForRiskyApps"), -1) | search index_number >= 0 | eval AllowUserConsentForRiskyApps = mvindex('ModifiedProperties{}.NewValue',index_number) | where AllowUserConsentForRiskyApps like "%true%" | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by signature dest user src vendor_account vendor_product AllowUserConsentForRiskyApps | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_block_user_consent_for_risky_apps_disabled_filter`O365 Bypass MFA via Trusted IP
The following analytic identifies instances where new IP addresses are added to the trusted IPs list in Office 365, potentially allowing users from these IPs to bypass Multi-Factor Authentication (MFA) during login. It leverages O365 audit logs, specifically focusing on events related to the modification of trusted IP settings. This activity is significant because adding trusted IPs can weaken the security posture by bypassing MFA, which is a critical security control. If confirmed malicious, this could lead to unauthorized access, compromising sensitive information and systems. Immediate investigation is required to validate the legitimacy of the IP addition.
Show query
`o365_management_activity` Operation="Set Company Information." ModifiedProperties{}.Name=StrongAuthenticationPolicy | rex max_match=100 field=ModifiedProperties{}.NewValue "(?<ip_addresses_new_added>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})" | rex max_match=100 field=ModifiedProperties{}.OldValue "(?<ip_addresses_old>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})" | eval ip_addresses_old=if(isnotnull(ip_addresses_old),ip_addresses_old,"0") | mvexpand ip_addresses_new_added | where isnull(mvfind(ip_addresses_old,ip_addresses_new_added)) | fillnull | stats count min(_time) as firstTime max(_time) as lastTime values(ip_addresses_old) as ip_addresses_old by signature dest user src vendor_account vendor_product ip_addresses_new_added | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_bypass_mfa_via_trusted_ip_filter`O365 Compliance Content Search Exported
The following analytic identifies when the results of a content search within the Office 365 Security and Compliance Center are exported. It uses the SearchExported operation from the SecurityComplianceCenter workload in the o365_management_activity data source. This activity is significant because exporting search results can involve sensitive or critical organizational data, potentially leading to data exfiltration. If confirmed malicious, an attacker could gain access to and exfiltrate sensitive information, posing a severe risk to the organization's data security and compliance posture.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation="SearchExported"
| rename user_id as user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
ExchangeLocations Query
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_compliance_content_search_exported_filter`O365 Compliance Content Search Started
The following analytic detects when a content search is initiated within the Office 365 Security and Compliance Center. It leverages the SearchCreated operation from the o365_management_activity logs under the SecurityComplianceCenter workload. This activity is significant as it may indicate an attempt to access sensitive organizational data, including emails and documents. If confirmed malicious, this could lead to unauthorized data access, potential data exfiltration, and compliance violations. Monitoring this behavior helps ensure the integrity and security of organizational data.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation=SearchCreated
| rename user_id as user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
ExchangeLocations Query
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_compliance_content_search_started_filter`O365 Concurrent Sessions From Different Ips
The following analytic identifies user sessions in Office 365 accessed from multiple IP addresses, indicating potential adversary-in-the-middle (AiTM) phishing attacks. It detects this activity by analyzing Azure Active Directory logs for 'UserLoggedIn' operations and flags sessions with more than one associated IP address. This behavior is significant as it suggests unauthorized concurrent access, which is uncommon in normal usage. If confirmed malicious, the impact could include data theft, account takeover, and the launching of internal phishing campaigns, posing severe risks to organizational security.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation=UserLoggedIn
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime values(src) as src
BY signature dest user
vendor_account vendor_product SessionId
| where mvcount(src) > 1
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_concurrent_sessions_from_different_ips_filter`O365 Cross-Tenant Access Change
The following analytic identifies when cross-tenant access/synchronization policies are changed in an Azure tenant. Adversaries have been observed altering victim cross-tenant policies as a method of lateral movement or maintaining persistent access to compromised environments. These policies should be considered sensitive and monitored for changes and/or loose configuration.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation IN ("Add a partner to cross-tenant access setting.","Delete partner specific cross-tenant access setting.") | eval user = case(match(mvindex('Actor{}.ID',-1),"User"),mvindex('Actor{}.ID',0),match(mvindex('Actor{}.ID',-1),"ServicePrincipal"),mvindex('Actor{}.ID',3),true(),mvindex('Actor{}.ID',0)) | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by dest user src vendor_account vendor_product signature signature_id | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_cross_tenant_access_change_filter`O365 DLP Rule Triggered
The following analytic detects when Microsoft Office 365 Data Loss Prevention (DLP) rules have been triggered. DLP rules can be configured for any number of security, regulatory, or business compliance reasons, as such this analytic will only be as accurate as the upstream DLP configuration. Detections from this analytic should be evaluated thoroughly to de termine what, if any, security relevance the underlying DLP events contain.
Show query
`o365_management_activity` Operation=DLPRuleMatch | eval recipient = 'ExchangeMetaData.To{}', signature_id = 'ExchangeMetaData.UniqueID', signature = 'PolicyDetails{}.Rules{}.RuleName' , src_user = UserId, reason ='PolicyDetails{}.Rules{}.ConditionsMatched.SensitiveInformation{}.SensitiveInformationTypeName', result='PolicyDetails{}.Rules{}.Actions{}', file_name=case(NOT match('PolicyDetails{}.Rules{}.ConditionsMatched.SensitiveInformation{}.Location',"Message Body"),'PolicyDetails{}.Rules{}.ConditionsMatched.SensitiveInformation{}.Location') | fillnull | stats count min(_time) as firstTime max(_time) as lastTime values(signature) as signature values(file_name) as file_name values(ExchangeMetaData.Subject) AS subject values(Workload) as app values(result) as result by action dest user src vendor_account vendor_product src_user recipient signature_id reason | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_dlp_rule_triggered_filter` O365 Disable MFA
The following analytic identifies instances where Multi-Factor Authentication (MFA) is disabled for a user within the Office 365 environment. It leverages O365 audit logs, specifically focusing on events related to MFA settings. Disabling MFA removes a critical security layer, making accounts more vulnerable to unauthorized access. If confirmed malicious, this activity could indicate an attacker attempting to maintain persistence or an insider threat, significantly increasing the risk of unauthorized access. Immediate investigation is required to validate the reason for disabling MFA, potentially re-enable it, and assess any other suspicious activities related to the affected account.
Show query
`o365_management_activity` Operation="Disable Strong Authentication."
| rename UserId as user object as src_user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
src_user
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_disable_mfa_filter`O365 Elevated Mailbox Permission Assigned
The following analytic identifies the assignment of elevated mailbox permissions in an Office 365 environment via the Add-MailboxPermission operation. It leverages logs from the Exchange workload in the o365_management_activity data source, focusing on permissions such as FullAccess, ChangePermission, or ChangeOwner. This activity is significant as it indicates potential unauthorized access or control over mailboxes, which could lead to data exfiltration or privilege escalation. If confirmed malicious, attackers could gain extensive access to sensitive email data and potentially manipulate mailbox settings, posing a severe security risk.
Show query
`o365_management_activity` Workload=Exchange Operation=Add-MailboxPermission (AccessRights=FullAccess OR AccessRights=ChangePermission OR AccessRights=ChangeOwner)
| rename Identity AS dest_user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
dest_user
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_elevated_mailbox_permission_assigned_filter`O365 Email Access By Security Administrator
The following analytic identifies when a user with sufficient access to O365 Security & Compliance portal uses premium investigation features (Threat Explorer) to directly view email. Adversaries may exploit privileged access with this premium feature to enumerate or exfiltrate sensitive data.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation=AdminMailAccess
| rename InternetMessageId as signature_id, UserId as src_user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY signature dest user
src vendor_account vendor_product
src_user signature_id
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_access_by_security_administrator_filter`O365 Email Hard Delete Excessive Volume
The following analytic identifies when an O365 email account hard deletes an excessive number of emails within a short period (within 1 hour). This behavior may indicate a compromised account where the threat actor is attempting to permanently purge a large amount of items from the mailbox. Threat actors may attempt to remove evidence of their activity by purging items from the compromised mailbox. --- Some account owner legitimate behaviors can trigger this alert, however these actions may not be aligned with organizational expectations / best practice behaviors.
Show query
`o365_management_activity` Workload=Exchange (Operation IN ("HardDelete") AND Folder.Path IN ("\\Sent Items","\\Recoverable Items\\Deletions"))
| eval user = lower(UserId), sender = lower(CASE(isnotnull(SendAsUserSmtp),SendAsUserSmtp,isnotnull(SendOnBehalfOfUserSmtp),SendOnBehalfOfUserSmtp,true(),MailboxOwnerUPN)), subject = trim(CASE(Operation IN ("Send","SendAs","SendOnBehalf"),'Item.Subject',Operation IN ("SoftDelete","HardDelete"),'AffectedItems{}.Subject')), -time = _time,file_name = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),split('Item.Attachments',"; "),Operation IN ("SoftDelete","HardDelete"),split('AffectedItems{}.Attachments',"; ")), file_size = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),round(tonumber('Item.SizeInBytes')/1024/1024,2),true(),round(tonumber(replace(file_name, "(.+)\s\((\d+)(b\)$)", "\2"))/1024/1024,2))
| bin _time span=1hr
| stats values(sender) as sender, values(ClientIPAddress) as src, values(ClientInfoString) as http_user_agent, values(Operation) as signature, latest(file_name) as file_name, sum(file_size) as file_size, values(Folder.Path) as file_path, min(-time) as firstTime, max(-time) as lastTime, dc(subject) as count by _time,user
| where count > 50 OR file_size > 10
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_hard_delete_excessive_volume_filter`O365 Email New Inbox Rule Created
The following analytic identifies the creation of new email inbox rules in an Office 365 environment. It detects events logged under New-InboxRule and Set-InboxRule operations within the o365_management_activity data source, focusing on parameters that may indicate mail forwarding, removal, or obfuscation. Inbox rule creation is a typical end-user activity however attackers also leverage this technique for multiple reasons.
Show query
`o365_management_activity` Workload=Exchange AND (Operation=New-InboxRule OR Operation=Set-InboxRule) Parameters{}.Name IN (SoftDeleteMessage,DeleteMessage,ForwardTo,ForwardAsAttachmentTo,RedirectTo,MoveToFolder,CopyToFolder)
| eval file_path = mvappend(MoveToFolder,CopyToFolder), recipient=mvappend(ForwardTo, ForwardAsAttachmentTo, RedirectTo), user = lower(UserId), signature = Operation, src = if(match(ClientIP, "^\["), ltrim(mvindex(split(ClientIP, "]:"), 0), "["), mvindex(split(ClientIP,":"),0)), desc = Name, action = 'Parameters{}.Name'
| stats values(action) as action, values(src) as src, values(recipient) as recipient, values(file_path) as file_path, count, min(_time) as firstTime, max(_time) as lastTime by user, signature, desc
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_new_inbox_rule_created_filter`O365 Email Password and Payroll Compromise Behavior
The following analytic identifies when an O365 email recipient receives and then deletes emails for the combination of both password and banking/payroll changes within a short period. This behavior may indicate a compromised account where the threat actor is attempting to redirect the victims payroll to an attacker controlled bank account.
Show query
`o365_messagetrace` subject IN ("*banking*","*direct deposit*","*pay-to*","*password *","*passcode *","*OTP *","*MFA *","*Account Recovery*")
| eval mailtime = _time
| bin _time span=4hr
| eval user = lower(RecipientAddress)
| eval InternetMessageId = lower(MessageId)
| join InternetMessageId, user max=0
[
| search `o365_management_activity` Workload=Exchange Operation IN ("SoftDelete","HardDelete")
| spath path=AffectedItems{} output=AffectedItemSplit
| fields _time,ClientIP,ClientInfoString,UserId,Operation,ResultStatus,MailboxOwnerUPN,AffectedItemSplit
| mvexpand AffectedItemSplit | spath input=AffectedItemSplit
| search Subject IN ("*banking*","*direct deposit*","*pay-to*","*password *","*passcode *","*OTP *","*MFA *","*Account Recovery*")
| eval deltime = _time
| bin _time span=4hr
| eval InternetMessageId = lower(InternetMessageId), user = lower(UserId)
]
| stats values(ClientInfoString) as http_user_agent, values(ClientIP) as src, values(Subject) as subject, dc(Subject) as subject_count, values(Operation) as action, values(ResultStatus) as result, count, min(mailtime) as firstTime, max(deltime) as lastTime by user,_time
| search subject IN ("*banking*","*direct deposit*","*pay-to*") AND subject IN ("*password *","*passcode *","*OTP *","*MFA *","*Account Recovery*")
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_password_and_payroll_compromise_behavior_filter`O365 Email Receive and Hard Delete Takeover Behavior
The following analytic identifies when an O365 email recipient receives and then deletes emails related to password or banking/payroll changes within a short period. This behavior may indicate a compromised account where the threat actor is attempting to redirect the victims payroll to an attacker controlled bank account.
Show query
`o365_messagetrace` subject IN ("*banking*","*direct deposit*","*pay-to*","*password *","*passcode *","*OTP *","*MFA *","*Account Recovery*")
| eval mailtime = _time
| bin _time span=4hr
| eval user = lower(RecipientAddress)
| eval InternetMessageId = lower(MessageId)
| join InternetMessageId, user max=0
[
| search `o365_management_activity` Workload=Exchange Operation IN ("HardDelete") AND Folder.Path IN ("\\Sent Items","\\Recoverable Items\\Deletions")
| spath path=AffectedItems{} output=AffectedItemSplit
| fields _time,ClientProcessName,ClientIPAddress,ClientInfoString,UserId,Operation,ResultStatus,MailboxOwnerUPN,AffectedItemSplit,Folder.Path
| mvexpand AffectedItemSplit | spath input=AffectedItemSplit
| search Subject IN ("*banking*","*direct deposit*","*pay-to*","*password *","*passcode *","*OTP *","*MFA *","*Account Recovery*")
| eval deltime = _time
| bin _time span=4hr
| eval InternetMessageId = lower(InternetMessageId), user = lower(UserId), subject = Subject
]
| stats values(ClientIPAddress) as src, values(ClientInfoString) as http_user_agent, values(Folder.Path) as file_path, values(Operation) as signature, values(ResultStatus) as result, values(InternetMessageId) as signature_id, count, min(mailtime) as firstTime, max(deltime) as lastTime by user,subject
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_receive_and_hard_delete_takeover_behavior_filter`O365 Email Reported By Admin Found Malicious
The following analytic detects when an email manually submitted to Microsoft through the Security & Compliance portal is found to be malicious. This capability is an enhanced protection feature that can be used within o365 tenants by administrative users to report potentially malicious emails. This correlation looks for any submission that returns a Phish or Malware verdict upon submission.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation=AdminSubmission
| search RescanVerdict IN (Phish,Malware)
| rename Id as signature_id, SenderIP as src, Recipients{} as dest_user, P1Sender as src_user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product signature
signature_id dest_user src_user
Subject SubmissionContent
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_reported_by_admin_found_malicious_filter`O365 Email Reported By User Found Malicious
The following analytic detects when an email submitted to Microsoft using the built-in report button in Outlook is found to be malicious. This capability is an enhanced protection feature that can be used within o365 tenants by users to report potentially malicious emails. This correlation looks for any submission that returns a Phish or Malware verdict upon submission.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation=AlertEntityGenerated Name="Email reported by user as*"
| fromjson Data
| rename _raw AS temp etps AS _raw
| extract pairdelim=";" kvdelim=":"
| rename _raw AS etps temp AS _raw
| search RescanVerdict IN (Phish,Malware)
| rex field=tsd "\<(?<src_user>.+)\>"
| eval src_user = case(isnull(src_user),tsd,true(),src_user)
| rename Name as signature, AlertId as signature_id, AlertEntityId as user, tsd as sender, ms as subject
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product signature
signature_id src_user sender
subject
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_reported_by_user_found_malicious_filter`O365 Email Security Feature Changed
The following analytic identifies when specific O365 advanced security settings are altered within the Office 365 tenant. If an attacker successfully disables O365 security settings, they can operate within the tenant with reduced risk of detection. This can lead to unauthorized data access, data exfiltration, account compromise, or other malicious activities without leaving a detailed audit trail.
Show query
`o365_management_activity` Workload=Exchange AND Operation IN ("Set-*","Disable-*","New-*","Remove-*") Operation IN ("*AntiPhish*","*SafeLink*","*SafeAttachment*","*Malware*")
| rename Id as object_id, UserId as user, Operation as signature, ObjectId as object
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product signature
object_id object
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_security_feature_changed_filter`O365 Email Send Attachments Excessive Volume
The following analytic identifies when an O365 email account sends an excessive number of email attachments to external recipients within a short period (within 1 hour). This behavior may indicate a compromised account where the threat actor is attempting to exfiltrate data from the mailbox. Threat actors may attempt to transfer data through email as a simple means of exfiltration from the compromised mailbox. Some account owner legitimate behaviors can trigger this alert, however these actions may not be aligned with organizational expectations / best practice behaviors.
Show query
`o365_messagetrace` Status=Delivered
| eval mailtime = _time
| bin _time span=1hr
| eval user = lower(SenderAddress), recipient = lower(RecipientAddress)
| eval InternetMessageId = lower(MessageId)
| join InternetMessageId, user, _time max=0
[
| search `o365_management_activity` Workload=Exchange Operation IN ("Send","SendAs","SendOnBehalf")
| eval user = lower(UserId), sender = lower(CASE(isnotnull(SendAsUserSmtp),SendAsUserSmtp,isnotnull(SendOnBehalfOfUserSmtp),SendOnBehalfOfUserSmtp,true(),MailboxOwnerUPN)), subject = trim(CASE(Operation IN ("Send","SendAs","SendOnBehalf"),'Item.Subject',Operation IN ("SoftDelete","HardDelete"),'AffectedItems{}.Subject')), -time = _time,file_name = trim(CASE(Operation IN ("Send","SendAs","SendOnBehalf"),split('Item.Attachments',"; "),Operation IN ("SoftDelete","HardDelete"),split('AffectedItems{}.Attachments',"; "))), file_size = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),round(tonumber('Item.SizeInBytes')/1024/1024,2),true(),round(tonumber(replace(file_name, "(.+)\s\((\d+)(b\)$)", "\2"))/1024/1024,2)), InternetMessageId = lower('Item.InternetMessageId')
| bin _time span=1hr
| eval file_name = mvfilter(NOT match(file_name, "\.jpg |\.png |\.jpeg |\.gif "))
| search file_name=*
| stats values(sender) as sender, values(ClientIPAddress) as src, values(ClientInfoString) as http_user_agent, values(Operation) as signature, values(file_name) as file_name, sum(file_size) as file_size, values(Folder.Path) as file_path, min(-time) as firstTime, max(-time) as lastTime, dc(file_name) as count by _time,user,InternetMessageId
| where count > 25
| eval file_name = mvjoin(file_name,"||")
]
| eval file_name = split(file_name,"||")
| stats values(sender) as sender, values(recipient) as recipient, values(http_user_agent) as http_user_agent, values(signature) as signature, values(file_name) as file_name, max(file_size) as file_size, min(firstTime) as firstTime, max(lastTime) as lastTime max(count) as count by subject,user,Organization,InternetMessageId
| eval recipient = mvmap(recipient, if(match(mvindex(split(lower(recipient),"@"),1),mvindex(split(lower(user),"@"),1)), null(),recipient))
| search recipient = *
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_send_attachments_excessive_volume_filter`O365 Email Send and Hard Delete Exfiltration Behavior
The following analytic identifies when an O365 email account sends and then hard deletes an email to an external recipient within a short period (within 1 hour). This behavior may indicate a compromised account where the threat actor is attempting to remove forensic artifacts or evidence of exfiltration activity. This behavior is often seen when threat actors want to reduce the probability of detection by the compromised account owner.
Show query
`o365_messagetrace` Status=Delivered
| eval mailtime = _time
| bin _time span=1hr
| eval user = lower(SenderAddress), recipient = lower(RecipientAddress)
| eval InternetMessageId = lower(MessageId)
| join InternetMessageId, user, max=0
[
| search `o365_management_activity` Workload=Exchange (Operation IN ("Send*")) OR (Operation IN ("HardDelete") AND Folder.Path IN ("\\Sent Items","\\Recoverable Items\\Deletions"))
| eval user = lower(UserId), sender = lower(CASE(isnotnull(SendAsUserSmtp),SendAsUserSmtp,isnotnull(SendOnBehalfOfUserSmtp),SendOnBehalfOfUserSmtp,true(),MailboxOwnerUPN)), subject = trim(CASE(Operation IN ("Send","SendAs","SendOnBehalf"),'Item.Subject',Operation IN ("SoftDelete","HardDelete"),'AffectedItems{}.Subject')), -time = _time,file_name = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),split('Item.Attachments',"; "),Operation IN ("SoftDelete","HardDelete"),split('AffectedItems{}.Attachments',"; ")), file_size = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),round(tonumber('Item.SizeInBytes')/1024/1024,2),true(),round(tonumber(replace(file_name, "(.+)\s\((\d+)(b\)$)", "\2"))/1024/1024,2)), InternetMessageId = lower('Item.InternetMessageId')
| eval sendtime = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),_time)
| eval deltime = CASE(Operation IN ("SoftDelete","HardDelete"),_time)
| bin _time span=1hr
| stats values(sender) as sender, values(ClientInfoString) as http_user_agent, values(InternetMessageId) as InternetMessageId, values(file_name) as file_name, sum(file_size) as file_size, values(sendtime) as firstTime, values(deltime) as lastTime values(Operation) as signature, dc(Operation) as opcount, count by _time,subject,user
| where opcount > 1 AND firstTime < lastTime
]
| stats values(sender) as sender, values(http_user_agent) as http_user_agent, values(signature) as signature, values(file_name) as file_name, sum(file_size) as file_size, min(firstTime) as firstTime, max(lastTime) as lastTime count by subject,user,recipient,Organization
| eval externalRecipient = if(match(lower(recipient),mvindex(split(lower(Organization),"."),0)),0,1)
| where externalRecipient = 1
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_send_and_hard_delete_exfiltration_behavior_filter`O365 Email Send and Hard Delete Suspicious Behavior
The following analytic identifies when an O365 email account sends and then hard deletes email with within a short period (within 1 hour). This behavior may indicate a compromised account where the threat actor is attempting to remove forensic artifacts or evidence of activity. Threat actors often use this technique to prevent defenders and victims from knowing the account has been compromised. --- Some account owner legitimate behaviors can trigger this alert, however these actions may not be aligned with organizational expectations / best practice behaviors.
Show query
`o365_management_activity` Workload=Exchange (Operation IN ("Send*")) OR (Operation IN ("HardDelete") AND Folder.Path IN ("\\Sent Items","\\Recoverable Items\\Deletions"))
| eval user = lower(UserId), sender = lower(CASE(isnotnull(SendAsUserSmtp),SendAsUserSmtp,isnotnull(SendOnBehalfOfUserSmtp),SendOnBehalfOfUserSmtp,true(),MailboxOwnerUPN)), subject = trim(CASE(Operation IN ("Send","SendAs","SendOnBehalf"),'Item.Subject',Operation IN ("SoftDelete","HardDelete"),'AffectedItems{}.Subject')), -time = _time,file_name = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),split('Item.Attachments',"; "),Operation IN ("SoftDelete","HardDelete"),split('AffectedItems{}.Attachments',"; ")), file_size = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),round(tonumber('Item.SizeInBytes')/1024/1024,2),true(),round(tonumber(replace(file_name, "(.+)\s\((\d+)(b\)$)", "\2"))/1024/1024,2))
| eval sendtime = CASE(Operation IN ("Send","SendAs","SendOnBehalf"),_time)
| eval deltime = CASE(Operation IN ("SoftDelete","HardDelete"),_time)
| stats values(sender) as sender, values(ClientIPAddress) as src, values(ClientInfoString) as http_user_agent, values(Operation) as signature, values(file_name) as file_name, sum(file_size) as file_size, values(Folder.Path) as file_path, min(sendtime) as firstTime, max(deltime) as lastTime, dc(Operation) as opcount, count by subject,user
| eval timediff = tonumber(lastTime) - tonumber(firstTime)
| where opcount > 1 AND firstTime < lastTime AND timediff < 3600
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_send_and_hard_delete_suspicious_behavior_filter`O365 Email Suspicious Behavior Alert
The following analytic identifies when one of O365 the built-in security detections for suspicious email behaviors are triggered. These alerts often indicate that an attacker may have compromised a mailbox within the environment. Any detections from built-in Office 365 capabilities should be monitored and responded to appropriately. Certain premium Office 365 capabilities further enhance these detection and response functions.
Show query
`o365_management_activity` Workload=SecurityComplianceCenter Operation=AlertEntityGenerated Name IN ("Suspicious email sending patterns detected","User restricted from sending email","Suspicious Email Forwarding Activity","Email sending limit exceeded")
| fromjson Data
| rename Name as signature, AlertId as signature_id, ObjectId as user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
BY dest user src
vendor_account vendor_product signature
signature_id
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_suspicious_behavior_alert_filter`O365 Email Suspicious Search Behavior
The following analytic identifies when Office 365 users search for suspicious keywords or have an excessive number of queries to a mailbox within a limited timeframe. This behavior may indicate that a malicious actor has gained control of a mailbox and is conducting discovery or enumeration activities.
Show query
`o365_management_activity` Operation=SearchQueryInitiatedExchange | eval command = case(Operation=="SearchQueryPerformed",SearchQueryText,true(),QueryText), UserId = lower(UserId), signature_id = CorrelationId, signature=Operation, src = ClientIP, user = lower(UserId), object_name=case(Operation=="SearchQueryPerformed",'EventData',true(),QuerySource), -time = _time, suspect_terms = case(match(command, `o365_suspect_search_terms_regex`),command,true(),null()) | where command != "*" AND command != "(*)" | bin _time span=1hr | stats values(ScenarioName) as app, values(object_name) as object_name values(command) as command, values(suspect_terms) as suspect_terms, values(src) as src, dc(suspect_terms) as suspect_terms_count, dc(command) as count, min(-time) as firstTime, max(-time) as lastTime by user,signature,_time | where count > 20 OR suspect_terms_count >= 2 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_email_suspicious_search_behavior_filter`
O365 Email Transport Rule Changed
The following analytic identifies when a user with sufficient access to Exchange Online alters the mail flow/transport rule configuration of the organization. Transport rules are a set of rules that can be used by attackers to modify or delete emails based on specific conditions, this activity could indicate an attacker hiding or exfiltrated data.
Show query
`o365_management_activity` Workload=Exchange AND Operation IN ("Set-*","Disable-*","New-*","Remove-*") AND Operation="*TransportRule"
| eval object_name = case('Parameters{}.Name'=="Name",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Name$")),true(),ObjectId), object_id = case('Parameters{}.Name'=="Identity",mvindex('Parameters{}.Value',mvfind('Parameters{}.Name',"^Identity$")),true(),Id)
| stats values(object_name) as object_name, min(_time) as firstTime, max(_time) as lastTime, count by object_id, UserId, Operation, signature
| rename UserId as user
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_email_transport_rule_changed_filter`O365 Excessive Authentication Failures Alert
The following analytic identifies an excessive number of authentication failures, including failed attempts against MFA prompt codes. It uses data from the `o365_management_activity` dataset, focusing on events where the authentication status is marked as failure. This behavior is significant as it may indicate a brute force attack or an attempt to compromise user accounts. If confirmed malicious, this activity could lead to unauthorized access, data breaches, or further exploitation within the environment.
Show query
`o365_management_activity` Workload=AzureActiveDirectory UserAuthenticationMethod=* status=failure
| stats count earliest(_time) AS firstTime latest(_time) AS lastTime values(UserAuthenticationMethod) AS UserAuthenticationMethod values(UserAgent) AS user_agent values(status) AS status values(src_ip) AS src values(signature) as signature
BY user vendor_account vendor_product
dest
| where count > 10
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_excessive_authentication_failures_alert_filter`O365 Excessive SSO logon errors
The following analytic detects accounts experiencing a high number of Single Sign-On (SSO) logon errors. It leverages data from the `o365_management_activity` dataset, focusing on failed user login attempts with SSO errors. This activity is significant as it may indicate brute-force attempts or the hijacking/reuse of SSO tokens. If confirmed malicious, attackers could potentially gain unauthorized access to user accounts, leading to data breaches, privilege escalation, or further lateral movement within the organization.
Show query
`o365_management_activity` Workload=AzureActiveDirectory LogonError=*Sso* Operation=UserLoginFailed
| stats count min(_time) as firstTime max(_time) as lastTime values(user) as user
BY src vendor_account vendor_product
dest signature user_agent
| where count >= 5
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_excessive_sso_logon_errors_filter`O365 Exfiltration via File Access
The following analytic detects when an excessive number of files are access from o365 by the same user over a short period of time. A malicious actor may abuse the "open in app" functionality of SharePoint through scripted or Graph API based access to evade triggering the FileDownloaded Event. This behavior may indicate an attacker staging data for exfiltration or an insider threat removing organizational data. Additional attention should be take with any Azure Guest (#EXT#) accounts.
Show query
`o365_management_activity` Operation IN ("fileaccessed") UserId!=app@sharepoint NOT SourceFileExtension IN (bmp,png,jpeg,jpg)
| eval user = replace(mvindex(split(lower(UserId),"#ext#"),0),"_","@"), user_flat = replace(UserId, "[^A-Za-z0-9]","_")
| where NOT match(SiteUrl,user_flat)
| stats values(user) as user, latest(ClientIP) as src values(ZipFileName) as file_name, values(Operation) as signature, values(UserAgent) as http_user_agent, dc(SourceFileName) as count, min(_time) as firstTime, max(_time) as lastTime by Workload,UserId,SiteUrl
| eventstats avg(count) as avg stdev(count) as stdev by Workload
| rename SiteUrl as file_path,Workload as app
| where count > 50 AND count > (avg + (3*(stdev)))
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_exfiltration_via_file_access_filter`O365 Exfiltration via File Download
The following analytic detects when an excessive number of files are downloaded from o365 by the same user over a short period of time. O365 may bundle these files together as a ZIP file, however each file will have it's own download event. This behavior may indicate an attacker staging data for exfiltration or an insider threat removing organizational data. Additional attention should be taken with any Azure Guest (#EXT#) accounts.
Show query
`o365_management_activity` Operation IN ("filedownloaded")
| eval user = replace(mvindex(split(lower(UserId),"#ext#"),0),"_","@"), user_flat = replace(UserId, "[^A-Za-z0-9]","_")
| stats values(user) as user, latest(ClientIP) as src values(ZipFileName) as file_name, values(Operation) as signature, values(UserAgent) as http_user_agent, dc(SourceFileName) as count, min(_time) as firstTime, max(_time) as lastTime by Workload,UserId,SiteUrl
| rename SiteUrl as file_path,Workload as app
| where count > 50
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_exfiltration_via_file_download_filter`O365 Exfiltration via File Sync Download
The following analytic detects when an excessive number of files are sync from o365 by the same user over a short period of time. A malicious actor abuse the user-agent string through GUI or API access to evade triggering the FileDownloaded event. This behavior may indicate an attacker staging data for exfiltration or an insider threat removing organizational data. Additional attention should be taken with any Azure Guest (#EXT#) accounts.
Show query
`o365_management_activity` Operation IN ("filesyncdownload*") UserAgent="*SkyDriveSync*"
| eval user = replace(mvindex(split(lower(UserId),"#ext#"),0),"_","@"), user_flat = replace(UserId, "[^A-Za-z0-9]","_")
| where NOT match(SiteUrl,user_flat)
| stats values(user) as user, latest(ClientIP) as src values(ZipFileName) as file_name, values(Operation) as signature, values(UserAgent) as http_user_agent, dc(SourceFileName) as count, min(_time) as firstTime, max(_time) as lastTime by Workload,UserId,SiteUrl
| rename SiteUrl as file_path,Workload as app
| where count > 50
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_exfiltration_via_file_sync_download_filter`O365 External Guest User Invited
The following analytic identifies the invitation of an external guest user within Azure AD. With Azure AD B2B collaboration, users and administrators can invite external users to collaborate with internal users. External guest account invitations should be monitored by security teams as they could potentially lead to unauthorized access. An example of this attack vector was described at BlackHat 2022 by security researcher Dirk-Jan during his tall `Backdooring and Hijacking Azure AD Accounts by Abusing External Identities`. This detection leverages the Universal Audit Log (UAL)/o365:management:activity sourcetype as a detection data source.
Show query
`o365_management_activity` Workload=AzureActiveDirectory AND Operation="Add user*" AND ModifiedProperties{}.NewValue="[*Guest*]" AND ModifiedProperties{}.NewValue="[*Invitation*]" | eval user = (mvindex('ModifiedProperties{}.NewValue',5)), src_user = case(match(mvindex('Actor{}.ID',-1),"User"),mvindex('Actor{}.ID',0),match(mvindex('Actor{}.ID',-1),"ServicePrincipal"),mvindex('Actor{}.ID',3),true(),mvindex('Actor{}.ID',0)) | rex field=user "(?<user> [ \w\.-]+@ [ \w-]+\. [ \w-]{2,4})" | rename Operation as signature, Id as signature_id | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by dest user src vendor_account vendor_product signature signature_id src_user | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_external_guest_user_invited_filter`O365 External Identity Policy Changed
The following analytic identifies when changes are made to the external guest policies within Azure AD. With Azure AD B2B collaboration, users and administrators can invite external users to collaborate with internal users. This detection also attempts to highlight what may have changed. External guest account invitations should be monitored by security teams as they could potentially lead to unauthorized access. An example of this attack vector was described at BlackHat 2022 by security researcher Dirk-Jan during his tall `Backdooring and Hijacking Azure AD Accounts by Abusing External Identities`.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Update policy." Target{}.ID="B2BManagementPolicy" | eval object_attrs = mvindex('ModifiedProperties{}.NewValue',0), object_attrs_old = mvindex('ModifiedProperties{}.OldValue',0), object_name = mvindex('Target{}.ID',3), signature=Operation, user = case(match(mvindex('Actor{}.ID',-1),"User"),mvindex('Actor{}.ID',0),match(mvindex('Actor{}.ID',-1),"ServicePrincipal"), mvindex('Actor{}.ID',3),true(),mvindex('Actor{}.ID',0)) | spath input=object_attrs_old output=B2BOld path={} | spath input=B2BOld | rename B2BManagementPolicy.* as B2BManagementPolicyOld.* | spath input=object_attrs output=B2BNew path={} | spath input=B2BNew | eval object_attrs = 'B2BManagementPolicy.InvitationsAllowedAndBlockedDomainsPolicy.AllowedDomains{}' , object_attrs_old = 'B2BManagementPolicyOld.InvitationsAllowedAndBlockedDomainsPolicy.AllowedDomains{}' | eval diff_add=mvmap(object_attrs,if(isnull(mvfind(object_attrs_old,object_attrs)),object_attrs,null)) | eval diff_remove=mvmap(object_attrs_old,if(isnull(mvfind(object_attrs,object_attrs_old)),object_attrs_old,null)) | eval result = case(isnotnull(diff_add),"Added ".mvjoin(diff_add,","),isnotnull(diff_remove),"Removed ".mvjoin(diff_remove,",")), action = case(isnotnull(diff_add),"created",isnotnull(diff_remove),"deleted") | stats values(object_attrs) as object_attrs, values(action) as action, values(result) as result, values(B2BManagementPolicy*) as B2BManagementPolicy*, count, min(_time) as firstTime, max(_time) as lastTime by user signature object_name dest vendor_account vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_external_identity_policy_changed_filter`O365 File Permissioned Application Consent Granted by User
The following analytic identifies instances where a user in the Office 365 environment grants consent to an application requesting file permissions for OneDrive or SharePoint. It leverages O365 audit logs, focusing on OAuth application consent events. This activity is significant because granting such permissions can allow applications to access, modify, or delete files, posing a risk if the application is malicious or overly permissive. If confirmed malicious, this could lead to data breaches, data loss, or unauthorized data manipulation, necessitating immediate investigation to validate the application's legitimacy and assess potential risks.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Consent to application." ResultStatus=Success | eval admin_consent =mvindex('ModifiedProperties{}.NewValue',0) | search admin_consent=False | eval permissions =mvindex('ModifiedProperties{}.NewValue',4) | rex field=permissions "Scope:(?<Scope>[^,]+)" | makemv delim=" " Scope | search Scope IN ("Files.Read", "Files.Read.All", "Files.ReadWrite", "Files.ReadWrite.All", "Files.ReadWrite.AppFolder") | fillnull | stats count min(_time) as firstTime max(_time) as lastTime values(Scope) as Scope by signature dest user src vendor_account vendor_product object ObjectId | `security_content_ctime(lastTime)` | `o365_file_permissioned_application_consent_granted_by_user_filter`O365 FullAccessAsApp Permission Assigned
The following analytic detects the assignment of the 'full_access_as_app' permission to an application registration in Office 365 Exchange Online. This detection leverages Office 365 management activity logs and filters Azure Active Directory workload events to identify when the specific permission, identified by GUID 'dc890d15-9560-4a4c-9b7f-a736ec74ec40', is granted. This activity is significant because it provides extensive control over Office 365 operations, including access to all mailboxes and the ability to send mail as any user. If confirmed malicious, this could lead to unauthorized data access, exfiltration, or account compromise. Immediate investigation is required.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Update application." | eval newvalue = mvindex('ModifiedProperties{}.NewValue',0) | spath input=newvalue | search "{}.ResourceAppId"="00000002-0000-0ff1-ce00-000000000000""{}.RequiredAppPermissions{}.EntitlementId"="dc890d15-9560-4a4c-9b7f-a736ec74ec40" | eval Permissions = '{}.RequiredAppPermissions{}.EntitlementId' | fillnull | stats count min(_time) as firstTime max(_time) as lastTime values(Scope) as Scope by signature dest user src vendor_account vendor_product object user_agent | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_fullaccessasapp_permission_assigned_filter`O365 High Number Of Failed Authentications for User
The following analytic identifies an O365 account experiencing more than 20 failed authentication attempts within 5 minutes. It uses O365 Unified Audit Logs, specifically "UserLoginFailed" events, to monitor and flag accounts exceeding this threshold. This activity is significant as it may indicate a brute force attack or password guessing attempt. If confirmed malicious, an attacker could gain unauthorized access to the O365 environment, potentially compromising sensitive emails, documents, and other data. Prompt investigation and action are crucial to prevent unauthorized access and data breaches.
Show query
`o365_management_activity` Operation=UserLoginFailed record_type=AzureActiveDirectoryStsLogon Workload=AzureActiveDirectory
| bucket span=5m _time
| fillnull
| stats dc(_raw) AS failed_attempts values(src_ip) as src
BY signature user _time
dest vendor_account vendor_product
| where failed_attempts > 10
| `o365_high_number_of_failed_authentications_for_user_filter`O365 High Privilege Role Granted
The following analytic detects when high-privilege roles such as "Exchange Administrator," "SharePoint Administrator," or "Global Administrator" are granted within Office 365. It leverages O365 audit logs to identify events where these roles are assigned to any user or service account. This activity is significant for SOCs as these roles provide extensive permissions, allowing broad access and control over critical resources and data. If confirmed malicious, this could enable attackers to gain significant control over O365 resources, access, modify, or delete critical data, and compromise the overall security and functionality of the O365 environment.
Show query
`o365_management_activity` Operation="Add member to role." Workload=AzureActiveDirectory | eval role_id = mvindex('ModifiedProperties{}.NewValue',2) | eval role_name = mvindex('ModifiedProperties{}.NewValue',1) | where role_id IN ("29232cdf-9323-42fd-ade2-1d097af3e4de", "f28a1f50-f6e7-4571-818b-6a12f2af6b6c", "62e90394-69f5-4237-9190-012177145e10") | fillnull | stats count min(_time) as firstTime max(_time) as lastTime by signature dest user src vendor_account vendor_product ObjectId role_name role_id | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_high_privilege_role_granted_filter`O365 Mail Permissioned Application Consent Granted by User
The following analytic identifies instances where a user grants consent to an application requesting mail-related permissions within the Office 365 environment. It leverages O365 audit logs, specifically focusing on events related to application permissions and user consent actions. This activity is significant as it can indicate potential security risks, such as data exfiltration or spear phishing, if malicious applications gain access. If confirmed malicious, this could lead to unauthorized data access, email forwarding, or sending malicious emails from the compromised account. Validating the legitimacy of the application and consent context is crucial to prevent data breaches.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Consent to application." ResultStatus=Success | eval admin_consent =mvindex('ModifiedProperties{}.NewValue',0) | search admin_consent=False | eval permissions =mvindex('ModifiedProperties{}.NewValue',4) | rex field=permissions "Scope:(?<Scope>[^,]+)" | makemv delim=" " Scope | search Scope IN ("Mail.Read", "Mail.ReadBasic", "Mail.ReadWrite", "Mail.Read.Shared", "Mail.ReadWrite.Shared", "Mail.Send", "Mail.Send.Shared") | fillnull | stats count min(_time) as firstTime max(_time) as lastTime values(Scope) as Scope by signature dest user src vendor_account vendor_product object ObjectId | `security_content_ctime(lastTime)` | `o365_mail_permissioned_application_consent_granted_by_user_filter`O365 Mailbox Email Forwarding Enabled
The following analytic identifies instances where email forwarding has been enabled on mailboxes within an Office 365 environment. It detects this activity by monitoring the Set-Mailbox operation within the o365_management_activity logs, specifically looking for changes to the ForwardingAddress or ForwardingSmtpAddress parameters. This activity is significant as unauthorized email forwarding can lead to data exfiltration and unauthorized access to sensitive information. If confirmed malicious, attackers could intercept and redirect emails, potentially compromising confidential communications and leading to data breaches.
Show query
`o365_management_activity` Operation=Set-Mailbox | eval match1=mvfind('Parameters{}.Name',"ForwardingAddress") | eval match2=mvfind('Parameters{}.Name', "ForwardingSmtpAddress") | where match1>= 0 OR match2>= 0 | eval ForwardTo=coalesce(ForwardingAddress,ForwardingSmtpAddress) | search ForwardTo!="" | rename user_id as user | stats count earliest(_time) as firstTime latest(_time) as lastTime values(ForwardTo) as ForwardTo by signature dest user src vendor_account vendor_product object ObjectId | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_mailbox_email_forwarding_enabled_filter`O365 Mailbox Folder Read Permission Assigned
The following analytic identifies instances where read permissions are assigned to mailbox folders within an Office 365 environment. It leverages the `o365_management_activity` data source, specifically monitoring the `ModifyFolderPermissions` and `AddFolderPermissions` operations, while excluding Calendar, Contacts, and PersonMetadata objects. This activity is significant as unauthorized read permissions can lead to data exposure and potential information leakage. If confirmed malicious, an attacker could gain unauthorized access to sensitive emails, leading to data breaches and compromising the confidentiality of organizational communications.
Show query
`o365_management_activity` Workload=Exchange (Operation=ModifyFolderPermissions OR Operation=AddFolderPermissions) Workload=Exchange object!=Calendar object!=Contacts object!=PersonMetadata | eval isReadRole=if(match('Item.ParentFolder.MemberRights',"(ReadAny)"), "true", "false") | rename UserId as user | stats count earliest(_time) as firstTime latest(_time) as lastTime by signature user object dest Item.ParentFolder.MemberUpn Item.ParentFolder.MemberRights src vendor_account vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_mailbox_folder_read_permission_assigned_filter`O365 Mailbox Folder Read Permission Granted
The following analytic identifies instances where read permissions are granted to mailbox folders within an Office 365 environment. It detects this activity by monitoring the `o365_management_activity` data source for the `Set-MailboxFolderPermission` and `Add-MailboxFolderPermission` operations. This behavior is significant as it may indicate unauthorized access or changes to mailbox folder permissions, potentially exposing sensitive email content. If confirmed malicious, an attacker could gain unauthorized access to read email communications, leading to data breaches or information leakage.
Show query
`o365_management_activity`
Workload=Exchange
Operation IN ("Set-MailboxFolderPermission", "Add-MailboxFolderPermission")
| eval isReadRole=if(match(AccessRights,"^(ReadItems|Author|NonEditingAuthor|Owner|PublishingAuthor|Reviewer)$"), "true", "false")
| search isReadRole="true"
| rename UserId as user
| fillnull
| stats count min(_time) as firstTime max(_time) as lastTime
by signature dest user src vendor_account
vendor_product Identity AccessRights
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_mailbox_folder_read_permission_granted_filter`O365 Mailbox Inbox Folder Shared with All Users
The following analytic detects instances where the inbox folder of an Office 365 mailbox is shared with all users within the tenant. It leverages Office 365 management activity events to identify when the 'Inbox' folder permissions are modified to include 'Everyone' with read rights. This activity is significant as it represents a potential security risk, allowing unauthorized access to sensitive emails. If confirmed malicious, this could lead to data breaches, exfiltration of confidential information, and further compromise through spear-phishing or other malicious activities based on the accessed email content.
Show query
`o365_management_activity` Operation=ModifyFolderPermissions Workload=Exchange object=Inbox Item.ParentFolder.MemberUpn=Everyone | eval isReadRole=if(match('Item.ParentFolder.MemberRights',"(ReadAny)"), "true", "false") | search isReadRole = "true" | rename UserId as user | fillnull | stats count earliest(_time) as firstTime latest(_time) as lastTime by signature, user, dest, vendor_account, vendor_product, object, MailboxOwnerUPN, Item.ParentFolder.MemberUpn, Item.ParentFolder.MemberRights, src | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_mailbox_inbox_folder_shared_with_all_users_filter`O365 Mailbox Read Access Granted to Application
The following analytic identifies instances where the Mail.Read Graph API permissions are granted to an application registration within an Office 365 tenant. It leverages O365 audit logs, specifically events related to changes in application permissions within the AzureActiveDirectory workload. This activity is significant because the Mail.Read permission allows applications to access and read all emails within a user's mailbox, which often contain sensitive or confidential information. If confirmed malicious, this could lead to data exfiltration, spear-phishing attacks, or further compromise based on the information gathered from the emails.
Show query
`o365_management_activity` Operation="Update application." | eval json_data=mvindex('ModifiedProperties{}.NewValue',0) | eval json_data=replace(json_data,"^\[\s*","") | eval json_data=replace(json_data,"\s*\]$","") | spath input=json_data path=RequiredAppPermissions{}.EntitlementId output=EntitlementIds | eval match_found=mvfind(EntitlementIds, "810c84a8-4a9e-49e6-bf7d-12d183f40d01") | where isnotnull(match_found) | fillnull | stats count earliest(_time) as firstTime max(_time) as lastTime values(EntitlementIds) as EntitlementIds by signature, user, dest, vendor_account, vendor_product, object, src | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_mailbox_read_access_granted_to_application_filter`O365 Multi-Source Failed Authentications Spike
The following analytic identifies a spike in failed authentication attempts within an Office 365 environment, indicative of a potential distributed password spraying attack. It leverages UserLoginFailed events from O365 Management Activity logs, focusing on ErrorNumber 50126. This detection is significant as it highlights attempts to bypass security controls using multiple IP addresses and user agents. If confirmed malicious, this activity could lead to unauthorized access, data breaches, privilege escalation, and lateral movement within the organization. Early detection is crucial to prevent account takeovers and mitigate subsequent threats.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation=UserLoginFailed ErrorNumber=50126
| bucket span=5m _time
| eval uniqueIPUserCombo = src_ip . "-" . user
| fillnull
| stats earliest(_time) as firstTime max(_time) as lastTime dc(uniqueIPUserCombo) as uniqueIpUserCombinations, dc(user) as uniqueUsers, dc(src_ip) as uniqueIPs, values(user) as user, values(src_ip) as ips, values(user_agent) as user_agents values(signature) as signature values(src) as src values(dest) as dest
BY _time vendor_account vendor_product
| where uniqueIpUserCombinations > 20 AND uniqueUsers > 20 AND uniqueIPs > 20
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `o365_multi_source_failed_authentications_spike_filter`O365 Multiple AppIDs and UserAgents Authentication Spike
The following analytic identifies unusual authentication activity in an O365 environment, where a single user account experiences more than 8 authentication attempts using 3 or more unique application IDs and over 5 unique user agents within a short timeframe. It leverages O365 audit logs, focusing on authentication events and applying statistical thresholds. This behavior is significant as it may indicate an adversary probing for multi-factor authentication weaknesses. If confirmed malicious, it suggests a compromised account, potentially leading to unauthorized access, privilege escalation, and data exfiltration. Early detection is crucial to prevent further exploitation.
Show query
`o365_management_activity` Workload=AzureActiveDirectory (Operation=UserLoggedIn OR Operation=UserLoginFailed)
| bucket span=5m _time
| stats dc(_raw) as failed_attempts dc(ApplicationId) as unique_app_ids dc(UserAgent) as unique_user_agents values(ApplicationId) values(OS) values(signature) as signature
BY _time user src
vendor_account vendor_product dest
| where failed_attempts > 5 and unique_user_agents > 5 and unique_app_ids > 2
| `o365_multiple_appids_and_useragents_authentication_spike_filter`O365 Multiple Failed MFA Requests For User
The following analytic identifies potential "MFA fatigue" attacks targeting Office 365 users by detecting more than nine Multi-Factor Authentication (MFA) prompts within a 10-minute timeframe. It leverages O365 management activity logs, focusing on Azure Active Directory events with the UserLoginFailed operation, a Success ResultStatus, and an ErrorNumber of 500121. This activity is significant as attackers may exploit MFA fatigue to gain unauthorized access by overwhelming users with repeated MFA requests. If confirmed malicious, this could lead to data breaches, unauthorized data access, or further compromise within the O365 environment. Immediate investigation is crucial.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation=UserLoginFailed ResultStatus=Success ErrorNumber=500121
| bucket span=10m _time
| stats dc(_raw) as mfa_prompts values(LogonError) as LogonError values(signature) as signature values(action) as action values(src) as src
BY user _time vendor_account
vendor_product dest
| where mfa_prompts > 9
| `o365_multiple_failed_mfa_requests_for_user_filter`O365 Multiple Mailboxes Accessed via API
The following analytic detects when a high number of Office 365 Exchange mailboxes are accessed via API (Microsoft Graph API or Exchange Web Services) within a short timeframe. It leverages 'MailItemsAccessed' operations in Exchange, using AppId and regex to identify API interactions. This activity is significant as it may indicate unauthorized mass email access, potentially signaling data exfiltration or account compromise. If confirmed malicious, attackers could gain access to sensitive information, leading to data breaches and further exploitation of compromised accounts. The threshold is set to flag over five unique mailboxes accessed within 10 minutes, but should be tailored to your environment.
Show query
`o365_management_activity` Workload=Exchange Operation=MailItemsAccessed AppId=* ClientAppId=*
| bucket span=10m _time
| eval matchRegex=if(match(ClientInfoString,"^Client=WebServices;ExchangeWebServices"), 1, 0)
| search (AppId="00000003-0000-0000-c000-000000000000" OR matchRegex=1)
| fillnull
| stats values(ClientIPAddress) as src dc(user) as unique_mailboxes values(user) as user
BY _time ClientAppId ClientInfoString
vendor_account vendor_product dest
signature
| where unique_mailboxes > 5
| `o365_multiple_mailboxes_accessed_via_api_filter`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.
Show query
`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`
O365 Multiple Service Principals Created by SP
The following analytic identifies instances where a single service principal creates more than three unique OAuth applications within a 10-minute timeframe. It leverages O365 logs from the Unified Audit Log, focusing on the 'Add service principal' operation in the Office 365 Azure Active Directory environment. This activity is significant as it may indicate a compromised or malicious service principal attempting to expand control or access within the network. If confirmed malicious, this could lead to unauthorized access and potential lateral movement within the environment, posing a significant security risk.
Show query
`o365_management_activity` Workload=AzureActiveDirectory Operation="Add service principal." | bucket span=10m _time | eval len=mvcount('Actor{}.ID') | eval userType = mvindex('Actor{}.ID',len-1) | search userType = "ServicePrincipal" | eval displayName = object | fillnull | stats count earliest(_time) as firstTime latest(_time) as lastTime values(displayName) as displayName dc(displayName) as unique_apps values(user) as user values(src) as src by src_user vendor_account vendor_product dest signature | where unique_apps > 3 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `o365_multiple_service_principals_created_by_sp_filter`Showing 951-1000 of 2,101