Skip to content

O365 message trace detections: support o365:graph:messagetrace (Office 365 add-on 6.x) - #4286

Merged
nasbench merged 4 commits into
splunk:developfrom
sbaker-gre:fix/o365-messagetrace-graph-sourcetype
Sep 29, 2026
Merged

nasbench merged 4 commits into
splunk:developfrom
sbaker-gre:fix/o365-messagetrace-graph-sourcetype

Conversation

@sbaker-gre

@sbaker-gre sbaker-gre commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #4285.

Splunk Add-on for Microsoft Office 365 6.x emits message trace as o365:graph:messagetrace
with camelCase fields. The four message trace detections and their macro only handled the
retired Reporting web service sourcetypes and PascalCase raw fields, so they return nothing
on a current add-on.

Changes

  • macros/o365_messagetrace.yml: add o365:graph:messagetrace.
  • Four detections switched from raw fields to the CIM fields the add-on aliases for both
    sourcetypes: Status → status_code, RecipientAddress → recipient,
    SenderAddress → src_user, MessageId → message_id. Drilldowns updated to match.
  • Organization (absent on the Graph sourcetype) replaced with a sender-domain vs
    recipient-domain comparison in the two exfiltration-style detections.
  • Second unit test per detection using the Graph fixture from T1114 o365_suspect_email_actions: add Graph message trace fixture attack_data#1224.
    Legacy test retained to prove backward compatibility with o365:reporting:messagetrace.
  • Versions bumped.
  • description, how_to_implement and known_false_positives reflowed to |- block
    scalars, one sentence per line, to match repo style. No content changes.

Detections

  • O365 Email Password and Payroll Compromise Behavior
  • O365 Email Receive and Hard Delete Takeover Behavior
  • O365 Email Send and Hard Delete Exfiltration Behavior
  • O365 Email Send Attachments Excessive Volume

Verification

  • contentctl-ng build passes.
  • On live o365:graph:messagetrace data (add-on 6.0.2), all five CIM fields are populated
    on 2,000 of 2,000 sampled events. Graph status values are lowercase (delivered);
    the status_code=Delivered filter is in the base search where value matching is
    case-insensitive, so it matches both.
  • The Graph unit tests depend on the attack_data PR merging first.

🤖 Generated with Claude Code

sbaker-gre and others added 2 commits September 23, 2026 14:32
Splunk Add-on for Microsoft Office 365 6.x collects message trace through
Microsoft Graph and emits sourcetype o365:graph:messagetrace with camelCase
fields (senderAddress, recipientAddress, messageId, status) instead of the
PascalCase fields of the retired Reporting web service sourcetypes.

- Add o365:graph:messagetrace to the o365_messagetrace macro.
- Switch the four dependent detections from raw field names to the CIM
  fields the add-on aliases for both sourcetypes: status_code, recipient,
  src_user, message_id. Behaviour is unchanged on the legacy sourcetypes.
- Replace the Organization field, which the Graph sourcetype does not
  carry, with a sender-domain vs recipient-domain comparison.
- Update drilldowns to use recipient.

Affected: O365 Email Password and Payroll Compromise Behavior, O365 Email
Receive and Hard Delete Takeover Behavior, O365 Email Send and Hard Delete
Exfiltration Behavior, O365 Email Send Attachments Excessive Volume.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Second test per detection replays the same four suspect messages in the
o365:graph:messagetrace shape (companion attack_data change adds
o365_graph_messagetrace_suspect_events.log). The legacy test is kept to
prove backward compatibility with o365:reporting:messagetrace.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@sbaker-gre
sbaker-gre force-pushed the fix/o365-messagetrace-graph-sourcetype branch from c9e65bd to 1f742a2 Compare September 23, 2026 19:32
@nasbench nasbench added this to the v6.8.0 milestone Sep 23, 2026
sbaker-gre and others added 2 commits September 24, 2026 16:47
Convert description, how_to_implement and known_false_positives to |- block
scalars with one sentence per line, matching the repo's detection YAML style.
No content changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nasbench

Copy link
Copy Markdown
Contributor

Tested the updates locally. See SS below and check count being doubled

image image image image

@nasbench nasbench left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updates LGTM. For context I looked at the props and the mapping is technically the same. Here it is below for reference.

[o365:reporting:messagetrace]
KV_MODE = json
MAX_TIMESTAMP_LOOKAHEAD = 30
SHOULD_LINEMERGE = 0
TIME_FORMAT = %Y-%m-%dT%H:%M:%S.%Q
TZ = UTC
TIME_PREFIX = "Received": "
REPORT-splunk_ta_o365_cim_all_email_domain = extract_messagetrace_src_user_domain, extract_messagetrace_recipient_domain
FIELDALIAS-o365_reporting_messagetrace_basic_alias_recipient = RecipientAddress AS recipient
FIELDALIAS-o365_reporting_messagetrace_basic_alias_src_user = SenderAddress AS src_user
FIELDALIAS-o365_reporting_messagetrace_basic_alias_dest = ToIP AS dest
FIELDALIAS-o365_reporting_messagetrace_basic_alias_src = FromIP AS src
FIELDALIAS-o365_reporting_messagetrace_basic_alias_message_id = MessageId AS message_id
FIELDALIAS-o365_reporting_messagetrace_basic_alias_subject = Subject AS subject
FIELDALIAS-o365_reporting_messagetrace_basic_alias_size = Size AS size
FIELDALIAS-o365_reporting_messagetrace_basic_alias_internal_message_id = MessageTraceId AS internal_message_id
FIELDALIAS-o365_reporting_messagetrace_basic_alias_status_code = Status AS status_code
EVAL-vendor_product = "Microsoft Office 365 MessageTrace"
EVAL-recipient_count = "1"
LOOKUP-splunk_ta_o365_cim_messagetrace_action = splunk_ta_o365_cim_messagetrace_action Status OUTPUT action

[o365:graph:messagetrace]
KV_MODE = json
MAX_TIMESTAMP_LOOKAHEAD = 30
SHOULD_LINEMERGE = 0
TIME_FORMAT = %Y-%m-%dT%H:%M:%S.%7N
TZ = UTC
TIME_PREFIX = "receivedDateTime": "
REPORT-splunk_ta_o365_cim_all_email_domain = extract_graph_messagetrace_src_user_domain, extract_graph_messagetrace_recipient_domain
FIELDALIAS-o365_graph_messagetrace_recipient = recipientAddress AS recipient
FIELDALIAS-o365_graph_messagetrace_src_user = senderAddress AS src_user
EVAL-toIP = if(toIP!="", toIP, null())
EVAL-dest = if(toIP!="", toIP, null())
FIELDALIAS-o365_graph_messagetrace_src = fromIP AS src
FIELDALIAS-o365_graph_messagetrace_message_id = messageId AS message_id
FIELDALIAS-o365_graph_messagetrace_subject = subject AS subject
FIELDALIAS-o365_graph_messagetrace_size = size AS size
FIELDALIAS-o365_graph_messagetrace_internal_message_id = id AS internal_message_id
FIELDALIAS-o365_graph_messagetrace_status_code = status AS status_code
EVAL-vendor_product = "Microsoft Office 365 MessageTrace"
EVAL-recipient_count = "1"
LOOKUP-splunk_ta_o365_cim_graph_messagetrace_action = splunk_ta_o365_cim_graph_messagetrace_action status OUTPUT action

I have also ran these searches locally and they work

@nasbench
nasbench merged commit 9aff0d8 into splunk:develop Sep 29, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

O365 message trace detections do not work with Splunk Add-on for Microsoft Office 365 6.x (o365:graph:messagetrace)

2 participants