The hotel Wi-Fi sign-in page was the compromise
Storm-2945 compromised the shared captive portal services that hotels, conference centres and similar venues run, then manipulated DNS and HTTP traffic on those networks to send guests to attacker infrastructure. Zscaler found compromised gateways in several US cities, in India and in Saudi Arabia. What the traveller sees is the sign-in page they were expecting. What follows is Microsoft 365 credential harvesting, device code phishing and malware delivery. The victims here are not the hotels. They are whoever stayed in them, across every sector.
What worked
Zscaler names no control that stopped an instance of this in a customer environment. The write-up lists the product settings that would have, which is a different claim, and the entry below is where the useful reading is.
What failed
Multi-factor authentication, and not because it was absent. The device code pages abuse the Entra ID authentication flow itself. The victim is shown a genuine Microsoft prompt and authenticates the attacker’s session rather than their own, which as Zscaler puts it "can bypass conventional multifactor authentication (MFA)" because no credential is being relayed and nothing is being faked. The user completes a real login. The attacker ends up with a device registered in the tenant.
The second failure is an assumption about the network. A laptop that drops its tunnel on an untrusted network so the captive portal will load is a laptop with no inspection at the exact moment it is talking to a hostile DNS server. That configuration is common because it is often the only way captive portals work at all, which makes it a design tension rather than an oversight, and this campaign is what the tension costs.
The number
500 MB
the per-cycle upload cap built into the CornFlake payload, which also limits itself to 1,000 files a cycle and collects 18 categories of host information.
What to do instead
Treat the captive portal as hostile, because in this campaign it was. The practical control is that the corporate tunnel comes up before anything else and stays up, in full rather than with a local proxy exception, and that DNS goes to your resolver instead of the network’s. Zscaler’s version of this is a list of their own settings, but the principle underneath it ports to whatever you run.
Then block device code flow in Conditional Access. It is the single change here that closes the identity half of the attack. Almost nobody uses the flow for real work, the people who do can be scoped into an exception, and without it the genuine Microsoft prompt that makes this work never appears.
Then alert on new device registrations in Entra ID, because that is what a successful device code phish looks like from your side of the glass. It is one of the few signals in this chain that reaches your tenant at all, given that everything before it happened on somebody else’s network.
And have the travel conversation, which is cheaper than any of the above. A phone hotspot removes the entire attack. Say so before the conference rather than after it.