AITM PHISH
TWO ACTORS
M365 UAL
PURVIEW DLP
Incident Response DFIR Engagement Insider Threat TLP:WHITE October 2024

The Insider Who Wasn’t (And Then Was)

Two threat actors exfiltrating from the same account at the same time — one external AiTM operator reading email, one insider VP stealing client files — each oblivious to the other, for completely different reasons.

Scroll

The following is a lightly anonymised account of a real DFIR engagement. Client identifiers, staff names, and financial specifics have been altered. All technical artifacts, commands, and findings are presented as they occurred. We are publishing this case because it demonstrates a failure mode that no playbook accounts for: two independent threat actors — one external, one insider — operating simultaneously in the same compromised account, each generating evidence that the other existed.

ParameterDetail
Case TypeHybrid External AiTM + Insider Threat — Dual-Actor Exfiltration
IndustryFinancial Services ($3.4B AUM, 180 staff)
Duration9 days on-site + 3 weeks remote analysis
YearYear 5 of operations
NotorietyThe one where every time we thought we understood what had happened, we were right — and wrong

Investigative Context

This engagement changed its working conclusion four times in six days. Each pivot was driven by new evidence that contradicted the prevailing theory — not because the previous evidence was wrong, but because each data source told a true but incomplete story. The table below reconstructs how the investigation’s hypothesis evolved.

PivotDayNew EvidenceWorking Conclusion
1Day 1Inbox forwarding rule to external Gmail, keyword filters on financial termsInsider threat — Derek is exfiltrating client data via email rule
2Day 2Rule created from Tor exit node (185.220.xx.xx) at 23:47 while Derek was in VancouverExternal actor — Derek’s account is compromised, he is the victim
3Day 4Purview Endpoint DLP: 23 client files copied to personal OneDrive from Derek’s enrolled deviceInsider confirmed — Derek is also stealing files independently of the email compromise
4Day 6Full IP + ClientInfoString + DeviceID correlation: zero overlap between actorsTwo independent actors — external AiTM broker reading email, insider VP stealing files, simultaneously

The Engagement

How We Were Called In

The call originated from an ethics hotline tip. An anonymous employee had reported that Derek — a VP in portfolio management — had been sending client investment strategy documents to a personal email address associated with a competitor firm. The firm’s General Counsel received the tip, reviewed it, and then did what General Counsels often do: waited three weeks before engaging external forensics, during which time the UAL retention clock continued to tick.

By the time we were retained, the M365 Unified Audit Log had 67 days of data remaining in its 90-day retention window. Twenty-three days of potential evidence had already aged out. This is not unusual — it is the norm. The gap between ‘suspicion’ and ‘investigation’ in insider threat cases routinely costs weeks of telemetry.

The Environment

The firm ran Microsoft 365 E3 — which provides the full Unified Audit Log with MailItemsAccessed, but critically did not include Defender for Cloud Apps (CASB) or the E5 security suite. There was no standalone SIEM. Microsoft Defender for Endpoint was deployed on 140 of 180 devices — a 78% enrollment rate that would prove significant later. Purview Endpoint DLP was configured in audit mode (logging but not blocking), which turned out to be the single most important data source in the investigation.

Environment Gap

E3 licensing without CASB meant no OAuth app governance, no session anomaly detection, and no automated impossible-travel alerts. The AiTM compromise had been active for 9 weeks before anyone noticed — and they noticed the insider, not the external actor.

Finding 1: The Inbox Forwarding Rule — Tor Exit Node at 23:47

Artifact: M365 Unified Audit Log — New-InboxRule Operation

Path: UAL Operation: New-InboxRule | Exchange Online PowerShell

  • New-InboxRule: records rule creation including name, conditions, actions, and source IP
  • ForwardTo / RedirectTo / ForwardAsAttachmentTo: the three forwarding action types
  • SubjectOrBodyContainsWords: keyword conditions that indicate targeted data collection
  • CRITICAL: always check ClientIPAddress against known user IPs to determine if rule was user-created or attacker-created

The first artifact we pulled was the inbox rule that had triggered the ethics hotline tip. The rule was forwarding emails matching financial keywords to an external Gmail address. On its face, this looked like a textbook insider exfiltration mechanism — until we checked the source IP.

