Threat Overview
Huntress documented an adversary-in-the-middle (AiTM) token-replay campaign affecting 79 organizations and 97 Microsoft 365 accounts. Between July 14 and September 22, 2026, investigators observed 497 successful sign-ins amid more than 200,000 failed attempts. Attackers captured post-MFA sessions using phishing relays and device-code/social-engineering methods, replayed tokens from hosting infrastructure, registered 48 rogue Entra devices, replaced MFA methods in at least 19 organizations, and hid financial correspondence with Exchange inbox rules. These are Huntress-observed events, not a claim that every sign-in from the provider is malicious. The October 26 reporting newly supplies detailed behaviors and infrastructure.
References
- Huntress — M365 Token Spray and Replay Campaign Compromises Business Email Accounts (research available by October 26, 2026) — https://www.huntress.com/blog/token-replay-spray
- The Hacker News — Microsoft 365 Token-Replay Attacks Compromise 97 Accounts at 79 Organizations (October 26, 2026) — https://thehackernews.com/2026/10/microsoft-365-token-replay-attacks.html
Impacted Systems
- **Vendor/product:** Microsoft Entra ID / Microsoft 365 / Exchange Online, Microsoft Office, Device Registration Service.
- **Deployment:** Cloud tenant identities and mailboxes; no vulnerable software build or patch version is implicated.
- **Prerequisite:** Attacker obtains an authenticated session/token through AiTM, device-code phishing, or social engineering; MFA completion alone does not prevent replay.
- **Exposure:** Users who can authenticate to Microsoft 365; affected device-registration and authentication-method controls depend on tenant policy.
- **Unaffected:** No Microsoft 365 product version is identified as inherently vulnerable; risk depends on compromised sessions and tenant controls.
Why this matters
This campaign crosses multiple MSSP customer tenants and produces observable Entra, Exchange, and identity persistence behaviors. The highest-value hunt is a successful campaign-IP sign-in followed by an unauthorized MFA change, device registration, or mailbox rule.
Exploitation Status
Confirmed real-world compromise (July 14–September 22, 2026); Huntress publication newly reported October 26. Infrastructure may have rotated since the observed window.
What this hunt looks for
Layered, behavior-first detection for the reported campaign, using available Microsoft Sentinel data. Each query requires its listed telemetry; no customer-specific execution is claimed.
Required logs
- AuditLogs
- OfficeActivity
- SigninLogs
- SigninLogs + OfficeActivity
Hunt 01 — Campaign replay IPs with successful sign-in
Required Sentinel telemetry: SigninLogs
SigninLogs
| where TimeGenerated >= ago(30d)
| where IPAddress startswith "193.26.115."
| where ResultType == "0"
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, ResourceDisplayName, ClientAppUsed, UserAgent, DeviceDetail, ConditionalAccessStatus, CorrelationId, RiskLevelAggregated
| order by TimeGenerated descHunt 02 — Rapid IP and device change within a recorded session
Required Sentinel telemetry: SigninLogs
SigninLogs
| where TimeGenerated >= ago(14d) and ResultType == "0"
| extend Session=tostring(column_ifexists("SessionId", "")), OS=tostring(DeviceDetail.operatingSystem)
| where isnotempty(Session) and isnotempty(UserPrincipalName)
| summarize IPs=make_set(IPAddress,10), OSs=make_set(OS,10), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Events=count() by UserPrincipalName, Session
| where array_length(IPs) >= 2 and datetime_diff('minute',LastSeen,FirstSeen) <= 30
| project UserPrincipalName, Session, FirstSeen, LastSeen, IPs, OSs, Events
| order by LastSeen descHunt 03 — Reported rogue device naming pattern in successful logins
Required Sentinel telemetry: SigninLogs
SigninLogs
| where TimeGenerated >= ago(30d) and ResultType == "0"
| extend DeviceName=tostring(DeviceDetail.displayName), DeviceId=tostring(DeviceDetail.deviceId), TrustType=tostring(DeviceDetail.trustType)
| where DeviceName matches regex @"^DESKTOP-[0-9A-F]{8}$"
| project TimeGenerated, UserPrincipalName, IPAddress, DeviceName, DeviceId, TrustType, AppDisplayName, UserAgent, CorrelationId
| order by TimeGenerated descHunt 04 — New Entra device registration with reported naming or IP
Required Sentinel telemetry: AuditLogs
AuditLogs
| where TimeGenerated >= ago(30d)
| where OperationName has_any ("Register device", "Add device", "Join device")
| extend Target=tostring(TargetResources), Actor=tostring(InitiatedBy), ActorIP=tostring(InitiatedBy.user.ipAddress)
| where Target matches regex @"DESKTOP-[0-9A-F]{8}" or ActorIP startswith "193.26.115."
| project TimeGenerated, OperationName, Result, ActorIP, Actor, Target, CorrelationId
| order by TimeGenerated descHunt 05 — MFA method removal and re-registration in three hours
Required Sentinel telemetry: AuditLogs
AuditLogs
| where TimeGenerated >= ago(30d)
| where OperationName has_any ("authentication method", "security info", "authenticator")
| extend TargetUPN=tostring(TargetResources[0].userPrincipalName), ActorIP=tostring(InitiatedBy.user.ipAddress)
| extend Kind=case(OperationName has_any ("Delete", "Remove"), "Removed", OperationName has_any ("Add", "Register"), "Added", "Other")
| where Kind in ("Removed", "Added") and isnotempty(TargetUPN)
| summarize FirstRemoved=minif(TimeGenerated,Kind=="Removed"), LastAdded=maxif(TimeGenerated,Kind=="Added"), Removed=countif(Kind=="Removed"), Added=countif(Kind=="Added"), Operations=make_set(OperationName,10), IPs=make_set(ActorIP,10) by TargetUPN
| where Removed > 0 and Added > 0 and LastAdded between (FirstRemoved .. FirstRemoved+3h)
| project TargetUPN, FirstRemoved, LastAdded, Removed, Added, Operations, IPs
| order by LastAdded descHunt 06 — Mailbox hiding rules targeting financial correspondence
Required Sentinel telemetry: OfficeActivity
OfficeActivity
| where TimeGenerated >= ago(30d)
| where Operation in~ ("New-InboxRule","Set-InboxRule","UpdateInboxRules","NewInboxRule")
| extend P=tostring(Parameters)
| where P has_any ("RSS Feeds","Conversation History","payroll","direct deposit","bonus","bank") or P has_any ("MarkAsRead","DeleteMessage")
| project TimeGenerated, UserId, ClientIP, Operation, OfficeWorkload, Parameters, ResultStatus
| order by TimeGenerated descHunt 07 — Campaign sign-in followed by inbox-rule manipulation
Required Sentinel telemetry: SigninLogs + OfficeActivity
let Logins=SigninLogs
| where TimeGenerated >= ago(30d) and ResultType == "0" and IPAddress startswith "193.26.115."
| project User=tolower(UserPrincipalName), LoginTime=TimeGenerated, LoginIP=IPAddress;
OfficeActivity
| where TimeGenerated >= ago(30d) and Operation in~ ("New-InboxRule","Set-InboxRule","UpdateInboxRules","NewInboxRule")
| extend User=tolower(UserId), RuleDetails=tostring(Parameters)
| join kind=inner Logins on User
| where TimeGenerated between (LoginTime .. LoginTime+24h)
| project LoginTime, TimeGenerated, User, LoginIP, ClientIP, Operation, RuleDetails
| order by TimeGenerated descHunt 08 — Device-code and token replay from campaign infrastructure
Required Sentinel telemetry: SigninLogs
SigninLogs
| where TimeGenerated >= ago(30d)
| where IPAddress startswith "193.26.115."
| extend AuthProtocol=tostring(column_ifexists("AuthenticationProtocol", "")), Client=tostring(ClientAppUsed)
| where AuthProtocol has "device" or AppDisplayName has_any ("Microsoft Office","Device Registration Service","OfficeHome") or UserAgent has "node"
| project TimeGenerated, UserPrincipalName, IPAddress, ResultType, ResultDescription, AppDisplayName, ResourceDisplayName, AuthProtocol, Client, UserAgent, DeviceDetail
| order by TimeGenerated descDetection Notes
Highest signal: campaign-source successful sign-ins, campaign sign-in → inbox-rule creation, and MFA removal followed by addition. Normal device enrollment and legitimate finance rules can produce individual matches. Token replay is inferred from correlated sign-in behavior, not directly proven by a KQL field. IPs are historical campaign infrastructure and may change.
Scope: Results are limited to log sources and retention ingested into Microsoft Sentinel. No customer workspace was queried for this publication.