Detection rules › Kusto
Malicious BEC Inbox Rule
'Often times after the initial compromise in a BEC attack the attackers create inbox rules to delete emails that contain certain keywords related to their BEC attack. This is done so as to limit ability to warn compromised users that they've been compromised.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Stealth |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | Exchange audit operation New-InboxRule: Federated domain added |
Rules detecting the same action
These rules filter on the same operation.
- High risk Office operation conducted by IP Address that recently attempted to log into a disabled account (Kusto)
- Inbox Rules Creation Or Update Activity in O365 (Sigma)
- M365 Exchange Inbox Phishing Evasion Rule Created (Elastic)
- Mail Forwarding/Redirecting Activity In O365 (Sigma)
- O365 New Email Forwarding Rule Created (Splunk)
- Rare and potentially high-risk Office operations (Kusto)
Rule body
id: 8ac77493-3cae-4840-8634-15fb23f8fb68
name: Malicious BEC Inbox Rule
description: |
'Often times after the initial compromise in a BEC attack the attackers create inbox rules to delete emails that contain certain keywords related to their BEC attack.
This is done so as to limit ability to warn compromised users that they've been compromised.
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
- DefenseEvasion
relevantTechniques:
- T1098
- T1078
tags:
- BEC
query: |
let BEC_Keywords = dynamic([ 'invoice','payment','paycheck','transfer','bank statement','bank details','closing','funds','bank account','account details','remittance','purchase','deposit',"PO#","Zahlung","Rechnung","Paiement", "virement bancaire","Bankuberweisung",'hacked','phishing']);
OfficeActivity
| where Operation =~ "New-InboxRule"
| where Parameters has "Deleted Items" or Parameters has "Junk Email" or Parameters has "DeleteMessage"
| extend Events=todynamic(Parameters)
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
| where SubjectContainsWords has_any (BEC_Keywords)
or BodyContainsWords has_any (BEC_Keywords)
or SubjectOrBodyContainsWords has_any (BEC_Keywords)
| extend ClientIPAddress = case( ClientIP has ".", tostring(split(ClientIP,":")[0]), ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))), ClientIP )
| extend Keyword = iff(isnotempty(SubjectContainsWords), SubjectContainsWords, (iff(isnotempty(BodyContainsWords),BodyContainsWords,SubjectOrBodyContainsWords )))
| extend RuleDetail = case(OfficeObjectId contains '/' , tostring(split(OfficeObjectId, '/')[-1]) , tostring(split(OfficeObjectId, '\\')[-1]))
| summarize count(), StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by Operation, UserId, ClientIPAddress, ResultStatus, Keyword, OriginatingServer, OfficeObjectId, RuleDetail
| extend UserName = split(UserId, '@')[0], DomainName = split(UserId, '@')[1]
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserId
- identifier: Name
columnName: UserName
- identifier: UPNSuffix
columnName: DomainName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIPAddress
version: 1.0.2
kind: Scheduled
Stages and Predicates
Let binding: BEC_Keywords
let BEC_Keywords = dynamic([ 'invoice','payment','paycheck','transfer','bank statement','bank details','closing','funds','bank account','account details','remittance','purchase','deposit',"PO#","Zahlung","Rechnung","Paiement", "virement bancaire","Bankuberweisung",'hacked','phishing']);
Stage 1: source
OfficeActivity
Stage 2: where
| where Operation =~ "New-InboxRule"
Stage 3: where
| where Parameters has "Deleted Items" or Parameters has "Junk Email" or Parameters has "DeleteMessage"
Stage 4: extend
| extend Events=todynamic(Parameters)
Stage 5: parse
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
Stage 6: parse
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
Stage 7: parse
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
Stage 8: where
| where SubjectContainsWords has_any (BEC_Keywords)
or BodyContainsWords has_any (BEC_Keywords)
or SubjectOrBodyContainsWords has_any (BEC_Keywords)
Stage 9: extend (3 consecutive steps)
| extend ClientIPAddress = case( ClientIP has ".", tostring(split(ClientIP,":")[0]), ClientIP has "[", tostring(trim_start(@'[[]',tostring(split(ClientIP,"]")[0]))), ClientIP )
| extend Keyword = iff(isnotempty(SubjectContainsWords), SubjectContainsWords, (iff(isnotempty(BodyContainsWords),BodyContainsWords,SubjectOrBodyContainsWords )))
| extend RuleDetail = case(OfficeObjectId contains '/' , tostring(split(OfficeObjectId, '/')[-1]) , tostring(split(OfficeObjectId, '\\')[-1]))
ClientIPAddress =if
ClientIP has "."tostring(split(ClientIP, ":")[0])elif
ClientIP has "["tostring(trim_start(@'[[]', tostring(split(ClientIP, "]")[0])))else
ClientIPStage 10: summarize
| summarize count(), StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by Operation, UserId, ClientIPAddress, ResultStatus, Keyword, OriginatingServer, OfficeObjectId, RuleDetail
Stage 11: extend
| extend UserName = split(UserId, '@')[0], DomainName = split(UserId, '@')[1]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
BodyContainsWords | match |
| field:"BodyContainsWords" kind:match |
Operation | eq |
| field:"Operation" kind:eq value:"New-InboxRule" |
Parameters | match |
| field:"m365::Parameters" kind:match |
SubjectContainsWords | match |
| field:"SubjectContainsWords" kind:match |
SubjectOrBodyContainsWords | match |
| field:"SubjectOrBodyContainsWords" kind:match |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ClientIPAddress | summarize |
EndTimeUtc | summarize |
Keyword | summarize |
OfficeObjectId | summarize |
Operation | summarize |
OriginatingServer | summarize |
ResultStatus | summarize |
RuleDetail | summarize |
StartTimeUtc | summarize |
UserId | summarize |
DomainName | extend |
UserName | extend |