Microsoft Exchange CVE-2026-96940 Cross-Mailbox Access Hunt

Threat Overview

CVE-2026-96940 is a high-severity weak-authorization vulnerability in on-premises Microsoft Exchange Server. Microsoft states that an authenticated network attacker can read mailbox messages and attachments belonging to other users in the same Exchange organization. The issue does not cross Microsoft 365 tenant boundaries. It is therefore best treated as post-authentication privilege expansion: an attacker first needs a valid account or session, but may then reach higher-value mailboxes without the intended authorization.

Microsoft released version 2 of the September 2026 Exchange security updates on October 2 specifically to add CVE-2026-96940. Microsoft identified the flaw internally, assessed exploitation as “More Likely,” and said it was not aware of active exploitation at publication. Exchange Online is already protected. Exchange Server 2016 and 2019 are out of support; the October packages for those branches are available only to Period 2 Extended Security Update customers, making migration to Exchange Server Subscription Edition the supported path for organizations without ESU coverage.

References

Impacted Systems

  • Exchange Server Subscription Edition: RTM before SU10V2 (KB5129955).
  • Exchange Server 2019: CU15 before SU11V2 (KB5129956) and CU14 before the October 2 V2 update (KB5129957). Period 2 ESU enrollment is required to obtain current 2019 updates.
  • Exchange Server 2016: CU23 before SU25V2 (KB5129958). Period 2 ESU enrollment is required to obtain current 2016 updates.
  • Platform/deployment: Self-managed/on-premises Exchange mailbox and client-access roles on Windows Server, including hybrid organizations that retain on-premises Exchange servers or management tools.
  • Attacker prerequisite: A valid authenticated Exchange account/session and network access to the affected service.
  • Exposure: Internet-published OWA/ECP/EWS/MAPI endpoints increase credential-abuse opportunity, but an internal or VPN-authenticated attacker can also exploit the authorization weakness.
  • Impact: Read access to other users’ messages and attachments within the same Exchange organization. Cross-tenant access is not reported.
  • Unaffected/customer action: Exchange Online is service-side protected; customers need only update any on-premises Exchange servers and Exchange Management Tools workstations that remain in the environment.

Why this matters

Mailbox confidentiality failures can expose credentials, password-reset links, legal or financial records, and material useful for business-email compromise. Because a malicious request is authenticated, perimeter controls may treat it as legitimate and there may be no failed sign-in. Patch verification is the primary control; mailbox-audit and IIS correlation are needed to identify abnormal cross-mailbox access where the appropriate telemetry exists.

Exploitation Status

No confirmed active exploitation as of October 6, 2026. Microsoft said it identified the issue internally and was not aware of exploitation. No public exploit path, request signature, actor infrastructure, or IOC set was published. Cross-mailbox audit anomalies are therefore behavioral leads, not CVE-specific proof.

What this hunt looks for

Affected Exchange versions, actor-versus-mailbox-owner mismatches, one identity reading multiple mailboxes, new access sources, scripted or EWS clients, Exchange IIS endpoint bursts, related delegation changes, and new successful logons to Exchange servers.

Required logs

Authoritative on-premises Exchange inventory; Exchange mailbox item-access auditing ingested into OfficeActivity or an equivalent custom table; W3CIISLog for client-endpoint context; and Windows Security Events for successful-logon context. Office 365 audit ingestion alone does not prove on-premises mailbox coverage.

Hunt 1 — First-pass Exchange product and version inventory

let lookback = 14d;
DeviceTvmSoftwareInventory
| where Timestamp >= ago(lookback)
| where SoftwareName has "Exchange Server" or SoftwareName has "Microsoft Exchange"
| summarize LastSeen=max(Timestamp), Devices=make_set(DeviceName, 50), DeviceCount=dcount(DeviceId) by SoftwareVendor, SoftwareName, SoftwareVersion
| order by SoftwareName asc, SoftwareVersion asc

Hunt 2 — Mail item access where actor differs from mailbox owner

let lookback = 30d;
OfficeActivity
| where TimeGenerated >= ago(lookback)
| where OfficeWorkload =~ "Exchange"
| where Operation in~ ("MailItemsAccessed", "MessageBind", "FolderBind")
| extend Actor=tolower(UserId), Owner=tolower(tostring(column_ifexists("MailboxOwnerUPN", ""))), Src=tostring(column_ifexists("ClientIP", "")), Client=tostring(column_ifexists("ClientInfoString", ""))
| where isnotempty(Owner) and Actor != Owner
| project TimeGenerated, Actor, Owner, Operation, Src, Client, ResultStatus, Parameters, Folders, AffectedItems
| order by TimeGenerated desc

Hunt 3 — One identity accessing multiple mailbox owners

let lookback = 30d;
OfficeActivity
| where TimeGenerated >= ago(lookback) and OfficeWorkload =~ "Exchange"
| where Operation in~ ("MailItemsAccessed", "MessageBind", "FolderBind")
| extend Actor=tolower(UserId), Owner=tolower(tostring(column_ifexists("MailboxOwnerUPN", ""))), Src=tostring(column_ifexists("ClientIP", ""))
| where isnotempty(Owner) and Actor != Owner
| summarize Events=count(), MailboxCount=dcount(Owner), Mailboxes=make_set(Owner, 50), Operations=make_set(Operation, 10), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by Actor, Src, bin(TimeGenerated, 1h)
| where MailboxCount >= 3 or Events >= 20
| order by MailboxCount desc, Events desc

Hunt 4 — New source IP for cross-mailbox item access