POWERSHELL
# New-InboxRule audit — forwarding rule created from Tor exit node, not Derek's device
Search-UnifiedAuditLog \
  -StartDate (Get-Date).AddDays(-90) \
  -EndDate (Get-Date) \
  -Operations New-InboxRule \
  -UserIds derek@firm.com \
  -ResultSize 5000 | ForEach-Object {
    $d = $_.AuditData | ConvertFrom-Json
    [PSCustomObject]@{
      Time       = $_.CreationDate
      IP         = $d.ClientIPAddress
      RuleName   = ($d.Parameters | Where-Object Name -eq 'Name').Value
      ForwardTo  = ($d.Parameters | Where-Object Name -eq 'ForwardTo').Value
      Keywords   = ($d.Parameters | Where-Object Name -eq 'SubjectOrBodyContainsWords').Value
    }
} | Format-Table -AutoSize

# OUTPUT:
Time                      IP               RuleName              ForwardTo                                    Keywords
2024-██-██ 23:47:12 UTC   185.220.xx.xx    'Portfolio-Sync'      derek.portfolio.mgmt.backup@gmail.com        {investment, strategy, portfolio,
                                                                                                                  allocation, client, AUM, quarterly}

# 185.220.xx.xx = known Tor exit node (TorProject exit list match)
# Rule created at 23:47 UTC = 3:47 PM PST — Derek was in Vancouver at a client meeting
# Corporate badge access log confirms Derek badged into Vancouver office at 08:12 PST that day
# Derek's known IPs: 10.xx.xx.xx (office), 72.xx.xx.xx (home) — neither matches Tor exit

The inbox rule was real. The forwarding address contained Derek’s name. The keyword filters targeted exactly the kind of financial data the ethics tip described. But the rule was created from a Tor exit node at 23:47 UTC while Derek was physically in the Vancouver office on the opposite side of the continent. The rule was not created by Derek. Someone else had access to Derek’s account.

Finding 01

Inbox Forwarding Rule Created from Tor Exit Node — Not Derek’s Device or Location

An inbox rule named ‘Portfolio-Sync’ was forwarding emails containing financial keywords (investment, strategy, portfolio, allocation, client, AUM, quarterly) to derek.portfolio.mgmt.backup@gmail.com. The rule was created at 23:47 UTC from Tor exit node 185.220.xx.xx. Physical access logs confirmed Derek was in the Vancouver office at the time. The forwarding address was crafted to look like Derek’s personal backup — a deliberate attribution misdirection by an external actor.

Finding 2: AiTM Credential Compromise via Evilginx2

Artifact: Azure AD Sign-In Logs + Exchange Message Trace

Path: Azure Portal → Azure AD → Sign-in Logs | Exchange Admin → Message Trace

  • AiTM sign-ins show MFA satisfied from unexpected geolocations — because the proxy relays the real MFA challenge
  • Look for PHPSESSID in session metadata and PHP/8.2 server headers — Evilginx2 fingerprints
  • The phishing email typically arrives 30–90 minutes before the anomalous sign-in
  • Cross-reference sign-in IP with message trace to find the initial phishing delivery

If an external actor created the inbox rule, they needed session access to Derek’s M365 account. We traced backward from the rule creation timestamp through the Azure AD sign-in logs to find the initial compromise.

AZURE AD SIGN-IN
# Azure AD sign-in log — AiTM session hijack, MFA satisfied from Moldova
# Anomalous sign-in, 9 weeks before inbox rule creation:

Timestamp:              2024-██-██T14:22:38Z (9 weeks before rule creation)
UserPrincipalName:      derek@firm.com
IPAddress:              94.140.xx.xx
Location:               Chisinau, Moldova
ClientApp:              Browser
DeviceDetail:           Windows 10, Chrome 118
Status:                 Success
MFA Result:             MFA requirement satisfied by claim in the token
AuthenticationDetails:  Primary (password) = succeeded | MFA (phone SMS) = succeeded
SessionId:              PHPSESSID=a8f3████████████   ← Evilginx2 session cookie fingerprint
ServerHeader:           PHP/8.2.14                              ← Evilginx2 reverse proxy header

