Malicious BEC Inbox Rule
Id | 8ac77493-3cae-4840-8634-15fb23f8fb68 |
Rulename | 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 |
Tactics | Persistence DefenseEvasion |
Techniques | T1098 T1078 |
Required data connectors | Office365 |
Kind | Scheduled |
Query frequency | 1d |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Business Email Compromise - Financial Fraud/Analytic Rules/BEC_MailboxRule.yaml |
Version | 1.0.2 |
Arm template | 8ac77493-3cae-4840-8634-15fb23f8fb68.json |
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]
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Business Email Compromise - Financial Fraud/Analytic Rules/BEC_MailboxRule.yaml
id: 8ac77493-3cae-4840-8634-15fb23f8fb68
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]
tags:
- BEC
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.
name: Malicious BEC Inbox Rule
relevantTechniques:
- T1098
- T1078
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserId
- identifier: Name
columnName: UserName
- identifier: UPNSuffix
columnName: DomainName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIPAddress
triggerThreshold: 0
severity: Medium
requiredDataConnectors:
- dataTypes:
- OfficeActivity
connectorId: Office365
queryFrequency: 1d
queryPeriod: 1d
version: 1.0.2
kind: Scheduled
tactics:
- Persistence
- DefenseEvasion
triggerOperator: gt
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/8ac77493-3cae-4840-8634-15fb23f8fb68')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/8ac77493-3cae-4840-8634-15fb23f8fb68')]",
"properties": {
"alertRuleTemplateName": "8ac77493-3cae-4840-8634-15fb23f8fb68",
"customDetails": null,
"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.\n This is done so as to limit ability to warn compromised users that they've been compromised. \n",
"displayName": "Malicious BEC Inbox Rule",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "UserId",
"identifier": "FullName"
},
{
"columnName": "UserName",
"identifier": "Name"
},
{
"columnName": "DomainName",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "ClientIPAddress",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Business Email Compromise - Financial Fraud/Analytic Rules/BEC_MailboxRule.yaml",
"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']);\nOfficeActivity\n| where Operation =~ \"New-InboxRule\"\n| where Parameters has \"Deleted Items\" or Parameters has \"Junk Email\" or Parameters has \"DeleteMessage\"\n| extend Events=todynamic(Parameters)\n| parse Events with * \"SubjectContainsWords\" SubjectContainsWords '}'*\n| parse Events with * \"BodyContainsWords\" BodyContainsWords '}'*\n| parse Events with * \"SubjectOrBodyContainsWords\" SubjectOrBodyContainsWords '}'*\n| where SubjectContainsWords has_any (BEC_Keywords)\n or BodyContainsWords has_any (BEC_Keywords)\n or SubjectOrBodyContainsWords has_any (BEC_Keywords)\n| extend ClientIPAddress = case( ClientIP has \".\", tostring(split(ClientIP,\":\")[0]), ClientIP has \"[\", tostring(trim_start(@'[[]',tostring(split(ClientIP,\"]\")[0]))), ClientIP )\n| extend Keyword = iff(isnotempty(SubjectContainsWords), SubjectContainsWords, (iff(isnotempty(BodyContainsWords),BodyContainsWords,SubjectOrBodyContainsWords )))\n| extend RuleDetail = case(OfficeObjectId contains '/' , tostring(split(OfficeObjectId, '/')[-1]) , tostring(split(OfficeObjectId, '\\\\')[-1]))\n| summarize count(), StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated) by Operation, UserId, ClientIPAddress, ResultStatus, Keyword, OriginatingServer, OfficeObjectId, RuleDetail\n| extend UserName = split(UserId, '@')[0], DomainName = split(UserId, '@')[1]\n",
"queryFrequency": "P1D",
"queryPeriod": "P1D",
"severity": "Medium",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"DefenseEvasion",
"Persistence"
],
"tags": [
"BEC"
],
"techniques": [
"T1078",
"T1098"
],
"templateVersion": "1.0.2",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}