let baseline = 30d;
let recent = 2d;
let Historical = OfficeActivity
| where TimeGenerated between (ago(baseline) .. ago(recent)) and OfficeWorkload =~ "Exchange"
| where Operation in~ ("MailItemsAccessed", "MessageBind", "FolderBind")
| extend Actor=tolower(UserId), Owner=tolower(tostring(column_ifexists("MailboxOwnerUPN", ""))), Src=tostring(column_ifexists("ClientIP", ""))
| where isnotempty(Owner) and Actor != Owner
| summarize by Actor, Src;
OfficeActivity
| where TimeGenerated >= ago(recent) and OfficeWorkload =~ "Exchange"
| where Operation in~ ("MailItemsAccessed", "MessageBind", "FolderBind")
| extend Actor=tolower(UserId), Owner=tolower(tostring(column_ifexists("MailboxOwnerUPN", ""))), Src=tostring(column_ifexists("ClientIP", "")), Client=tostring(column_ifexists("ClientInfoString", ""))
| where isnotempty(Owner) and Actor != Owner
| join kind=leftanti Historical on Actor, Src
| project TimeGenerated, Actor, Owner, Src, Client, Operation, ResultStatus
| order by TimeGenerated desc

Hunt 5 — EWS or scripted clients performing cross-mailbox reads

let lookback = 30d;
OfficeActivity
| where TimeGenerated >= ago(lookback) and OfficeWorkload =~ "Exchange"
| where Operation in~ ("MailItemsAccessed", "MessageBind", "FolderBind")
| extend Actor=tolower(UserId), Owner=tolower(tostring(column_ifexists("MailboxOwnerUPN", ""))), Src=tostring(column_ifexists("ClientIP", "")), Client=tostring(column_ifexists("ClientInfoString", "")), UA=tostring(column_ifexists("UserAgent", ""))
| where isnotempty(Owner) and Actor != Owner
| where Client has_any ("EWS", "REST", "PowerShell", "ExchangeWebServices") or UA has_any ("python", "curl", "powershell", "ExchangeServicesClient")
| project TimeGenerated, Actor, Owner, Src, Client, UA, Operation, ResultStatus, AffectedItems
| order by TimeGenerated desc

Hunt 6 — Exchange IIS bursts against mailbox-access endpoints

let lookback = 30d;
W3CIISLog
| where TimeGenerated >= ago(lookback)
| where csUriStem has_any ("/ews/", "/mapi/", "/owa/", "/ecp/")
| extend User=tolower(csUserName), Src=cIP, Status=tostring(scStatus), Endpoint=tolower(csUriStem)
| summarize Requests=count(), Successes=countif(Status startswith "2"), Endpoints=make_set(Endpoint, 20), UserAgents=make_set(csUserAgent, 10), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by sComputerName, Src, User, bin(TimeGenerated, 10m)
| where Requests >= 100 or (Successes >= 50 and array_length(Endpoints) >= 2)
| order by Requests desc

Hunt 7 — Delegation or mailbox-permission changes near unusual access

let lookback = 30d;
OfficeActivity
| where TimeGenerated >= ago(lookback) and OfficeWorkload =~ "Exchange"
| where Operation in~ ("Add-MailboxPermission", "Add-RecipientPermission", "Set-Mailbox", "New-ManagementRoleAssignment", "UpdateCalendarDelegation")
| extend Actor=tolower(UserId), Src=tostring(column_ifexists("ClientIP", ""))
| project TimeGenerated, Actor, Src, Operation, ResultStatus, Parameters, ObjectId, ExternalAccess
| order by TimeGenerated desc

Hunt 8 — Successful Windows logons to Exchange servers from new sources

let baseline = 30d;
let recent = 2d;
let ExchangeHosts = DeviceTvmSoftwareInventory
| where Timestamp >= ago(14d)
| where SoftwareName has "Exchange Server" or SoftwareName has "Microsoft Exchange"
| distinct DeviceName;
let Known = SecurityEvent
| where TimeGenerated between (ago(baseline) .. ago(recent)) and EventID == 4624
| where LogonType in (3, 8, 10)
| summarize by Computer, Account, IpAddress;
SecurityEvent
| where TimeGenerated >= ago(recent) and EventID == 4624
| where LogonType in (3, 8, 10)
| join kind=inner ExchangeHosts on $left.Computer == $right.DeviceName
| join kind=leftanti Known on Computer, Account, IpAddress
| project TimeGenerated, Computer, Account, IpAddress, LogonType, AuthenticationPackageName, LogonProcessName, WorkstationName
| order by TimeGenerated desc

Detection Notes

  • Hunts 2–5 are the most relevant behavioral detections, but they depend on audit records containing both the acting identity and mailbox owner. Legitimate shared-mailbox delegates, eDiscovery, compliance tooling, backup products, migration tools, and service accounts can produce the same actor/owner mismatch.
  • Build an allowlist from approved delegation and service-account inventories before escalating high-volume access. An identity reaching multiple high-value mailboxes from a new source or unfamiliar client is higher signal than one known delegate accessing one shared mailbox.
  • MailItemsAccessed availability, aggregation, licensing, and retention differ by Exchange deployment and audit configuration. MessageBind and FolderBind are included as legacy alternatives but may not be present.
  • IIS logs expose endpoint, user, IP, status, and volume but usually cannot establish the target mailbox or prove unauthorized content disclosure. Use Hunt 6 for triage and correlate it with mailbox auditing.
  • Hunt 7 is contextual: CVE-2026-96940 does not require a permission change. The query helps separate legitimate new delegation from unexplained access and can identify an alternative attack path.
  • Hunt 8 depends on Defender inventory and Windows Security Events being ingested with compatible host naming. Adjust the host join for FQDN/short-name differences.
  • No public request path or exploit signature was released. Do not treat a mailbox-owner mismatch alone as proof of CVE exploitation.