Zscaler Blog
Get the latest Zscaler blog updates in your inbox
CaptiveCrunch: Midnight Blizzard Weaponizes Hotel Wi-Fi Captive Portals to Steal Microsoft 365 Credentials
Introduction
On July 31, Microsoft Threat Intelligence reported an ongoing credential theft campaign tracked as CaptiveCrunch. Microsoft attributes this activity to Storm-2945, a sub-cluster of Midnight Blizzard (also known as APT29, Cozy Bear, NOBELIUM, and BlueBravo), a threat group linked to Russia. The campaign manipulates DNS and HTTP traffic on captive portal networks at hospitality venues, redirecting victims to attacker-controlled infrastructure for Microsoft 365 credential harvesting, device code phishing, and malware delivery.
Evidence suggests that Storm-2945 compromised shared captive portal services used by hotels, conference centers, and similar venues rather than breaching each location individually. ReliaQuest identified compromised gateways in several U.S. cities, India, and Saudi Arabia.
Although the initial access vector remains under investigation, CaptiveCrunch targets travelers across a broad range of sectors. Microsoft assesses that Storm-2945 leveraged AI tools to support a significant portion of its operations, including the development of the CornFlake and ChocoShell malware. This assessment is based partly on extensive and unusually detailed comments found in the malware’s code. Microsoft also acknowledged contributions from Anthropic and OpenAI to the investigation. CaptiveCrunch has also expanded to target Android devices through malicious APK files.
Recommendations
1. Zscaler Client Connector (ZCC) — Full Tunnel Mode
- Enable full tunnel so all traffic (including DNS) is routed through Zscaler and does not egress from ZCC to the local DNS resolver
- Disable "Tunnel with Local Proxy". Attackers can inject a rogue proxy via captive portal settings.
- Configure strict enforcement so users cannot bypass or disable ZCC even on untrusted networks.
2. DNS Security Policies (ZIA)
- Enable DNS Security in ZIA to block malicious/suspicious domains and IPs at the resolver level.
- Block newly registered domains (NRDs) and dynamic DNS (DDNS) domains as they are commonly used in captive portal hijacking infrastructure.
- Enable DNS filtering for categories: phishing, malware, C2, and suspicious domains.
3. Zero Trust Firewall Policies (ZIA)
- Block outbound DNS (UDP/TCP port 53) to all destinations except Zscaler's resolvers. This prevents DNS queries from leaking to a poisoned resolver via a compromised gateway or directly.
- Block HTTP/HTTPS traffic to known phishing and malicious IPs.
- Configure IPS control policies which will be applied to DNS and other non-web protocols.
4. URL & Content Filtering (ZIA)
- Enable SSL inspection. CaptiveCrunch phishing pages may use HTTPS to appear legitimate. Without SSL inspection, Zscaler cannot inspect the content.
5. Advanced Threat Protection & Advanced Cloud Sandbox (ZIA)
- Enable Malware Protection to catch CornFlake (Go-based RAT) and ChocoShell (PowerShell stealer) payloads at download time.
- Configure Zscaler Advanced Cloud Sandbox policies for unknown executables - especially .exe, .ps1, .msi files that may arrive via fake "update" prompts.
- Enable File Type Controls to block execution-capable file types (.ps1, .vbs, .hta, .bat) from being downloaded via browser on untrusted networks.
Attack Techniques
Captive portal traffic manipulation and Adversary-in-the-Middle (AitM)
After compromising captive portal equipment or shared infrastructure, Storm-2945 manipulates DNS and HTTP traffic on the network. When a victim connects to Wi-Fi and encounters the captive portal login prompt, traffic is redirected through an Adversary-in-the-Middle (AitM) position to attacker-controlled infrastructure via one of three paths:
- Phishing pages impersonating Microsoft 365 sign-in portals to harvest credentials;
- Device code phishing pages abusing the Microsoft Entra ID authentication flow; or
- Fake browser/OS update pages using the ClickFix technique.
Device code and OAuth code phishing
Storm-2945 integrates device code phishing directly into the captive portal and traffic manipulation infrastructure. Device code phishing pages abuse the Microsoft Entra ID authentication flow, tricking victims into authenticating the attacker's session, which leads to Entra device registration and Microsoft 365 data collection. Because this abuses a legitimate authentication flow, it can bypass conventional multifactor authentication (MFA). OAuth code phishing and doppelganger domains mimicking Microsoft services support the same objective.
ClickFix social engineering and malware delivery
On the third redirect path, victims encounter fake browser or operating system (OS) update pages using the ClickFix technique. Lures include fake Windows Update, Defender scan, DirectX, VC++ Redistributable, disk optimization, network diagnostics, browser update, and PDF viewer installer prompts. Victims are instructed to paste and run commands, in some cases with instructions for Android APK installation. Executing the ClickFix instructions downloads and runs CornFlake and/or ChocoShell.
CornFlake
CornFlake is a Go-based Windows RAT that serves as the cornerstone of Storm-2945's persistent access strategy. In dropper mode, CornFlake displays a fake progress window while copying itself to %APPDATA%\svchost32\svchost32.exe. It establishes an encrypted C2 channel via ECDH P-256 key exchange and provides RAT capabilities including keylogging, screenshot capture, microphone and webcam surveillance, file exfiltration, USB drive monitoring, and remote shell execution.
CornFlake collects 18 categories of host intelligence and applies an upload throttle of 1,000 files or 500 MB per cycle. Storm-2945 uses CornFlake to maintain a permanent foothold, enabling it to then deploy ChocoShell to extract the specific session tokens and credentials required for cloud environment access.
Persistence and defense evasion
CornFlake implements persistence through service registration, Registry Run keys, scheduled tasks, and a watchdog routine. Additional defense evasion and privilege abuse across the toolset include SYSTEM token impersonation, Volume Shadow Copy Service abuse, and a Defender signature lock.
ChocoShell
ChocoShell is an in-memory PowerShell information stealer. It disables Windows Antimalware Scan Interface (AMSI) via .NET reflection, performs sandbox and VM detection, and escalates privileges using silent User Account Control (UAC) bypass techniques (such as SilentCleanup task hijack, wsreset.exe COM hijack, and sdclt.exe folder hijack), falling back to a visible UAC prompt when necessary.
ChocoShell harvests browser cookies and passwords using ChromeKatz-derived techniques, Chrome ABE bypass, Firefox NSS/SDR decryption, and Chrome DevTools Protocol remote debugging for cookie extraction. It also harvests Microsoft 365 and Azure AD/WAM tokens from the Token Broker cache, as well as Wi-Fi credentials via netsh wlan.
Exfiltration and C2 communication
Collected data is compressed, encoded, and exfiltrated via HTTPS POST to C2 endpoints disguised as tracking pixels and JavaScript polyfill files. ChocoShell beacons to a URI mimicking an image tracking pixel, retrieves additional tooling from a URI disguised as a JS polyfill file, and exfiltrates GZip-compressed, Base64-wrapped JSON to a dedicated event endpoint. Operators manage compromised systems, deploy payloads, and review stolen data through FruitStone, an unauthenticated web-based C2 panel branded as CloudSync Console.
Conclusion
CaptiveCrunch demonstrates how a sophisticated, state-linked actor can turn the trust travelers place in hotel and conference Wi-Fi into a pathway for Microsoft 365 account compromise. By manipulating DNS and HTTP at the network layer, staging AitM phishing outside the corporate perimeter, and abusing the device code authentication flow, Storm-2945 bypasses defenses that rely on network location and conventional MFA. The reported use of AI to accelerate malware development, alongside expansion toward Android targeting, signals a threat that will continue to evolve and scale. Organizations that eliminate implicit trust in network paths and enforce phishing-resistant authentication are best positioned to withstand campaigns like CaptiveCrunch.
Zscaler Coverage
Zscaler’s multilayered cloud security platform detects indicators related to this threat at various levels. The figure below depicts the Zscaler Cloud Sandbox, showing detection details for the ChocoShell malware payload.