# Derek's normal sign-in pattern: 10.xx.xx.xx (Toronto office), 72.xx.xx.xx (home)
# Moldova IP 94.140.xx.xx: first and only sign-in from this ASN in Derek's entire history
# MFA was satisfied — because the Evilginx2 proxy relayed the real MFA challenge to Derek
# Derek completed MFA thinking he was signing into Microsoft. The proxy captured the session token.

The sign-in occurred 9 weeks before the inbox rule was created. The external actor had been inside Derek’s account for over two months before making the forwarding rule — a patience pattern consistent with access brokers who sell compromised sessions on initial access markets. We then traced the phishing email that preceded the sign-in.

MESSAGE TRACE
# Exchange message trace — phishing email 48 minutes before AiTM sign-in
Get-MessageTrace \
  -RecipientAddress derek@firm.com \
  -StartDate (Get-Date '2024-██-██').AddHours(-4) \
  -EndDate (Get-Date '2024-██-██').AddHours(4) |
  Select-Object Received, SenderAddress, Subject, Status

# OUTPUT:
Received                SenderAddress                               Subject                              Status
2024-██-██ 13:34:11     noreply@microsoftonline-alerts[.]com        Action Required: Verify Your M365    Delivered
                                                                     Account Security Settings

# Phishing email delivered 48 minutes before Moldova sign-in
# Domain microsoftonline-alerts[.]com: registered 3 days prior, Namecheap, privacy-protected
# Email contained link to Evilginx2 phishing page proxying login.microsoftonline.com
# Evilginx2 fingerprint confirmed: PHPSESSID cookie + PHP/8.2 server response header
Finding 02

AiTM Credential Compromise via Evilginx2 — MFA Bypassed, Session Token Captured 9 Weeks Before Detection

A phishing email from microsoftonline-alerts[.]com was delivered 48 minutes before an anomalous Azure AD sign-in from Moldova (94.140.xx.xx). The sign-in showed MFA satisfied via SMS — because the Evilginx2 reverse proxy relayed the legitimate MFA challenge to Derek in real-time. The PHPSESSID cookie and PHP/8.2 server header confirmed the Evilginx2 toolkit. The external actor maintained persistent access for 9 weeks via the captured session token before creating the inbox forwarding rule.

Finding 3: 1,203 REST/Graph API Mailbox Reads — External Actor vs. Derek

Artifact: M365 Unified Audit Log — MailItemsAccessed by IP

Path: UAL Operation: MailItemsAccessed | Group by ClientIPAddress

  • MailItemsAccessed with ClientInfoString containing ‘REST’ or ‘Graph’ indicates API-based access
  • Compare against known user IPs and device-based Outlook access patterns
  • Bind events contain InternetMessageId — reconstruct exactly which emails were read
  • Volume alone is not diagnostic — pattern and IP separation are the key indicators

With the AiTM compromise confirmed, we needed to understand the full scope of the external actor’s mailbox access. The MailItemsAccessed audit log provided complete visibility into every email read event, grouped by source IP and client type.

POWERSHELL
# MailItemsAccessed grouped by IP — separating Derek's legitimate access from external actor
Search-UnifiedAuditLog \
  -StartDate (Get-Date).AddDays(-67) \
  -EndDate (Get-Date) \
  -Operations MailItemsAccessed \
  -UserIds derek@firm.com \
  -ResultSize 5000 | ForEach-Object {
    $d = $_.AuditData | ConvertFrom-Json
    [PSCustomObject]@{
      IP         = $d.ClientIPAddress
      ClientInfo = $d.ClientInfoString
    }
} | Group-Object IP | Select-Object Name, Count, @{
    N='ClientInfo';E={($_.Group | Select-Object -First 1).ClientInfo}
} | Sort-Object Count -Descending

# OUTPUT:
Source          IP               ClientInfoString                           Count    Attribution
DEREK           10.xx.xx.xx      Outlook/16.0 (Windows; MAPI)              4,847    Corporate device, office IP
DEREK           72.xx.xx.xx      Outlook/16.0 (Windows; MAPI)              891      Corporate device, home IP
EXTERNAL        94.140.xx.xx     Client=REST;Action=MailItemsAccessed       847      Moldova — AiTM operator
EXTERNAL        185.220.xx.xx    Client=REST;Action=MailItemsAccessed       312      Tor exit — same actor
EXTERNAL        91.243.xx.xx     Client=REST;Action=MailItemsAccessed       44       Romania — same actor

