Mailbox search and export tooling in a script block
Matches the scripted-access half of AN0131: a PowerShell script block that names a bulk mailbox search or export cmdlet, one of the published mail-harvesting toolkits, the Graph message-reading cmdlets, or the Exchange Web Services assembly. The whole selection sits on `ScriptBlockText` under EventID 4104, which is the only field in this log source that carries the script text as the engine compiled it — so an `-EncodedCommand` payload arrives decoded, but decoded is not deobfuscated: name splitting (`"Sea"+"rch-Mailbox"`), backtick insertion and wildcard command resolution (`&(gcm Sear*-Mailbox)`) all survive compilation and defeat every literal term below. The interactive-administration cmdlet Connect-ExchangeOnline is deliberately left out: it is how every legitimate session to the service also begins, so including it would make the rule fire on ordinary administration. The rule can only see a host whose PowerShell is being logged — an adversary reaching the mailbox from an unmanaged machine, a browser session or a direct Graph call writes nothing here, and the Office Suite side of this technique lives in the tenant's own audit log rather than in any Windows event channel. The brief's other two log sources, Sysmon EventID 3 and 22, were not used: a connection or a DNS lookup to a mail service endpoint is what every mail client on the estate does all day, so neither carries a signal at the single-event level. EventID 4104 requires *Script Block Logging* to be enabled by policy; it is off in a default install, and with it off this rule returns zero rows, which reads as quiet when it means blind. UNVERIFIED AS AUTHORED — derived from MITRE ATT&CK DET0048, not hand-written and not tested by its author. Any lab result is on this rule's own page.Full descriptionShow less
The detection
The 4 SIEM queries below are previews produced by Siemphony’s own translator, not pySigma, and none has been executed against a real backend — review before you deploy.
detection.yml
Sentinel · KQL
Run this as a search.
Event| where (EventID == 4104 and (ScriptBlockText contains "Invoke-GlobalMailSearch" or ScriptBlockText contains "Invoke-SelfSearch" or ScriptBlockText contains "Invoke-OpenInboxFinder" or ScriptBlockText contains "Get-GlobalAddressList" or ScriptBlockText contains "Search-Mailbox" or ScriptBlockText contains "New-MailboxSearch" or ScriptBlockText contains "New-MailboxExportRequest" or ScriptBlockText contains "New-ComplianceSearchAction" or ScriptBlockText contains "Get-MgUserMessage" or ScriptBlockText contains "Get-MgUserMailFolderMessage" or ScriptBlockText contains "Microsoft.Exchange.WebServices" or ScriptBlockText contains "AADInternals"))
Splunk · SPL
Run this as a search.
index=* (EventID="4104" AND (ScriptBlockText="*Invoke-GlobalMailSearch*" OR ScriptBlockText="*Invoke-SelfSearch*" OR ScriptBlockText="*Invoke-OpenInboxFinder*" OR ScriptBlockText="*Get-GlobalAddressList*" OR ScriptBlockText="*Search-Mailbox*" OR ScriptBlockText="*New-MailboxSearch*" OR ScriptBlockText="*New-MailboxExportRequest*" OR ScriptBlockText="*New-ComplianceSearchAction*" OR ScriptBlockText="*Get-MgUserMessage*" OR ScriptBlockText="*Get-MgUserMailFolderMessage*" OR ScriptBlockText="*Microsoft.Exchange.WebServices*" OR ScriptBlockText="*AADInternals*"))Elastic · ES|QL
Run this as a search.
FROM logs-*| WHERE (event.code == 4104 AND (TO_LOWER(powershell.file.script_block_text) LIKE "*invoke-globalmailsearch*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*invoke-selfsearch*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*invoke-openinboxfinder*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*get-globaladdresslist*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*search-mailbox*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*new-mailboxsearch*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*new-mailboxexportrequest*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*new-compliancesearchaction*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*get-mgusermessage*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*get-mgusermailfoldermessage*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*microsoft.exchange.webservices*" OR TO_LOWER(powershell.file.script_block_text) LIKE "*aadinternals*"))
Wazuh · XML rule
Deploy to your manager — this is a rule, not a search.
<group name="sigma,windows,"> <!-- Rule ids must be unique on your manager; 100000+ is the user range. --> <rule id="100000" level="7"> <!-- Set <if_sid> to the decoder/base rule for windows so this only evaluates relevant events. --> <field name="EventID" type="pcre2">(?i)^4104$</field> <field name="ScriptBlockText" type="pcre2">(?i)(Invoke-GlobalMailSearch|Invoke-SelfSearch|Invoke-OpenInboxFinder|Get-GlobalAddressList|Search-Mailbox|New-MailboxSearch|New-MailboxExportRequest|New-ComplianceSearchAction|Get-MgUserMessage|Get-MgUserMailFolderMessage|Microsoft\.Exchange\.WebServices|AADInternals)</field> <description>Mailbox search and export tooling in a script block</description> <mitre> <id>T1114.002</id> </mitre> </rule></group>
Verdicts · reactions · comments
Community
Verdicts from engineers who actually deployed it, and the conversation around it.
Nobody has run this in a real environment and said what happened.
Verdicts from engineers who deployed it
0 castNo verdicts reported yet. The first one is worth more than the tenth — say what you ran it against.
Log in to report a verdict.
Log in to join the discussion.
No comments yet. Someone who deploys this will have something to say about it.