Azure CLI Password Spray: Building an IOC Feed (IPv6/ASN) and Detecting Bursts
Azure CLI password spray detection: build an ASN/IPv6 IOC feed (AS32167 LSHIY), tune Entra ID thresholds, and avoid false positives on legitimate CLI usage.
Between June 12 and June 26, a password spray campaign generated more than 81 million authentication attempts against Microsoft Entra ID accounts, documented by Huntress. The vector: the Azure CLI client, whose user-agent and appId were hijacked to fire authentication requests at scale. Nearly all the traffic came from a single network operator, AS32167 (LSHIY LLC), from IPv6 ranges. Reported outcome: 78 compromised accounts across the affected organizations.
This is not another generic credential-stuffing wave. It is an actionable signal right now: an identified ASN range, a precise client pattern, an unusual time window. The question for a security lead or M365 administrator is not "should I worry about password spray in general" but "are my accounts currently targeted by this specific campaign, and which blocklist do I activate today."
Why AS32167 and IPv6 change the picture
The choice of IPv6 is deliberate. The IPv6 address space is so vast that blocking IP by IP is pointless: the attacker rotates source addresses on every attempt. Blocking by ASN (the autonomous system number, the operator or hosting provider announcing those ranges) is the only approach that holds, because the infrastructure behind an ASN leased for offensive purposes does not churn as fast as individual addresses.
AS32167 (LSHIY LLC) is the number observed in this campaign. Relying on it alone would be fragile: operators of this kind of infrastructure routinely rotate from one ASN to another to dodge static blocklists. That is why you need a feed, not a list frozen in time.
Building the IOC feed: IPv6/ASN ranges
The repeatable method:
- Start from the documented fact. The public advisory identifies the ASN, the time window, the volume. That is raw material, not a proof of concept to copy verbatim.
- Resolve the IPv6 prefixes announced by the ASN. An ASN announces blocks (prefixes) via BGP; pull them from regional registries (RIPE, ARIN) or tools like
bgp.he.net/whois -h whois.radb.net. - Check cross-source corroboration. An ASN should only enter a feed you share or resell if corroborated by multiple independent sources (the Huntress advisory, your own sign-in logs, possibly a second public report), never on a single isolated report.
- Apply "never block" hygiene. Confirm no legitimate prefix (shared CDN, mixed-use public cloud) was pulled in by mistake before it goes into a conditional blocklist.
Example feed structure consumable by a conditional access policy:
# IOC feed excerpt - conditional blocklist ASN/IPv6
indicators:
- type: asn
value: 32167
name: "LSHIY LLC"
first_seen: "2026-06-12"
last_seen: "2026-06-26"
corroboration: 2
context: "password_spray_azure_cli"
- type: ipv6_range
value: "2a0e:aa07::/32"
asn: 32167
confidence: high
action: conditional_blockThe key point: the feed does not say "block this IP," it says "this context (ASN plus behavior) warrants stronger conditional access." That nuance is what keeps a threat intelligence signal from turning into a production outage.
Entra ID rule: bursts on the Azure CLI client
The observed vector specifically abuses the Azure CLI client (appId 04b07795-8ddb-461a-bbee-02f9e1bf7b46, well known, with its characteristic user-agent python/... azure-cli/...). A spray campaign through that client shows up as the combination of three signals in Entra ID SigninLogs:
- appDisplayName = "Azure CLI" or the matching appId, at abnormal volume
- Burst of attempts in a short window (minutes) from few distinct network sources sharing the same ASN
- Outside normal business hours for the organization (night, weekend, for usage that should be daytime and workday-bound)
Example Sigma rule applied to SigninLogs:
title: Azure CLI Authentication Burst Outside Business Hours
id: 8e2f4a1c-azure-cli-spray
status: experimental
logsource:
product: azure
service: signinlogs
detection:
selection:
AppDisplayName: "Azure CLI"
ResultType:
- '50126' # invalid username or password
- '50053' # account locked
timeframe: 10m
condition: selection | count() by SourceASN > 20
falsepositives:
- Legitimate CI/CD pipelines using Azure CLI service principals
- Administrators scripting bulk operations
level: highThe 20-failure threshold in 10 minutes is not universal: it needs calibrating against the organization's normal CLI authentication volume. That is the next point.
Thresholds tuned for SMBs: how many attempts before blocking
An SMB does not have the authentication volume of a large enterprise, which is actually an advantage: abnormal bursts stand out more clearly. Reasonable starting orders of magnitude:
| Context | Trigger threshold | Action |
|---|---|---|
| Failures per single source / 10 min | > 15 | Alert |
| Cumulative failures per ASN / 10 min | > 30 | Conditional access (stronger MFA or block) |
| Azure CLI client failures outside business hours | > 5 in a burst | Immediate alert |
| Distinct accounts targeted by the same ASN | > 3 accounts | Campaign correlation, ASN block |
These thresholds tighten with history: after two to three weeks of observation, adjust to the organization's real baseline rather than generic values.
Anti-false-positive: do not block IPv6 blindly
This is the costliest trap. The Azure CLI client is used daily for perfectly legitimate purposes:
- CI/CD pipelines (GitHub Actions, GitLab CI, Azure DevOps) authenticating via a service principal with the same Azure CLI appId
- Administrators scripting bulk operations from workstations or jump hosts
- Internal automation (provisioning scripts, scheduled exports)
Before/after on the same alert:
Before (naive rule): block any IPv6 associated with an Azure CLI authentication failure. Result: a legitimate CI pipeline that fails once on an expired secret triggers a block, the build breaks, the team opens a ticket, and trust in the alerts erodes.
After (targeted rule): only trigger on the combination of suspicious ASN plus burst volume plus outside business hours, with an explicit allowlist of known ASNs and IPv6 ranges for the organization (CI/CD provider, corporate VPN, identified admin hosts). The legitimate pipeline, failing from an allowlisted range during business hours, never triggers the stronger conditional access.
The rule to keep: target the ASN and the spray pattern, never IPv6 as a protocol in itself.
Where it plugs in: IOC feed plus Sigma rule, two complementary layers
The IOC feed (IP/ASN) feeds the conditional access policy on the Entra ID side: the static layer, fast to activate, that blocks or hardens authentication based on network origin. The Sigma rule on SigninLogs (Azure CLI appDisplayName, mass failures) is the behavioral layer: it catches the pattern even if the attacker switches ASN tomorrow.
The two are complementary, not interchangeable. The IOC feed alone misses any new infrastructure leased after the advisory is published. The behavioral rule alone misses the chance to block upstream, before the first successful attempt, an ASN already known to be hostile.
Maintenance: infrastructure that keeps moving needs a feed that keeps up
The point most often overlooked: attack infrastructure is not static. An ASN used today for password spray may be abandoned in two weeks in favor of another leased block elsewhere. An IOC feed frozen at June 26 becomes stale within weeks.
Recommended cadence:
- ASN/IPv6 feed update: weekly at minimum, ideally correlated with new report publications (Huntress, CISA, threat intelligence vendors)
- Entra ID threshold re-evaluation: monthly, or immediately after a change in normal volume (new CI tool, headcount growth)
- Combine static IOC with behavioral detection: never rely solely on one or the other. The static layer blocks known bad fast; the behavioral layer catches what is not known yet.
In summary
This AS32167/LSHIY campaign is a concrete case of password spray via the Azure CLI client, a directly exploitable initial-access vector for organizations hosted on Azure/M365. The response comes down to two layers: a corroborated, maintained ASN/IPv6 IOC feed consumed by conditional access, and a behavioral rule on SigninLogs that catches the burst pattern even as infrastructure changes. Anti-false-positive work is not optional: whitelisting legitimate CLI usage before activation is what separates useful detection from a control that breaks pipelines.
That is exactly the discipline (documented fact, corroborated ASN ranges, calibrated thresholds, verified anti-FP) behind the ThreatClaw IOC feed: indicators are updated at the pace attack infrastructure actually moves, not frozen at an advisory's publication date.
Related articles
The Verizon 2026 report puts vulnerability exploitation ahead as the top initial access vector and confirms ransomware mainly hits SMBs. The concrete actions.
Via vishing, actor O-UNC-066 registers its own FIDO2 passkey in the victim's account. Detect the method addition correlated with a risky sign-in.
The best IOC feeds are largely free. So what do you actually pay for? A practical comparison of abuse.ch, AlienVault OTX, MISP and commercial threat intel, and where a curated aggregation layer earns its place.
A campaign impersonates Interpol to trap SMBs: Proton Drive link, encrypted archive, executable disguised as a video. The indicators and the detection rule.