# Total DEREK legitimate access: 5,738 events (Outlook MAPI, known IPs, enrolled device)
# Total EXTERNAL access:         1,203 events (REST API, Eastern European IPs, no device enrollment)
# External actor read email for 9 weeks via REST/Graph API — never used Outlook client

The external actor had accumulated 1,203 mailbox read events over 9 weeks from three IP addresses across Moldova, Tor, and Romania — all using REST/Graph API, never an Outlook client. We reconstructed the specific messages accessed via Bind events.

POWERSHELL
# Bind event reconstruction — 63 client-named email threads accessed by external actor
$external_ips = @('94.140.xx.xx', '185.220.xx.xx', '91.243.xx.xx')

Search-UnifiedAuditLog \
  -Operations MailItemsAccessed \
  -UserIds derek@firm.com \
  -StartDate (Get-Date).AddDays(-67) \
  -EndDate (Get-Date) \
  -ResultSize 5000 | Where-Object {
    $ip = ($_.AuditData | ConvertFrom-Json).ClientIPAddress
    $ip -in $external_ips
  } | ForEach-Object {
    ($_.AuditData | ConvertFrom-Json).Folders.FolderItems
  } | Select-Object -ExpandProperty InternetMessageId |
    Sort-Object -Unique | Measure-Object

# Unique messages accessed by external actor: 387
# Thread analysis (grouped by conversation ID): 63 distinct email threads
# All 63 threads involved client names, investment strategies, or portfolio allocations
# The external actor was systematically harvesting financial intelligence from Derek's mailbox
Finding 03

1,203 REST/Graph API Reads Over 9 Weeks — 63 Client-Named Threads Accessed by External Actor

The external AiTM operator read Derek’s mailbox via REST/Graph API from three Eastern European IPs over a 9-week period. Bind event reconstruction identified 387 unique messages across 63 client-named email threads. The access pattern was systematic financial intelligence collection — not ransomware staging, not lateral movement, not BEC wire fraud. The external actor appeared to be an access broker harvesting data for resale or competitive intelligence.

Finding 4: Purview Endpoint DLP — 23 Client Files to Personal OneDrive

Artifact: Microsoft Purview Endpoint DLP — Activity Explorer

Path: Purview Compliance Portal → Data Loss Prevention → Activity Explorer

  • Endpoint DLP logs file copy, upload, print, and clipboard events on MDE-enrolled devices
  • In audit mode: all events logged but not blocked — creates forensic record without user awareness
  • Key fields: FileName, Activity, DeviceName, DeviceId (MDE GUID), DestinationPath, Timestamp
  • Activity Explorer CSV export provides the full event detail for offline analysis

On Day 4, while we were still mapping the external actor’s mailbox access, the investigation pivoted again. The firm’s compliance team had pulled the Purview Endpoint DLP logs at our request — a data source we check in every insider investigation, even when the working theory is external compromise. The results upended everything.

PYTHON
# Purview Endpoint DLP Activity Explorer — 23 client files copied to personal OneDrive in 4 minutes
import pandas as pd

df = pd.read_csv('activity_explorer_export.csv')
derek_events = df[df['User'] == 'derek@firm.com']
file_copies = derek_events[derek_events['Activity'] == 'FilecopiedToCloudSyncFolder']

print(file_copies[['Timestamp', 'FileName', 'DeviceName', 'DestinationPath']].to_string())

# OUTPUT (23 events in 4-minute window, 48 hours before Derek's resignation date):
# Timestamp                   FileName                                      DeviceName      DestinationPath
# 2024-██-██ 19:02:14         [Client_A]_Investment_Strategy_FY25.pdf       DEREK-CORPLT    OneDrive - Personal
# 2024-██-██ 19:02:31         [Client_B]_Portfolio_Allocation_Q3.xlsx       DEREK-CORPLT    OneDrive - Personal
# 2024-██-██ 19:02:47         [Client_C]_Alternative_Assets_Memo.pdf        DEREK-CORPLT    OneDrive - Personal
# 2024-██-██ 19:03:02         [Client_D]_Risk_Assessment_2024.pdf           DEREK-CORPLT    OneDrive - Personal
# 2024-██-██ 19:03:18         [Client_E]_Fee_Schedule_Confidential.xlsx    DEREK-CORPLT    OneDrive - Personal
# 2024-██-██ 19:03:33         [Client_F]_Investment_Committee_Notes.pdf    DEREK-CORPLT    OneDrive - Personal
# ... [17 additional files through 19:06:41]
# 2024-██-██ 19:06:41         [Client_W]_Quarterly_Performance_Report.pdf  DEREK-CORPLT    OneDrive - Personal
#
# All 23 files: client-named investment documents
# All from device: DEREK-CORPLT (Derek's MDE-enrolled corporate laptop)
# All to destination: OneDrive - Personal (not corporate OneDrive)
# Time window: 4 minutes 27 seconds — rapid, systematic bulk copy
# Timing: 48 hours before Derek's submitted resignation effective date
Key Insight

