Token replay attack on Microsoft 365: check Entra ID for the 1337 Services campaign
Short answer: Huntress reports a Microsoft 365 campaign that stole sessions after MFA and
replayed them from 193.26.115.0/24 (1337 Services GmbH). Search both user sign-in tables for that
range from 14 July 2026. Then look for what survives a password reset: Entra devices named
DESKTOP- plus eight uppercase hex characters, MFA methods deleted and replaced, and hidden inbox
rules. Revoke sessions and reset the password, then remove the devices, methods and rules
yourself, because Huntress says “A password reset alone does not remove attacker-registered
devices or MFA methods.”
Every campaign fact on this page comes from the Huntress write-up of 22 October 2026. Check it for updates before you act.
What did Huntress report?
Section titled “What did Huntress report?”Huntress tracked the campaign from 14 July to 22 September 2026. Across 79 organizations it saw at least 497 successful sign-ins and more than 200,000 failed attempts. The attacker got sessions in three ways: adversary-in-the-middle (AiTM) relays that captured the session after the victim completed MFA, device-code phishing, and social engineering during legitimate logins.
| Phase (2026) | What Huntress reports |
|---|---|
| 1: 14 Jul – 3 Aug | Replay from 193.26.115[.]221 and 193.26.115[.]199. Rogue devices registered in 13 of 14 incidents on 14 July. Inbox rules created; one account sent spam. |
| 2: from 17 Aug | Replay from 193.26.115[.]16 and 193.26.115[.]21. Adds device-code phishing, MFA methods wiped and re-registered, more inbox rules. |
| 3: 11 – about 15 Sep | 193.26.115[.]72 made 303 successful sign-ins across 29 organizations. A payroll-themed email went to an external CPA. |
| 4: 2 – 22 Sep | AiTM relay at Evoxt Sdn. Bhd. paired with replay from 193.26.115[.]210. The final takeover on 22 September came about four minutes after the victim completed MFA. |
After replay the attacker registered at least 48 rogue Entra devices. “In 19 organizations, the
victim’s existing MFA methods were wiped and a new method registered within three hours” of the
first sign-in from a campaign address, sometimes an authenticator labelled “iPhone 13”. Inbox rules
with throwaway names such as ., sss, s and d moved or deleted mail about payroll, banking or
specific contacts.
Why didn’t MFA or a password reset stop it?
Section titled “Why didn’t MFA or a password reset stop it?”Because the attacker didn’t need either. A stolen session was created after the victim passed MFA, so replaying it doesn’t ask for MFA again (our reading of how AiTM works; Huntress describes the sessions as captured “after victims completed MFA”). Huntress also notes that “a password reset alone does not invalidate the access token”. Revoking refresh tokens stops new tokens, but an access token already issued keeps working until it expires; the session revocation guide explains the window.
The persistence steps are the bigger problem. A registered device and an attacker-owned MFA method let the attacker start a fresh session after you have reset the password and revoked everything.
Which indicators should I search for?
Section titled “Which indicators should I search for?”From the Huntress write-up:
| Indicator | Value |
|---|---|
| Replay hosts (1337 Services GmbH, AS210558) | 193.26.115[.]221, .199, .16, .21, .72, .210 |
| Other 1337 Services addresses | 124.198.132[.]33, 45.83.31[.]44, 192.159.99[.]172 |
| AiTM relays | 185.238.2[.]195, 2400:8d60:2::1:841d:5dd |
| Inbox-rule host | 167.148.41[.]96 |
| Client IDs | d3590ed6-52b3-4102-aeff-aad2292ab01c (Microsoft Office), 29d9ed98-a469-4536-ade2-f981bc1d605e (Authentication Broker), 4765445b-32c6-49b0-83e6-1d93765276ca (OfficeHome) |
| Device names | DESKTOP- plus exactly eight uppercase hex characters. Huntress notes Windows’ default is seven alphanumeric characters. |
Huntress describes two attacker builds. Build A is scripted: the node user agent, the Office
and Authentication Broker client IDs, targeting Graph, Exchange, SharePoint and the Device
Registration Service. Build B is a browser: a current Chrome or Edge user agent and OfficeHome.
Don’t rely on the IP list alone. Huntress says “Blocking any single address would have stopped one phase at most.” The /24 covered all six main replay hosts, but the operator also used 1337 Services addresses outside it, and the inbox rules were created from VPN and rented hosting addresses, not from 1337 Services. A clean result for the /24 doesn’t clear the tenant.
How do I check my tenant?
Section titled “How do I check my tenant?”None of these queries has been run in a lab tenant yet. Test them in your own workspace and check column contents against one real row first. They start on 1 July 2026, so they only see the whole campaign if your workspace keeps sign-in and audit logs that long.
Step 1: Did anything sign in from the campaign infrastructure?
Section titled “Step 1: Did anything sign in from the campaign infrastructure?”let campaignIPs = dynamic(["124.198.132.33", "45.83.31.44", "192.159.99.172", "185.238.2.195", "167.148.41.96"]);union (SigninLogs | extend Log = "Interactive"), (AADNonInteractiveUserSignInLogs | extend Log = "NonInteractive")| where TimeGenerated > datetime(2026-07-01)| where ipv4_is_in_range(IPAddress, "193.26.115.0/24") or IPAddress in (campaignIPs) or IPAddress startswith "2400:8d60:2:"| summarize Rows = count(), Apps = make_set(AppDisplayName, 10), Resources = make_set(ResourceDisplayName, 10), UserAgents = make_set(UserAgent, 5), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, IPAddress, ResultType, Log| sort by FirstSeen ascResultType is a string, so successes are "0", not 0. Read the results in two groups:
"0"from a replay host: a token was issued to the attacker. Treat the account as compromised and do everything under What should I do?.- 53003: Huntress says to treat these Conditional Access blocks “as a sign of a valid credential, not a save.” Reset the password.
- Hits on the AiTM relays (185.238.2[.]195, the IPv6 address): our reading is that these show
where the victim’s own sign-in passed through the relay, so the user was phished even if the
replay itself came from elsewhere. The
startswithmatch for the IPv6 relay is loose on purpose; check how your logs write IPv6 addresses.
IP caveat for confidential clients. Microsoft’s
non-interactive sign-ins page
says: “The IP address of non-interactive sign-ins performed by confidential clients doesn’t match
the actual source IP of where the refresh token request is coming from. Instead, it shows the
original IP used for the original token issuance.” So in AADNonInteractiveUserSignInLogs a row
may show where the token was first issued rather than where it was replayed from. The Office and
broker clients in this campaign are public clients, so this matters less here (our reasoning), but
keep it in mind before you pivot on an IP from that table.
Step 2: Did the same tooling sign in from somewhere else?
Section titled “Step 2: Did the same tooling sign in from somewhere else?”Huntress recommends hunting for these sign-ins from hosting infrastructure, “especially with the
node or bare Mozilla/5.0 user agents.” This query looks for successful sign-ins with the
campaign’s client IDs and those user agents, from any IP:
let campaignClients = dynamic(["d3590ed6-52b3-4102-aeff-aad2292ab01c", "29d9ed98-a469-4536-ade2-f981bc1d605e", "4765445b-32c6-49b0-83e6-1d93765276ca"]);union SigninLogs, AADNonInteractiveUserSignInLogs| where TimeGenerated > datetime(2026-07-01)| where ResultType == "0"| where AppId in (campaignClients)| where UserAgent == "node" or UserAgent == "Mozilla/5.0"| summarize Rows = count(), Users = make_set(UserPrincipalName, 20), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by IPAddress, AutonomousSystemNumber, UserAgent, AppDisplayName, Type| sort by FirstSeen ascThe Office client ID is used by real Office apps every day, so the filter that matters is the user
agent. Look up the ASN of each result: a hosting or VPN provider is worth a timeline; your own ISP
and Microsoft are not. Huntress also names request types (OAuth2:Token, Cmsi:Cmsi,
Login:reprocess, OAuth2:Authorize). We haven’t found those in a documented SigninLogs
column, so the query doesn’t use them.
Step 3: Who signed in with device code flow?
Section titled “Step 3: Who signed in with device code flow?”Phase 2 added device-code phishing. Microsoft calls device code flow “a high-risk authentication
method that can be part of a phishing attack” and documents an Authentication protocol filter
with a Device code option, plus an original transfer method that is set to Device code
flow for sessions that started that way. Both exist as SigninLogs columns
(AuthenticationProtocol, OriginalTransferMethod):
SigninLogs| where TimeGenerated > datetime(2026-07-01)| where AuthenticationProtocol has "device" or OriginalTransferMethod has "device"| summarize Rows = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, AuthenticationProtocol, OriginalTransferMethod, ResultType| sort by FirstSeen ascMicrosoft’s docs show the portal labels, not the stored values, so the query matches loosely on “device”. Check the exact values in your workspace. Most tenants have very few legitimate device code sign-ins (meeting-room devices, CLI tools); every user that isn’t one of those needs a look.
Step 4: Are there rogue devices?
Section titled “Step 4: Are there rogue devices?”The quickest check is the device list itself. In PowerShell with Microsoft Graph:
Get-MgDevice -All -Property Id,DisplayName,TrustType,ApproximateLastSignInDateTime,RegistrationDateTime | Where-Object { $_.DisplayName -cmatch '^DESKTOP-[0-9A-F]{8}$' } | Select-Object DisplayName, Id, TrustType, RegistrationDateTime, ApproximateLastSignInDateTime-cmatch is case-sensitive, so only uppercase hex matches. A real Windows PC can, by chance, have a
name in this shape, so check the owner and registration date before acting. To see who registered
a device and from where, use the audit log. Add device, Add registered owner to device and
Add registered users to device are Core Directory activities in Microsoft’s audit reference;
Register device is listed under Device Registration Service:
AuditLogs| where TimeGenerated > datetime(2026-07-01)| where OperationName in ("Add device", "Register device", "Add registered owner to device", "Add registered users to device")| mv-expand Target = TargetResources| extend DeviceName = tostring(Target.displayName)| where DeviceName matches regex @"^DESKTOP-[0-9A-F]{8}$"| extend Actor = tostring(InitiatedBy.user.userPrincipalName), ActorIP = tostring(InitiatedBy.user.ipAddress)| project TimeGenerated, OperationName, DeviceName, Actor, ActorIP, Result| sort by TimeGenerated ascWhich target holds the device name may differ by activity (an owner change can also list the user as a target), which is why the query expands all targets. Check one row of each activity in your tenant. If a matching device shows up in PowerShell but not here, drop the name filter and look at what these activities record for device names in your logs.
Step 5: Were MFA methods deleted and replaced?
Section titled “Step 5: Were MFA methods deleted and replaced?”Huntress saw the victim’s methods wiped and a new one registered within three hours of the first campaign sign-in. This finds a deletion followed by a registration for the same user within three hours, from any IP, because the IP list alone isn’t enough. The activity names are from Microsoft’s audit reference (Authentication Methods, UserManagement category):
let methodEvents = AuditLogs| where TimeGenerated > datetime(2026-07-01)| where OperationName in ("User deleted security info", "Admin deleted security info", "User registered security info", "Admin registered security info")| extend Who = tolower(coalesce(tostring(TargetResources[0].userPrincipalName), tostring(InitiatedBy.user.userPrincipalName))), ActorIP = tostring(InitiatedBy.user.ipAddress), Detail = tostring(ResultReason);let deletes = methodEvents | where OperationName has "deleted"| project Who, DeletedAt = TimeGenerated, DeleteOp = OperationName, DeleteIP = ActorIP;let adds = methodEvents | where OperationName has "registered"| project Who, AddedAt = TimeGenerated, AddOp = OperationName, AddIP = ActorIP, Detail;deletes| join kind=inner adds on Who| where AddedAt between (DeletedAt .. DeletedAt + 3h)| project Who, DeletedAt, DeleteOp, DeleteIP, AddedAt, AddOp, AddIP, Detail| sort by DeletedAt ascFor each user it returns, line the times up with that user’s sign-ins from Steps 1 to 3. Then look
at the user’s current methods in the Entra admin center and ask the user about anything they don’t
recognise, including an authenticator called “iPhone 13”. Which field holds the method details
varies; check ResultReason and AdditionalDetails on one row.
Step 6: Are there hidden inbox rules?
Section titled “Step 6: Are there hidden inbox rules?”For each affected mailbox, in Exchange Online PowerShell:
Select-Object Name, Enabled, DescriptionMicrosoft documents -IncludeHidden as including “hidden Inbox rules in the results.” Look for
the short names Huntress saw (., sss, s, d) and for any rule that moves or deletes mail
about payroll, banking or particular contacts. Microsoft’s Outlook-rules guidance says to
“Look for rules that the user didn’t create, or any unexpected rules or rules with suspicious
names,” and to use Disable-InboxRule while you investigate. Huntress says some rules were
created through the Outlook REST API and from addresses outside 1337 Services, so the sign-in IP
from Step 1 won’t lead you to them.
What should I do?
Section titled “What should I do?”For each compromised account:
- Revoke sessions and reset the password. Huntress: “Revoke sessions and reset the
password.” Microsoft’s revoke-access procedure uses
Revoke-MgUserSignInSession -UserId $User.Idand says that afterwards “the user can’t gain new tokens for any application tied to Microsoft Entra ID.” Then prove it worked with 50173 rows, as in the session revocation guide. - Remove the rogue devices. Microsoft: “Disabling a device revokes the Primary Refresh Token (PRT) and any refresh tokens on the device.” Disable first so you keep the record for the investigation; deleting “Is a nonrecoverable activity.” Once you’re done, delete the device objects you’re sure are the attacker’s.
- Remove MFA methods the user doesn’t recognise, then have the user re-register.
- Disable or remove the inbox rules, and check what mail they moved or deleted, especially payroll and banking. In one Huntress case a payroll email went to an outside contact.
For the tenant:
- Close gaps in Conditional Access. Huntress recommends requiring MFA or blocking for all users, all cloud apps and all client app types, without exceptions, and says “Token replay attacks can be prevented with properly implemented Conditional Access Policies.” Our caveat: a requirement for MFA alone doesn’t stop the replay of a session that already passed MFA. What it does is remove the exceptions that let a sprayed password work without MFA.
- Block device code flow. Microsoft: “Microsoft recommends blocking device code flow wherever possible.” In Entra ID > Conditional Access > Policies, set Conditions > Authentication Flows to Device code flow and grant Block access. Microsoft says to start in Report-only and to exclude your break-glass accounts.
- Consider Token Protection. Microsoft describes it as a session control that “attempts to reduce token replay attacks by ensuring only device bound sign-in session tokens, like Primary Refresh Tokens (PRTs), are accepted.” It covers native apps for Exchange Online, SharePoint Online and Teams on supported Windows, macOS and iOS devices; browser support is limited to selected web apps for Azure Resource Manager. Our reading: Huntress’s browser-based Build B isn’t in scope for it, so treat it as one layer, as Microsoft itself says.
- Restrict device registration and user consent. Microsoft’s device settings let you limit who can register devices and require MFA to register or join; that MFA setting defaults to No. Huntress also recommends restricting user consent for new applications and hunting for new enterprise apps; the consent phishing guide covers that hunt.
- Prioritise by valid credentials, not spray volume. Huntress found that the most-sprayed
tenants weren’t necessarily the most compromised. Work through accounts with a
"0"or 53003 first; for the failed-attempt side, see the password spray guide.
For a related case where the compromised identity was a vendor’s app rather than a user, see investigating a compromised vendor app.
What can’t this guide tell me?
Section titled “What can’t this guide tell me?”- Whether you were affected if your logs don’t go back to July. Without sign-in and audit logs for the campaign window, Steps 1 to 5 can’t answer that; Steps 4 and 6 still show current devices and rules.
- Whether this is the whole campaign. The numbers, IPs and phases are what Huntress saw in its own customers’ tenants. The operator rotated addresses, and Huntress’s list may not be complete.
- What the attacker read. Sign-in logs show the token being issued, not each mailbox or file access.
- Exact log values. The
AuthenticationProtocolandOriginalTransferMethodvalues, and where device names and method details sit inAuditLogs, need checking against your own rows.
The queries are based on Microsoft’s schema documentation and the Huntress write-up, and have not been reproduced in a lab tenant yet. Until they have, the page is marked as lab test pending.
Sources
- Huntress: M365 token spray and replay campaign compromises business email accounts (22 Oct 2026)
- Revoke user access in Microsoft Entra ID
- Manage device identities (Microsoft Entra)
- Microsoft Entra audit log activities
- SigninLogs table reference (Azure Monitor)
- Non-interactive user sign-ins
- Authentication flows in Conditional Access
- Block authentication flows with Conditional Access policy
- Token Protection in Microsoft Entra Conditional Access
- Detect and remediate Outlook rules and custom forms injections attacks
- Get-InboxRule (Exchange PowerShell)