On the campaign’s escalation day, 15 of the 23 impacted organizations had MFA turned on. It didn’t matter. Their attacker never saw an MFA prompt — because the login request never went through a browser at all.

TL;DR

  • Between June 12–26, 2026, activity from LSHIY LLC’s IPv6 range compromised 78 Microsoft accounts across 64 organizations, firing over 81 million login attempts in 14 days (Huntress).
  • The core technique wasn’t clever malware — it was recycled breached credentials combined with the OAuth 2.0 ROPC (Resource Owner Password Credentials) flow, which sends a password straight to Microsoft’s /token endpoint with no interactive MFA prompt.
  • Of 23 impacted organizations Huntress analyzed on June 22, 15 had MFA misconfigured (wrong app scope, admin-only groups, “trusted location” loopholes) and 8 had no MFA policy at all.
  • This isn’t an isolated incident: Huntress reports a 155x increase in credential spray volume across its customer base over six months, averaging 1,964 failed spray attempts per tenant, per month.
  • The fix isn’t “turn on MFA” — most of these orgs already had. It’s closing the specific gap that lets a password alone still be enough.

Why This Matters

If your organization runs Microsoft 365 or Azure and you believe MFA “handles” credential attacks, this campaign is the counter-example. It matters for anyone responsible for Conditional Access policy, identity security, or SOC detection engineering — not because MFA failed as a concept, but because a legacy authentication path exposed accounts where Conditional Access did not actually require strong authentication. If you administer Entra ID (Azure AD), this is worth 15 minutes of policy review today.

Table of Contents


What Happened: The LSHIY Campaign

Everything in this section is as reported by Huntress in their own incident writeup — this is their confirmed telemetry, not third-party speculation.

Infrastructure. Huntress tied most of the activity to LSHIY LLC, operating from autonomous system AS32167 (registered June 14, 2021), using an IPv6-only range (2a0a:d683::/32) with no IPv4 equivalent — itself an unusual footprint. A secondary ASN, AS955 (registered June 22, 2022), was also linked to the same operator. Registration records point to Hong Kong, Wuhan, and a shared office space (TKO Suites) in New York.

Scope and volume. Between June 12 and 26, 2026, Huntress tracked 78 compromised Microsoft accounts across 64 organizations. The attack fired more than 81 million login attempts in that 14-day window — this was not a handful of guesses, it was industrial-scale credential testing.

Timeline:

DateActivity
June 12–21Steady baseline: 2–4 accounts compromised per day
June 19Spike to 12 accounts in a single day
June 22Major escalation: 30 accounts across 23 businesses
June 25–26Campaign continues

Credential source. Huntress states the attacker replayed “old username/password combinations where the credentials were previously breached but had never been rotated” — this is credential stuffing feeding a spray, not a novel breach against the victims themselves.

Geographic evasion. Source IPs geolocated inconsistently — some to China, others to Nebraska, US. That inconsistency wasn’t noise; it let the attacker’s traffic slip past conditional access rules that only trigger on “untrusted” geographies.


Red Team: How Password Spray + ROPC Actually Works

The spray, in plain terms

Traditional brute forcing tries many passwords against one account — and trips lockout policies fast. Password spraying flips this: try a small number of likely passwords (or, as here, previously breached real passwords) against many accounts, spaced out to stay under per-account lockout thresholds. MITRE ATT&CK catalogs this as T1110.003 – Brute Force: Password Spraying, under the Credential Access tactic.

Think of it like trying one spare key on every door in an apartment building instead of trying every key on one door — the security guard watching one door never notices, because the “attack” against it is a single, unremarkable attempt.

The ROPC trick that made MFA irrelevant

This is the part that makes the LSHIY case worth studying rather than filing under “yet another spray.”

Modern Microsoft 365 / Entra ID logins normally go through an interactive flow: browser redirect → password field → MFA challenge (push notification, code, etc.) → token issued. OAuth 2.0 ROPC (Resource Owner Password Credentials) is a different, older grant type built for a specific legacy use case: a trusted application collects a username and password directly (no browser, no redirect) and exchanges them for a token in a single API call to Microsoft’s /token endpoint.

The catch: because there’s no interactive session, there’s no interactive MFA challenge either. Microsoft explicitly warns that ROPC is incompatible with MFA: if the user must satisfy MFA, the request should be blocked rather than challenged. Red Canary’s write-up on BAV2ROPC and Embrace The Red’s “So, you think you have MFA?” both cover the same underlying weakness LSHIY exploited at scale. In effect:

Normal login: user → browser → password → MFA prompt → token
ROPC login: tool → password → /token endpoint → token (no MFA step exists)

An attacker with a valid breached password doesn’t need to phish a session or bypass a push notification — they just need a client that speaks ROPC (a script, curl, or in this campaign, tooling built around the Azure CLI authentication path) and a Conditional Access policy that does not fail closed for that sign-in path.

Why MFA Didn’t Stop It

Huntress’s own breakdown of the 23 organizations impacted on June 22 (the escalation day) is the most useful part of this case, because it shows exactly which MFA configurations failed and how:

GapOrgs affectedWhy it failed
MFA scoped to specific apps onlySome of 15Policy targeted e.g. “Microsoft Admin Portals,” not “All Cloud Apps” — ROPC traffic against Azure CLI / Graph fell outside scope
MFA scoped to admin groups onlySome of 15Attackers targeted regular users, who had no MFA requirement at all
”Trusted location” exemptionSome of 15Attacker IPs geolocated (incorrectly, per the geo-inconsistency above) as US-based “trusted” traffic
MFA in “Report-only” mode2 orgsPolicy existed but was never switched from audit to enforce
No MFA policy8 orgsNothing to bypass — password alone was sufficient

The pattern across all of these: MFA existed as a checkbox, not as a universally enforced control. That distinction is the entire story.


Blue Team: Detecting Password Spray and ROPC Abuse

Detect the ROPC flow itself

Entra ID sign-in logs include an AuthenticationProtocol field that is populated with "ropc" when that grant type is used — this is documented Microsoft telemetry, and Elastic ships a prebuilt detection rule built directly on it. A starting KQL query for Sentinel / Log Analytics:

// Illustrative starting point — tune against your own tenant baseline.
// Static ROPC filters alone produce noise from legitimate service accounts.
SigninLogs
| where AuthenticationProtocol == "ropc"
| where ResultType == 0 // successful sign-in
| summarize Accounts = dcount(UserPrincipalName),
Attempts = count(),
IPs = make_set(IPAddress)
by AppDisplayName, bin(TimeGenerated, 1h)
| where Accounts > 5

Treat this as a hunting starting point, not a drop-in rule — as security researchers who’ve built this detection note, a bare AuthenticationProtocol == "ropc" filter alone flags known-good automation too. Baseline ROPC usage per app/user over 14 days before alerting on deviations.

Detect the spray pattern itself

Independent of ROPC, the spray pattern (many accounts, few passwords, tight time window, single source or IP range) is a classic Sigma-style detection:

title: Potential Password Spray Against Cloud Identity
status: experimental
logsource:
product: azure
service: signinlogs
detection:
selection:
ResultType: [50126, 50053] # invalid credentials / account locked
timeframe: 1h
condition: selection | count(distinct UserPrincipalName) by IPAddress > 15
level: high

MFA / Conditional Access checklist

Given the exact gaps LSHIY exploited, audit your tenant against this list today:

  • Conditional Access MFA policy targets “All Cloud Apps”, not a named subset
  • Policy targets “All Users”, not just admin/privileged groups
  • No blanket exemption for “trusted locations” without verifying how that trust is determined
  • No policy left in Report-only mode past initial testing
  • Legacy/basic authentication is blocked tenant-wide
  • ROPC and other non-interactive grants are explicitly restricted to apps that genuinely require them

Mitigations

ActionWhy it mattersPriority
Enforce MFA for All Users, All Cloud Apps, all client app types, unconditionallyCloses every scoping gap Huntress found (app-only, admin-only, location-exempt policies)Critical
Configure Conditional Access to actively deny sign-ins Microsoft’s Entra platform flags as requiring strong authentication the client cannot satisfy (this is how CA can fail-closed against ROPC, per Huntress’s own remediation guidance)ROPC has no MFA challenge mechanism — a correctly scoped policy denies the sign-in outright instead of letting it throughCritical
Restrict the Azure CLI application (and other native/legacy clients) for non-admin usersRemoves a major ROPC-capable client from the hands of the accounts attackers actually targetedHigh
Rotate any credentials known to appear in breach dumps, even if “nothing happened yet”LSHIY’s initial access was entirely recycled, never-rotated breached passwordsHigh
Triage spray alerts by credential validity (did a login actually succeed?), not raw volume81 million attempts is meaningless without knowing which handful actually returned a valid tokenMedium
Move any Conditional Access policy out of Report-only once testedTwo organizations in this campaign had the right idea and never flipped the switchMedium

What You Can Do Today

  1. Pull your Conditional Access policies and check the scope field first — “All Cloud Apps” and “All Users,” not a curated list. This single check would have closed the gap at 15 of the 23 organizations Huntress analyzed.
  2. Search your Entra sign-in logs for AuthenticationProtocol == "ropc" over the last 30 days and confirm every result maps to a known, intended automation — not an unrecognized script or IP.
  3. Confirm no policy is stuck in Report-only. It takes one query and prevents this exact failure mode.
  4. Cross-reference active user passwords against known breach corpora (e.g., via Have I Been Pwned’s password API or your identity provider’s built-in leaked-credential detection) and force rotation on matches.


Sources

  1. LSHIY Password Spray Attack — Huntress (primary source for all campaign-specific facts and figures)
  2. T1110.003 – Brute Force: Password Spraying — MITRE ATT&CK
  3. Microsoft identity platform and OAuth 2.0 Resource Owner Password Credentials — Microsoft Learn
  4. When MFA isn’t an option: The legacy of ROPC — Red Canary
  5. Legacy authentication: The curious case of BAV2ROPC — Red Canary
  6. ROPC - So, you think you have MFA? — Embrace The Red
  7. Entra ID OAuth ROPC Grant Login Detected — Elastic Security