Two threat actors. One account. The external actor was reading email. Derek was stealing files. They were operating simultaneously, oblivious to each other, for completely different reasons.

Finding 04

23 Client Files Copied to Personal OneDrive in 4 Minutes — 48 Hours Before Resignation

Purview Endpoint DLP in audit mode recorded 23 file copy events from Derek’s enrolled corporate laptop (DEREK-CORPLT) to his personal OneDrive. All files were client-named investment strategy documents. The entire copy operation took 4 minutes 27 seconds, executed 48 hours before Derek’s resignation effective date. This was not the external actor — the DeviceID matched Derek’s MDE-enrolled corporate device, the source IP was his home address, and the OneDrive destination was his personal Microsoft account.

Finding 5: SharePoint Access 6x Baseline — All 41 Client Portfolios

Artifact: M365 Unified Audit Log — SharePoint FileAccessed Operations

Path: UAL Operations: FileAccessed, FileDownloaded | SharePoint Online

  • FileAccessed: records every document open/preview in SharePoint or OneDrive for Business
  • Baseline comparison: calculate average daily access for a user over 30+ days, then identify anomalous periods
  • Cross-portfolio access: a user accessing documents outside their normal scope is a high-confidence insider indicator
  • Compare accessed sites/libraries against the user’s assigned client list from HR records

With the DLP evidence confirming Derek as an insider threat, we expanded the investigation to his full SharePoint access pattern. The question was whether the 23 copied files represented the full extent of Derek’s data collection, or whether he had been systematically browsing beyond his assigned clients.

POWERSHELL
# SharePoint FileAccessed — baseline vs. anomalous period comparison
# Baseline period: 30 days, starting 60 days before resignation
$baseline = Search-UnifiedAuditLog \
  -StartDate (Get-Date '2024-██-██').AddDays(-60) \
  -EndDate (Get-Date '2024-██-██').AddDays(-30) \
  -Operations FileAccessed \
  -UserIds derek@firm.com \
  -ResultSize 5000

# Anomalous period: final 14 days before resignation
$anomalous = Search-UnifiedAuditLog \
  -StartDate (Get-Date '2024-██-██').AddDays(-14) \
  -EndDate (Get-Date '2024-██-██') \
  -Operations FileAccessed \
  -UserIds derek@firm.com \
  -ResultSize 5000

# RESULTS:
# Baseline daily average:   6.9 FileAccessed events/day (30-day average)
# Anomalous daily average: 42.4 FileAccessed events/day (14-day pre-resignation period)
# Increase:                6.1x baseline — 515% above normal access volume
#
# Baseline portfolio scope:  8 client portfolios (Derek's assigned client list per HR)
# Anomalous portfolio scope: 41 client portfolios (ALL firm client portfolios)
# Plus: firm-level documents (investment committee minutes, fee schedules, AUM reports)
#
# Derek accessed every client portfolio the firm managed — not just his 8 assigned clients.
# This is systematic, cross-portfolio data collection inconsistent with any legitimate work task.

Derek had been assigned 8 client portfolios. In his final 14 days, he accessed documents in all 41 client portfolios the firm managed — plus firm-level investment committee minutes, master fee schedules, and aggregate AUM reports. His daily SharePoint access rate was 6.1x his 30-day baseline. This was not incidental browsing. It was systematic reconnaissance of the firm’s entire client base, executed in the two weeks before his departure.

Finding 05

SharePoint Access 6.1x Baseline — All 41 Client Portfolios Accessed (vs. 8 Assigned)