Figure 1: Zscaler Cloud Sandbox report for ChocoShell.
In addition to sandbox detections, Zscaler’s multilayered cloud security platform detects indicators related to the campaign at various levels with the following threat names:
Indicators Of Compromise (IOCs)
IOC | Type | Description |
|---|---|---|
ms365-device.com | Domain | CaptiveCrunch device code flow (DCF) redirect domain |
ms365-live.com | Domain | CaptiveCrunch DCF redirect domain |
m365-owa.com | Domain | CaptiveCrunch AitM infrastructure |
owa-ms365.com | Domain | CaptiveCrunch AitM infrastructure |
31.57.243.154 | IP Address | CaptiveCrunch AitM infrastructure |
38.146.28.75 | IP Address | CaptiveCrunch AitM infrastructure |
38.146.28.132 | IP Address | CaptiveCrunch DNS Resolver |
104.194.159.150 | IP Address | CaptiveCrunch AitM infrastructure |
107.189.26.194 | IP Address | ChocoShell C2 / CaptiveCrunch DNS Resolver |
213.145.86.112 | IP Address | ChocoShell C2 server |
918fa52ae45ed60ba7cc8bdc99c3cbe9ab92e0375ec31fc05d0d4513be11c593 | SHA-256 | CornFlake file hash |
be99857449d2856dd5a84e21c8a3d5e0e01456adb44062ddec5a6b4970d8d42c | SHA-256 | ChocoShell file hash |
213.145.86.112/t/pixel.gif | URL | ChocoShell C2 beacon URI, mimics image tracking pixel |
213.145.86.112/cdn/chunks/polyfill-7e2b.min.js | URL | ChocoShell additional tooling download URI, disguised as JS polyfill file |
213.145.86.112/t/event | URL | ChocoShell exfiltration endpoint (GZip-compressed, Base64-wrapped JSON POST) |
Was this post useful?
Disclaimer: This blog post has been created by Zscaler for informational purposes only and is provided "as is" without any guarantees of accuracy, completeness or reliability. Zscaler assumes no responsibility for any errors or omissions or for any actions taken based on the information provided. Any third-party websites or resources linked in this blog post are provided for convenience only, and Zscaler is not responsible for their content or practices. All content is subject to change without notice. By accessing this blog, you agree to these terms and acknowledge your sole responsibility to verify and use the information as appropriate for your needs.
Get the latest Zscaler blog updates in your inbox
By submitting the form, you are agreeing to our privacy policy.


