10 MIN READ

Microsoft Sentinel: Malicious Inbox Rule V2

Microsoft Sentinel SIEM is a fantastic tool that enables you to keep an eye on any malicious activity occurring in Microsoft 365 tenants. I strongly suggest everyone to implement this tool as it is very affordable.

This improved Sentinel Analytics Rule can be used to detect malicious Inbox Rules used by threat actors to hide invoice fraud activity. I’ve used the Inbox rule currently available as a template within Sentinel, and modified it to alert on Outlook rules I encountered in the wild.

The changes I made were the Keyword and the removal of the limitations of the folder destinations. This is because I often see RSS, Conversation History or other folders being used. The “..” are often used as Inbox rule names.

The modified rule is on the left, and the original one is on the right.

<strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-colibri-color-1-color">let Keywords = dynamic(["..", "RSS", "Conversation", "History", ',,', '..', "MarkAsRead"]);</mark></strong>
OfficeActivity
| where Operation =~ "New-InboxRule"
| where Parameters has_any (Keywords)
| extend Events=todynamic(Parameters)
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
| 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,
   <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-colibri-color-1-color"> <strong>tostring(Events)</strong></mark>
| extend
    timestamp = StartTimeUtc,
    IPCustomEntity = ClientIPAddress,
    AccountCustomEntity = UserId,
    HostCustomEntity =  OriginatingServer
Code language: HTML, XML (xml)
<strong><s>let Keywords = dynamic(["helpdesk", " alert", " suspicious", "fake", "malicious", "phishing", "spam", "do not click", "do not open", "hijacked", "Fatal"]);</s></strong>
OfficeActivity
| where Operation =~ "New-InboxRule"
<strong><s>| where Parameters has "Deleted Items"
    or Parameters has "Junk Email"
    or Parameters has "DeleteMessage"</s></strong>
| extend Events=todynamic(Parameters)
| parse Events with * "SubjectContainsWords" SubjectContainsWords '}'*
| parse Events with * "BodyContainsWords" BodyContainsWords '}'*
| parse Events with * "SubjectOrBodyContainsWords" SubjectOrBodyContainsWords '}'*
| where SubjectContainsWords has_any (Keywords)
    or BodyContainsWords has_any (Keywords)
    or SubjectOrBodyContainsWords has_any (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
    timestamp = StartTimeUtc,
    IPCustomEntity = ClientIPAddress,
    AccountCustomEntity = UserId,
    HostCustomEntity =  OriginatingServer
Code language: PHP (php)

Need help managing your own or your customers tenants? Contact us!

Latest Articles

SOAR: Block Log Analytics IP Entities on Azure Frontdoor / WAF #3
How it works Previously, I’ve blogged about two variants that we used at Prof-IT Services to block malicious IP addresses on Azure Frontdoor that were ...
The G-Door: Microsoft 365 & the risk of unmanaged Google Doc accounts
It’s time to secure Google Workspace—even if you’re not using it. Read about our recent discovered vulnerability, called 'G-Door', which allows users to bypass Microsoft ...
Automating Azure SQL Maintenance with Azure Automation
Keeping Your Azure SQL Databases Healthy: The Power of Automation In the realm of database management, maintaining optimal performance and storage efficiency for your Azure ...
Malware Analysis – Shortcuts in zip file
Recently, we encountered two distinct variants of a payload delivered through Google Drive, both containing a malicious shortcut. While these threats were successfully mitigated, it’s ...