Derek’s SharePoint FileAccessed volume increased from 6.9 events/day (baseline) to 42.4 events/day in his final 14 days — a 6.1x increase. He accessed all 41 client portfolios managed by the firm, despite being assigned only 8. He also accessed firm-level documents including investment committee minutes, fee schedules, and AUM reports. The access pattern was systematic and cross-portfolio, consistent with pre-departure data collection for competitive purposes.

Finding 6: Complete Actor Separation — Zero Overlap

Artifact: Correlation Matrix — IP + ClientInfoString + DeviceID Pivot

Path: Custom correlation across UAL MailItemsAccessed, SharePoint FileAccessed, DLP Activity Explorer, Azure AD Sign-In

  • Three-axis separation: IP address, ClientInfoString (application identifier), DeviceID (MDE enrollment GUID)
  • If two actors share zero overlap on all three axes, they are definitively independent
  • This methodology is critical for legal proceedings — you must prove Derek acted independently of the external compromise

On Day 6, we completed the full correlation. The question the General Counsel needed answered was precise: could Derek’s legal team argue that the external actor had performed the file exfiltration, and Derek was simply a victim of account compromise? The answer required proving zero overlap between the two actors’ activities.

PYTHON
# Three-axis actor separation — IP + ClientInfoString + DeviceID pivot table
import pandas as pd

# Merge all UAL data sources into unified event log
events = pd.read_csv('unified_events.csv')

pivot = events.pivot_table(
    index='Actor',
    columns='ActivityCategory',
    values='EventCount',
    aggfunc='sum',
    fill_value=0
)

print(pivot.to_string())

# OUTPUT — Actor Separation Matrix:
#                          MailItemsAccessed   InboxRuleCreation   SharePointAccess   DLP_FileEgress
# EXTERNAL (AiTM)          1,203               1                   0                  0
# DEREK (Insider)          5,738               0                   594                23
#
# ZERO OVERLAP:
# - External actor: 0 file egress events, 0 SharePoint access events
# - Derek:          0 inbox rule manipulation events, 0 REST API mail access events
# - External IPs never appear in SharePoint/DLP logs
# - Derek's device ID never appears in REST API mail access logs

# DeviceID verification:
# All 23 DLP file copy events → DeviceId: 7a3f████-████-████-████████████ (DEREK-CORPLT)
# All 1,203 REST API reads → DeviceId: (none) — external actor used no enrolled device
# All 594 SharePoint events → DeviceId: 7a3f████-████-████-████████████ (DEREK-CORPLT)
#
# Conclusion: Two independent actors. Complete separation on all three axes.
# The external actor never touched files. Derek never touched email rules or REST API.
Finding 06

Complete Actor Separation Confirmed — Zero Overlap on IP, ClientInfoString, and DeviceID

The three-axis correlation (IP address, ClientInfoString, DeviceID) proved definitively that the external AiTM operator and Derek the insider VP were independent actors. The external actor performed 1,203 REST API email reads and 1 inbox rule creation — zero file egress, zero SharePoint access. Derek performed 594 SharePoint accesses and 23 DLP-logged file copies — zero email rule manipulation, zero REST API access. All 23 DLP events carried Derek’s enrolled MDE device GUID. All 1,203 REST events carried no device enrollment. The two actors shared the same account but operated in completely non-overlapping M365 service boundaries.

Dual-Actor Simultaneous Timeline

TimestampActorArtifact SourceEvent
T-9 weeks External Message Trace Evilginx2 phishing email from microsoftonline-alerts[.]com delivered to Derek. Link to AiTM proxy of login.microsoftonline.com.
T-9w, +48 min External Azure AD Sign-In AiTM sign-in from Moldova (94.140.xx.xx). MFA satisfied via proxy relay. Session token captured. PHPSESSID + PHP/8.2 fingerprint.
T-9w to T-2w External UAL MailItemsAccessed 1,203 REST API mailbox reads across Moldova, Tor, and Romania IPs. 63 client-named threads systematically accessed.
T-3 weeks Derek HR Records Derek submits resignation, effective in 3 weeks. No mention of external job offer destination.
T-2w, 23:47 UTC External UAL New-InboxRule Inbox forwarding rule ‘Portfolio-Sync’ created from Tor exit (185.220.xx.xx). Forwards financial keywords to Gmail.
T-14 to T-2 days Derek UAL FileAccessed SharePoint access increases to 42.4/day (6.1x baseline). Derek accesses all 41 client portfolios + firm-level documents.
T-2 days, 19:02 Derek Purview Endpoint DLP 23 client files copied to personal OneDrive in 4 min 27 sec from DEREK-CORPLT. Bulk pre-departure exfiltration.
T-0 Derek HR Records Derek’s resignation effective date. Last day at firm. Corporate device returned.
T+1 day Ethics Hotline Anonymous tip received about Derek sending client data to competitor. GC begins internal review.
T+3 weeks IR Engagement Mjolnir Security retained. 67 days UAL remaining. Investigation begins with inbox rule analysis.
Investigation Day 1 UAL New-InboxRule Inbox forwarding rule discovered. Initial theory: Derek is the insider. Pivot 1.
Investigation Day 2 UAL + IP Analysis Tor exit node identified as rule source. Derek in Vancouver at time of creation. Theory shifts: external actor. Pivot 2.
Investigation Day 4 Purview DLP 23 file copies to personal OneDrive from Derek’s device. Theory shifts: insider confirmed alongside external. Pivot 3.
Investigation Day 6 Full Correlation Three-axis separation completed. Zero overlap. Two independent actors confirmed. Final conclusion. Pivot 4.

What This Engagement Teaches Us

For Incident Responders

  1. Multi-hypothesis investigation is mandatory, not optional. Every time we committed to a single theory in this case, new evidence contradicted it. Run the external and insider hypotheses in parallel from Day 1. Do not prune a hypothesis until you have affirmatively disproved it with artifact-level evidence.
  2. Three-axis actor separation (IP + ClientInfoString + DeviceID) is the standard for proving independent actors in a shared-account scenario. Two axes are suggestive. Three axes are dispositive. This is the level of proof required for legal proceedings and regulatory filings.
  3. AiTM detection signals are subtle but consistent: look for PHPSESSID cookies in session metadata, PHP server headers in sign-in logs, MFA satisfied from geographically impossible IPs within minutes of a phishing email delivery, and REST/Graph API access from IPs that never appear in Outlook client connections.
  4. Purview Endpoint DLP in audit mode is a forensic goldmine — even when it is not blocking anything. The file-level detail (filename, device, destination, timestamp) provided the evidence that separated the insider from the external actor. Recommend audit-mode DLP to every client, even if they are not ready for enforcement.

For Security Engineers

  1. Risk-based Conditional Access policies defeat AiTM at the session layer. Require compliant/hybrid-joined device for Exchange and SharePoint access. The external actor used REST API from an unenrolled device — a Conditional Access policy requiring device compliance would have blocked the session token replay entirely.
  2. Alert on New-InboxRule from non-corporate IPs. Every M365 tenant should have an alert rule for New-InboxRule operations where ClientIPAddress does not match the corporate IP range. This is a 15-minute configuration in the Security & Compliance Center and would have detected this compromise 7 weeks earlier.
  3. SharePoint access baseline monitoring is the earliest-firing insider threat detection for file-focused exfiltration. A user jumping from 8 to 41 accessed sites in a 14-day window is a signal that no UEBA tool should miss — and it fires weeks before the actual file copy event.
  4. 100% MDE enrollment is a forensic requirement, not just a security one. The firm had 78% enrollment (140/180). If Derek’s device had not been enrolled, we would have had no DLP telemetry and no DeviceID to prove actor separation. Partial enrollment creates forensic blind spots that can undermine an entire investigation.

Mjolnir Security — M365 Forensics & Insider Threat Investigation

Mjolnir Security provides 24/7 incident response, M365 forensics, and insider threat investigation services for financial institutions, asset managers, and regulated industries. Our DFIR team specializes in multi-actor attribution, AiTM phishing response, and Purview DLP forensics across complex M365 environments.

Incident Response M365 Forensics Insider Threat Investigation AiTM Phishing Response Purview DLP Analysis SharePoint Access Monitoring

mjolnirsecurity.com — 24/7 Incident Response Hotline: +1 833 403 5875

Written by Mjolnir Security DFIR team

Published October 2024 · DFIR Engagement Series · TLP:WHITE

Case #214 · Skuggaheimar · Mjolnir Security · All client details anonymized · TLP:WHITE