Brevo (Sendinblue) CDN Supply-Chain Attack — ClickFix Lures & the "Web Media Optimizer" WordPress Backdoor

A stolen long-lived Cloudflare API key with full account permissions let attackers stand up a malicious Cloudflare Worker that rewrote Brevo's CDN-edge JavaScript for ~4-5.5 hours on 2026-09-14, pushing fake "verify you are human" ClickFix prompts and a self-hiding WordPress backdoor plugin to visitors of an estimated 100,000+ sites embedding Brevo forms, chat, or SDK scripts.
Threat
Brevo CDN Supply-Chain / ClickFix / Web Media Optimizer
Severity
HIGH IMPACT ~100k sites
Type
Cloud/SaaS Supply Chain → ClickFix + Web Backdoor
Access
Third-party script trust boundary · No auth required
Version
v0.1 · 2026-09-20
Author
HuntPack
Confidence
High (core facts, 5+ independent sources) / Medium (atomic IOCs, mostly single-sourced)
01

Executive Summary

What happened. On 2026-09-14 an attacker used a long-lived Cloudflare API key with full account permissions — hardcoded in Brevo's application source code — to create a malicious Cloudflare Worker that rewrote content at the CDN edge for Brevo's own site and for JavaScript files (sdk-loader.js, the Brevo Conversations widget, and the Brevo forms script) embedded on customer websites. Sansec places the active malware-serving window at roughly 16:05-20:13 UTC; Brevo's own stated exposure window is 16:07-20:30 UTC. All attacker-controlled subdomains stopped resolving on 2026-09-15. Sansec estimates over 100,000 websites were affected because trust was inherited transitively through a simple <script> tag — no individual customer had to be compromised.

The payload had two branches. (1) Every visitor could be shown a fake "Cloudflare, verify you are human" page that used the ClickFix social-engineering technique: copy a command to the clipboard, then walk the victim through Win+R → paste → Enter to execute it via PowerShell or mshta. (2) On WordPress sites embedding an affected Brevo widget, if the visiting browser showed signs of being an authenticated WordPress administrator, the script instead attempted to silently install a plugin called "Web Media Optimizer" from an attacker-controlled CDN subdomain. That plugin behaves as a persistent backdoor: it hides itself from the WordPress admin plugin list, copies itself into the mu-plugins (must-use plugins) directory for persistence outside normal plugin management, carries a hardcoded authentication key that lets the attacker generate valid admin sessions without a password, and periodically polls for updated payload URLs.

Root cause. A long-lived Cloudflare API key with full account permissions was stored in Brevo's application source code and obtained by the attacker, letting them create Cloudflare Workers, routes, and DNS records across Brevo's zones without triggering the alerting a short-lived, narrowly-scoped token would have. Evidence (identical Last-Modified timestamps on rewritten assets, unified Cloudflare-DNS control of five Brevo apex domains) points to CDN-edge content rewriting rather than a breach of Brevo's origin servers — meaning file-integrity checks against the origin would not have caught this.

Relationship to the prior Sept 10 incident. Several sources describe a separate, earlier incident on 2026-09-10 in which attackers exploited a SAML SSO misconfiguration to access 138 Brevo customer accounts (including Trezor) and run phishing campaigns; Brevo's own status-page write-up confirms this SSO incident and its remediation. Whether the two incidents are connected is, per SecurityAffairs, a question Brevo had not answered as of the reporting cycle covered by this pack's sources — treat them as two related but distinct events; this pack's detections target the 2026-09-14 Cloudflare Worker / ClickFix / Web Media Optimizer incident.

Defender priority: This is a third-party script supply-chain exposure, not a bug in your own code. The two actionable planes are: (1) hunt your own endpoints and WordPress estate for the ClickFix execution chain and the Web Media Optimizer plugin using the queries and log hunts below, and (2) reduce the blast radius of the next compromised third-party script with Subresource Integrity (SRI) and a restrictive Content-Security-Policy on any page that embeds Brevo (or any third-party) JavaScript — see §12.

02

Source Review & Web Hunter Notes

TierSourceKey findingCarry fwd
1 VendorBrevo status.brevo.com incident write-upBrevo's own account of the SEPARATE 2026-09-10 SAML SSO incident (138 accounts, root cause = auth scope bug). No technical indicators for the 09-14 Cloudflare incident are in this write-up; Brevo's words on 09-14 are only available second-hand via direct quotation in SecurityAffairs.partial (context only)
2 PressBleepingComputer — "Brevo supply-chain attack injected ClickFix scripts on customer sites"Full IOC set: 4 attacker domains, cdn10.sendibt1.com/p/wm.zip, plugin name + SHA-256, root cause, affected properties, "not affected" list.yes
2 ResearchSansec — "Brevo supply chain attack hits 100k+ sites"Minute-level timeline, injection mechanism (appended loader snippet), clean-vs-injected script hashes, C2 API path list, detection log signatures, remediation guidance ("search for POST to /wp-admin/update.php?action=upload-plugin").yes
2 PressSecurityWeek — "Brevo Supply Chain Attack Injects Malware Into 100,000 Websites"Corroborates timeline, root cause, exposure window, affected pages, prior Sept 10 SSO incident context.yes
2 PressSecurityAffairs — "Brevo Supply-Chain Attack Infected Over 100,000 Websites"Direct quote of Brevo's own incident notice on root cause; mu-plugins persistence detail; notes the open question of whether the 09-10 and 09-14 incidents are linked.yes
3 PressCyberInsider — "100,000+ WordPress sites infected via Brevo supply chain attack"Corroborates cdn10.sendibt1.com, /p/wm.zip, f.js loader filename, timeline.partial
3 PressIT-Connect.tech — "Brevo ClickFix Attack Hits WordPress Sites"Corroborates cdn10.sendibt1.com, "Web Media Optimizer" plugin name, ClickFix Win+R/Ctrl+V instruction wording, timeline.partial
3 PressCyberNews — "Brevo hack: 100,000+ websites serve malware for hours" (search-summary; direct fetch returned HTTP 403)Corroborates timeline and affected properties narratively; no atomic IOC in this pack traces to this source alone.partial (narrative only)

Intel gaps / perishability: Of the atomic host indicators, only cdn10.sendibt1.com / /p/wm.zip / "Web Media Optimizer" are corroborated by two or more independently fetched sources. The four other attacker domains (glegchner.com, corralos.beer, yelahaye.surf, boiseno.club) and the plugin SHA-256 appear in only one saved snapshot (BleepingComputer) — per this pack's two-source rule for prevent/critical, they ship as detect-tier indicators, not blocklist-tier. All attacker infrastructure stopped resolving on 2026-09-15, so these are historical/retrospective hunting indicators, not a live blocking need — see §4 and §10. No published report recovered the actual "Web Media Optimizer" plugin source code, so its full capability set is described narratively by researchers, not independently verified by this pack's authors.

03

Hunt Brief & Attack Chain

Hunt hypotheses (fidelity-ordered)

#HypothesisMITRETelemetryConf
H1A Windows endpoint's explorer.exe spawns powershell.exe, mshta.exe, or cmd.exe with an encoded or remote-fetch command line shortly after Run-dialog activity — the ClickFix clipboard-paste-and-execute pattern.T1204.004 / T1059.001 / T1218.005ProcessRollup2HIGH
H2A browser process (chrome.exe, msedge.exe, firefox.exe) directly spawns a script host or command interpreter — a browser-triggered ClickFix variant.T1204.004 / T1059.001ProcessRollup2MED
H3An instrumented host issues a DNS query for one of the four attacker domains or an attacker-repurposed sendibt1.com subdomain.T1071.001DnsRequestHIGH
H4A script host (powershell.exe, curl.exe, bitsadmin.exe, certutil.exe) downloads a file referencing wm.zip or sendibt1.com.T1105 / T1059.001ProcessRollup2HIGH
H5A monitored host writes a file matching the Web Media Optimizer plugin filename (wm.zip) or its SHA-256 hash to disk.T1505.003ZipFileWritten / PeFileWrittenHIGH
H6A file write lands inside a WordPress wp-content/mu-plugins path — the plugin's persistence mechanism — on a web-server host with Falcon coverage. ⚠ validate in tenantT1505.003PeFileWrittenMED
H7Native WordPress/web-server access logs show a POST to /wp-admin/update.php?action=upload-plugin followed by a GET to /wp-admin/plugins.php?action=activate on 2026-09-14 — off-sensor for Falcon, the highest-fidelity WordPress-side signal per Sansec.T1505.003Native web/access logHIGH

Attack chain

StepActionTelemetry / hunt angle
1 · Initial access (T1552.001)Attacker obtains a long-lived, full-permission Cloudflare API key hardcoded in Brevo's own application source code.Off-sensor — vendor-side credential exposure. Root-cause lesson for §12.
2 · Infrastructure abuse (T1584 / T1195.002)Attacker creates a malicious Cloudflare Worker + supporting routes/DNS records to rewrite content at the CDN edge for Brevo's own domains and embedded scripts.Off-sensor — Cloudflare account activity, not EDR-visible.
3 · Delivery (T1195.002)Rewritten sdk-loader.js / brevo-conversations.js / forms script append a loader that pulls f.js from an attacker *.sendibt1.com subdomain, on every page that embeds the affected Brevo widget.DNS/network egress from the visitor's browser process. H3.
4a · Visitor branch — ClickFix (T1204.004)Regular visitors see a fake "verify you are human" page instructing them to paste a clipboard command into Win+R.ProcessRollup2: explorer.exe → powershell/mshta/cmd with suspicious CommandLine. H1/H2.
4b · Admin branch — plugin backdoor (T1505.003)If the visiting session looks like a logged-in WordPress admin, the script instead fetches wm.zip ("Web Media Optimizer") from cdn10.sendibt1.com/p/wm.zip and attempts silent plugin installation.Native web log: POST to /wp-admin/update.php?action=upload-plugin. Falcon (if sensor on the web host): ZipFileWritten/PeFileWritten. H4/H5/H7.
5 · Persistence (T1505.003)Plugin hides from the WordPress plugin list and copies itself into wp-content/mu-plugins, which WordPress auto-loads without appearing as a manageable plugin.File write into mu-plugins path. H6. Filesystem-vs-admin-panel plugin count mismatch. H7.
6 · Command & control (T1071.001 / T1102)Plugin carries a hardcoded auth key for attacker-generated admin sessions and periodically polls for updated payload URLs from its C2.Periodic outbound connections from the web host; recurring admin-session creation with no matching interactive login.
04

Consolidated IOC Table

TypeValueConfActionContext
Domaincdn10.sendibt1.comhighpreventHosted the "Web Media Optimizer" plugin archive at /p/wm.zip. Corroborated by 4 independent sources (BleepingComputer, Sansec, CyberInsider, IT-Connect). Attacker-controlled subdomain of a legitimate Brevo apex domain; safe to block — Brevo revoked/cleaned this after 2026-09-15.
URLhttps://cdn10.sendibt1.com/p/wm.ziphighpreventMalicious WordPress plugin archive download. 2+ independent sources.
Domainglegchner.commediumdetectWeb Media Optimizer C2 (/ads.php). Single-sourced (BleepingComputer only) — ships detect-only per two-source rule for prevent/critical.
Domaincorralos.beermediumdetectClickFix lure delivery (/a412dkoq.js). Single-sourced (BleepingComputer).
Domainyelahaye.surfmediumdetectAssociated malicious domain per BleepingComputer's IOC set. Single-sourced.
Domainboiseno.clubmediumdetectAssociated malicious domain per BleepingComputer's IOC set. Single-sourced.
SHA-256f359ab0d2f732b54dd3300065f4d6553f4df1b67454b71fd81197e26f02af4a8mediumdetect"Web Media Optimizer" plugin archive hash (VirusTotal, per BleepingComputer). Single-sourced — ships detect-only per two-source rule.
Domaincdn.sendibt1.com / cdn2 / cdn3 / cdn4 / cdn9 / cdn11.sendibt1.commediumdetectAdditional attacker-repurposed CDN subdomains used to serve the rewritten loader/f.js. Single-sourced (Sansec).
Filenamewm.zipmediumdetectGeneric filename — pair with the hash or full URL for fidelity; do not block on filename alone.
Artifact (plugin name)"Web Media Optimizer"highhuntNamed in 3 independent sources (BleepingComputer, SecurityAffairs, IT-Connect). Not a network-blockable IOC — audit for its presence in the WP plugin directory and mu-plugins.
BehavioralInjected loader snippet appended to sdk-loader.js / brevo-conversations.js that dynamically creates a <script> tag pointing at an attacker *.sendibt1.com subdomainhighdetectSansec. See §10 Script Integrity Reference for clean-vs-injected hash comparisons.

Deliberately excluded from this table: the Cloudflare-anycast IPs reported for some *.sendibt1.com records (e.g. in the 104.21.x.x and 188.114.x.x ranges). Those are shared Cloudflare edge addresses used by millions of unrelated sites — blocking or alerting on them produces overwhelming false positives and provides no attribution value once the DNS records themselves are gone. Hunt on the domain names and the plugin artifact, not the shared IP space behind Cloudflare's proxy.

05

Affected Surface & Telemetry Matrix

SurfaceRequired telemetryPriorityGap risk
Windows endpoints of anyone who browsed an affected site 2026-09-14 16:00-21:00 UTCProcessRollup2 / SyntheticProcessRollup2, DnsRequestCriticalLow — standard Falcon sensor coverage
WordPress hosts embedding a Brevo forms/chat/SDK snippet, where the logged-in admin visited the site that dayZipFileWritten / PeFileWritten (if Falcon-instrumented), native web/access logs (always)CriticalHigh — most WordPress hosting is not Falcon-instrumented; native log hunting (§7) is the primary detection here
Web-server / hosting infrastructure behind those WordPress sitesNative access/error logs, file-integrity monitoring on wp-contentHighMedium — depends on hosting provider log retention
Browsers (all, regardless of OS) rendering the ClickFix overlayBrowser process telemetry (Windows-only for the documented PowerShell/mshta execution path); no equivalent macOS/Linux execution primitive is documented in these sourcesHighMedium — ClickFix as documented here targets Windows clipboard-to-Run; non-Windows visitor impact is a documented gap, not confirmed absent

Coverage reality: the highest-fidelity WordPress-side signal (H7 — the admin plugin-upload POST) lives in native web/access logs, not Falcon telemetry, unless the web server itself runs a Falcon sensor with file-write monitoring enabled for PHP/zip writes under wp-content — validate this in your tenant before relying on Q5/Q6 as your only WordPress detection.

06

ATT&CK Mapping

TacticTechniqueObserved behaviorQuery / control
Resource DevelopmentT1584 Compromise InfrastructureMalicious Cloudflare Worker + routes/DNS created using the stolen API keyOff-sensor; §12 credential hygiene
Initial Access / Credential AccessT1552.001 Unsecured Credentials: Credentials in FilesLong-lived full-permission Cloudflare API key hardcoded in application source codeOff-sensor (vendor-side); §12 secret-scanning + scoped tokens
Initial AccessT1195.002 Supply Chain Compromise: Software Supply ChainCDN-edge rewrite of trusted third-party JavaScript served to 100,000+ downstream sites§12 SRI / CSP
Execution / User ExecutionT1204.004 Malicious Copy and Paste (ClickFix)Fake "verify you are human" overlay instructs victim to paste and run a clipboard commandQ1, Q2, Q3
ExecutionT1059.001 Command and Scripting Interpreter: PowerShellPowerShell invoked from Run dialog / browser with encoded or remote-fetch command lineQ2, Q3, Q4
ExecutionT1218.005 System Binary Proxy Execution: Mshtamshta.exe used as an alternate ClickFix execution vectorQ2, Q3
Command & ControlT1071.001 Application Layer Protocol: Web ProtocolsDNS/HTTP to attacker domains and C2 API pathsQ1
Command & ControlT1105 Ingress Tool TransferScript host downloads wm.zip from attacker CDNQ4
PersistenceT1505.003 Server Software Component: Web Shell"Web Media Optimizer" plugin: hides from plugin list, persists via mu-plugins, hardcoded backdoor auth keyQ5, Q6, native H7
07

Native Audit-Log Hunts (non-CQL)

The single highest-fidelity WordPress-side signal for this campaign lives in your web server / WAF access logs, not EDR. Run these on every WordPress host that embeds a Brevo forms, Conversations, or SDK-loader snippet.

On the WordPress web/access log

  • Plugin upload: search 2026-09-14 (and a few days either side, given the "late August" key-theft window) for a POST to /wp-admin/update.php?action=upload-plugin.
  • Plugin activation: a GET to /wp-admin/plugins.php?action=activate shortly after that POST is the confirming second half of the signature (per Sansec's published remediation guidance).
  • Hidden-plugin check: list the contents of wp-content/plugins/ and wp-content/mu-plugins/ on disk (SSH/SFTP/hosting file manager) and diff against what the WordPress admin "Plugins" screen shows. Web Media Optimizer is designed to hide from that screen — a plugin present on disk but absent from the admin list is the tell.
  • Injected-script check: inspect served HTML/JS for script[src*="file.js"] (a commonly reported default loader filename in this campaign family) or a script tag carrying a data-c attribute — both reported as injection artifacts.
  • Script hash check: compute SHA-256 of the embedded sdk-loader.js / brevo-conversations.js as served to visitors and compare against the clean vs. injected hashes in §10's Script Integrity Reference.

On the WordPress admin session / auth log

  • Review admin login activity around 2026-09-14 16:00-21:00 UTC for sessions with no corresponding interactive login event — a symptom of the plugin's hardcoded backdoor auth key generating sessions without credentials.
  • Force a credential reset and session invalidation for any admin account active on an affected site during the exposure window, out of caution, even without confirmed compromise.

On the endpoint (non-Falcon fallback — AV/EDR-agnostic)

  • Check clipboard history / recent Run-dialog (Win+R) MRU entries for base64 or URL-bearing strings on machines whose users browsed an affected site during the window.
  • Per Sansec's guidance: anyone who followed the ClickFix instructions and executed the pasted command should run a full anti-virus/EDR scan immediately, not wait for a hunt cycle.
08

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.

All attacker domains stopped resolving 2026-09-15 — these are retrospective hunts against the 2026-09-14 window and general-purpose detections for the ClickFix/backdoor-plugin technique class going forward, not a live-blocking need.

Q1 · DNS resolution to Brevo ClickFix / Web Media Optimizer attacker infrastructure
CONF HIGHFP LOWCOST LOW

Looks for: any instrumented host resolving one of the four attacker domains or an attacker-repurposed sendibt1.com subdomain. FP: very low — these are not shared/legitimate hosting domains, just retired campaign infrastructure.

// HUNT: DNS resolution to Brevo ClickFix / Web Media Optimizer attacker infrastructure
// MITRE: T1071.001 | CONF: high  FP: low  COST: low | REQUIRES: DnsRequest
#event_simpleName=/^DnsRequest$/
| DomainName=/^(glegchner\.com|corralos\.beer|yelahaye\.surf|boiseno\.club|cdn10\.sendibt1\.com|cdn\.sendibt1\.com|cdn2\.sendibt1\.com|cdn3\.sendibt1\.com|cdn4\.sendibt1\.com|cdn9\.sendibt1\.com|cdn11\.sendibt1\.com)$/i
| table([ComputerName, aid, UserName, DomainName], limit=200)
Q2 · ClickFix clipboard-to-Run execution chain (explorer.exe → shell/script host)
CONF HIGHFP MEDCOST LOW

Looks for: the canonical ClickFix pattern — a user pastes a command into the Win+R Run dialog, so explorer.exe is the direct parent of powershell.exe, mshta.exe, or cmd.exe, carrying an encoded, hidden-window, or remote-fetch command line. FP: some IT helpdesk/RMM tools and support scripts legitimately launch PowerShell this way — baseline against your fleet before promoting to Detect.

// HUNT: ClickFix clipboard-to-Run-dialog execution chain
// MITRE: T1204.004 / T1059.001 / T1218.005 | CONF: high  FP: medium  COST: low | REQUIRES: ProcessRollup2, SyntheticProcessRollup2
// TUNING: exclude known signed IT helpdesk / RMM tools that legitimately spawn PowerShell from explorer.exe on your fleet
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ParentBaseFileName=/^explorer\.exe$/i
| FileName=/^(powershell|powershell_ise|mshta|cmd)\.exe$/i
| CommandLine=/(-enc|-e |-en |-w hidden|-windowstyle hidden|frombase64string|iex|invoke-expression|http(s)?:\/\/)/i
| table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Q3 · Browser-triggered child-process chain (ClickFix browser variant)
CONF MEDFP MEDCOST LOW

Looks for: a browser process directly spawning a script host or command interpreter — covers ClickFix variants that trigger execution without a visible Run-dialog step. FP: browser updaters, native messaging hosts, and some extensions legitimately spawn helper processes; validate your ParentBaseFileName/FileName pairs against known-good browser child processes before promoting.

// HUNT: Browser process spawning script host / command interpreter
// MITRE: T1204.004 / T1059.001 / T1218.005 | CONF: medium  FP: medium  COST: low | REQUIRES: ProcessRollup2, SyntheticProcessRollup2
// TUNING: exclude signed browser updater/helper binaries and native-messaging hosts observed in your environment
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ParentBaseFileName=/^(chrome|msedge|firefox|iexplore)\.exe$/i
| FileName=/^(powershell|mshta|cmd|wscript|cscript)\.exe$/i
| table([ComputerName, aid, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Q4 · Script-host download of the Web Media Optimizer plugin archive
CONF HIGHFP LOWCOST LOW

Looks for: PowerShell or a common LOLBin downloader fetching wm.zip or referencing sendibt1.com in its command line. FP: low — these strings are campaign-specific.

// HUNT: Script-host download of the Web Media Optimizer plugin archive (wm.zip)
// MITRE: T1105 / T1059.001 | CONF: high  FP: low  COST: low | REQUIRES: ProcessRollup2, SyntheticProcessRollup2
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| FileName=/^(powershell|curl|bitsadmin|certutil)\.exe$/i
| CommandLine=/(wm\.zip|sendibt1\.com|cdn10\.sendibt1)/i
| table([ComputerName, aid, UserName, FileName, CommandLine], limit=200)
Q5 · Web Media Optimizer plugin archive written to disk (filename or hash match)
CONF HIGHFP LOWCOST LOW

Looks for: a file write matching the plugin archive's filename or its published SHA-256. FP: low for the hash match; the filename alone (wm.zip) is generic, so treat a filename-only hit as lower fidelity than a hash hit. Coverage note: this fires only on hosts with a Falcon sensor and file-write visibility — most WordPress hosting is not Falcon-instrumented; §7's native log hunt is the primary WordPress-side detection.

// HUNT: Web Media Optimizer malicious plugin archive written to disk
// MITRE: T1505.003 | CONF: high  FP: low  COST: low | REQUIRES: ZipFileWritten, PeFileWritten
#event_simpleName=/^(ZipFileWritten|PeFileWritten)$/
| FileName=/^wm\.zip$/i OR SHA256HashData=/^f359ab0d2f732b54dd3300065f4d6553f4df1b67454b71fd81197e26f02af4a8$/i
| table([ComputerName, aid, UserName, FileName, FilePath, SHA256HashData], limit=200)
Q6 · File write into WordPress mu-plugins directory (persistence)
CONF MEDFP MEDCOST LOW

Looks for: any file write into a wp-content/mu-plugins path — the plugin's documented persistence mechanism. ⚠ validate in tenant — file-write event coverage for PHP content on Linux-hosted WordPress varies by sensor configuration; this is far more reliable on a Windows-hosted CMS. FP: legitimate must-use plugins and managed-hosting platform files also live here — baseline your known-good mu-plugins writers first.

// HUNT: File write into WordPress mu-plugins directory (Web Media Optimizer persistence)
// MITRE: T1505.003 | CONF: medium  FP: medium  COST: low | REQUIRES: PeFileWritten ⚠ validate in tenant — Linux/PHP file-write coverage varies by sensor config
// TUNING: exclude known-good managed-hosting platform writers and legitimate must-use plugin deployment processes on your fleet
#event_simpleName=/^PeFileWritten$/
| FilePath=/wp-content[\\\/]mu-plugins/i
| table([ComputerName, aid, UserName, FileName, FilePath], limit=200)
09

Custom IOA Recommendations

IOA namePatternExclusionsPath
ClickFix Run-Dialog Executionexplorer.exe → powershell/mshta/cmd with encoded/hidden-window/remote-fetch CommandLineSigned IT helpdesk/RMM tools baselined per-fleetInvestigate → Detect after baseline (Q2)
Brevo Campaign DNS ResolutionDnsRequest to any of the 11 listed attacker/repurposed domainsNone expected — retired campaign infra onlyDetect immediately (Q1)
Web Media Optimizer Artifact DropZipFileWritten/PeFileWritten matching filename wm.zip or the published SHA-256None for the hash match; filename-only hits reviewed manuallyDetect immediately (Q5)
Browser-Spawned Shell (ClickFix variant)chrome/msedge/firefox → powershell/mshta/cmd/wscript/cscriptSigned browser updater/helper binaries, native messaging hostsInvestigate-only (Q3)

The highest-fidelity WordPress-side detection (native H7 — the admin plugin-upload POST) belongs in your web server/WAF log pipeline, not a Falcon IOA — most WordPress hosting never reports to the Falcon sensor.

10

Machine-Readable IOC Appendix

Falcon IOC Management CSVbulk import
type,value,action,severity,expiration,description,tags
domain,cdn10.sendibt1.com,prevent,critical,2026-12-20,Brevo ClickFix attack -- attacker-controlled CDN subdomain hosting the Web Media Optimizer malicious WordPress plugin archive; 2+ independent sources,campaign:brevo-clickfix-2026-09
url,https://cdn10.sendibt1.com/p/wm.zip,prevent,critical,2026-12-20,Brevo ClickFix attack -- malicious WordPress plugin archive download URL; 2+ independent sources,campaign:brevo-clickfix-2026-09
domain,glegchner.com,detect,high,2026-12-20,Brevo ClickFix attack -- Web Media Optimizer plugin C2 (/ads.php); single-sourced (BleepingComputer) -- detect only per two-source rule,campaign:brevo-clickfix-2026-09
domain,corralos.beer,detect,high,2026-12-20,Brevo ClickFix attack -- ClickFix lure delivery (/a412dkoq.js); single-sourced (BleepingComputer),campaign:brevo-clickfix-2026-09
domain,yelahaye.surf,detect,medium,2026-12-20,Brevo ClickFix attack -- associated malicious domain; single-sourced (BleepingComputer),campaign:brevo-clickfix-2026-09
domain,boiseno.club,detect,medium,2026-12-20,Brevo ClickFix attack -- associated malicious domain; single-sourced (BleepingComputer),campaign:brevo-clickfix-2026-09
sha256,f359ab0d2f732b54dd3300065f4d6553f4df1b67454b71fd81197e26f02af4a8,detect,high,2026-12-20,Brevo ClickFix attack -- Web Media Optimizer malicious WordPress plugin archive hash (VirusTotal); single-sourced -- detect only per two-source rule,campaign:brevo-clickfix-2026-09
domain,cdn.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
domain,cdn2.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
domain,cdn3.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
domain,cdn4.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
domain,cdn9.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
domain,cdn11.sendibt1.com,detect,medium,2026-12-20,Brevo ClickFix attack -- attacker-repurposed CDN subdomain; single-sourced (Sansec),campaign:brevo-clickfix-2026-09
filename,wm.zip,detect,medium,2026-12-20,Brevo ClickFix attack -- malicious WordPress plugin archive filename; generic, pair with hash/URL for fidelity,campaign:brevo-clickfix-2026-09
Behavioral SignaturesC2 / network
# C2 / loader API paths reported by Sansec (relative to attacker malware hosts;
# single-sourced -- hunt/enrich only, do not block on generic paths alone):
#   /f.js                  - main loader
#   /api/v1/0044d4a        - fingerprint submission (POST)
#   /api/v1/e08a3c4        - proof-of-work token request
#   /api/v1/8e4c615        - fingerprint submission variant
#   /api/v1/f659473        - token request variant
#   /api/v1/4aff112?tk=    - clipboard command delivery
#   /api/v1/b832c14?e=     - event beacon (click, copy, fallback, failure, close)
#   /api/v1/4ead0ff?tk=    - image beacon
#   /image.php?tk=         - image beacon variant
# C2 "cloak" response -- identical body returned to non-victims/crawlers/scanners:
#   response hash: 4af488d79aef7daa12b1c18f0cce28b7edadccb8b6b0fb8d50d1d53a9a7c2df7
#   body: {"s":0,"r":"https:\/\/www.google.com"}
# Injection artifacts in served HTML/JS:
#   script[src*="file.js"]   - commonly reported default loader filename
#   script[data-c]           - custom attribute set by the injection
WordPress Log Hunt Stringsnative web/access log
# Search access logs for 2026-09-14 (plus a few days either side):
#   POST /wp-admin/update.php?action=upload-plugin
#   GET  /wp-admin/plugins.php?action=activate    (shortly after the POST)
# Filesystem-vs-admin-panel mismatch check:
#   ls -la wp-content/plugins/ wp-content/mu-plugins/
#   # compare against what wp-admin/plugins.php actually lists --
#   # Web Media Optimizer is designed to hide from that screen
# Injected-script detection in served pages:
#   grep -r 'script\[src\*="file.js"\]' .   # or view-source for the pattern
#   grep -r 'data-c=' .
Script Integrity ReferenceSHA-256 -- clean vs. injected
# Per Sansec. Informational / enrichment only -- NOT for blocking (these are
# tampered variants of Brevo's own legitimate scripts, already offline since
# 2026-09-15). Use to verify your embedded scripts weren't served a tampered
# variant during the exposure window, and as SRI reference hashes going forward.
#
# CLEAN (legitimate):
#   sdk-loader.js            fe8447fd1ec4dca652b71db2c749fcc24a5bec3875f3654042169fb2418aed09
#   brevo-conversations.js   26166cd87ff07e7a50317a24126d14b262e842c5715585636dee3ab3f227ddca
#
# INJECTED VARIANTS observed during the 2026-09-14 exposure window:
#   sdk-loader.js (-> cdn2)          58a5c601c9df7ca2120435588fc39f97712d9b878795f6ee500590099a432308
#   sdk-loader.js (-> cdn11)         f67d572d2d30407b3f470904326411450763108980cdad89550fbb221fb06782
#   brevo-conversations.js (-> cdn4) 9b62c12bc5c7feb9802f58e6cf75a368690df3c754e37cc64483a92acacf87a5
11

Detection Validation Gates

GateCheckPass criterion
Telemetry readyProcessRollup2/SyntheticProcessRollup2 and DnsRequest flowing from endpoint fleet; PeFileWritten/ZipFileWritten confirmed present (or absent, and documented) on any Falcon-instrumented web hostsEvents queryable in Falcon within last 24h
Benign baselineRun Q2/Q3/Q6 against 7-30 days of history before promoting to DetectKnown-good exclusions identified and added via TUNING notes
WordPress log access confirmedConfirm access to web server/WAF logs covering 2026-09-14 for every WordPress host embedding a Brevo snippetLogs retained and searchable for the exposure window
Script integrity check runCompare live embedded Brevo script hashes against §10 Script Integrity ReferenceNo match to a listed injected-variant hash
Positive testIn a lab, replicate the explorer.exe → powershell.exe chain with a benign encoded command; confirm Q2 firesQuery returns the test event
12

Hardening — Tiered & Deployable

Immediate (this week)
  • Security awareness: ClickFix-specific warning. No legitimate site or CAPTCHA will ever ask a user to open Win+R and paste/run a command. This single message closes the highest-volume branch of this attack (the visitor overlay). MITRE M1017 (User Training).
  • Block mshta.exe execution via AppLocker/WDAC on endpoints that have no legitimate business need for it (most do not). Removes one of the two documented ClickFix execution vectors outright. MITRE M1038 (Execution Prevention).
  • Deploy Q1/Q2/Q4/Q5 as Detect and run the §7 WordPress log hunts against 2026-09-14 access logs on every host embedding a Brevo snippet, immediately.
Near term (1–4 weeks)
  • Enable PowerShell Script Block Logging + Constrained Language Mode for non-admin, non-signed scripts, so an encoded ClickFix payload is both logged and constrained even if it runs. MITRE M1040 (Behavior Prevention on Endpoint) / M1042.
  • WordPress hardening: enforce MFA on wp-admin, restrict access to /wp-admin/update.php and /wp-admin/plugins.php by source IP/VPN at the WAF, and deploy file-integrity monitoring on wp-content/plugins and wp-content/mu-plugins so an unauthorized plugin write alerts even without EDR on the host. MITRE M1032 (Multi-factor Authentication) / M1047 (Audit) / M1022 (Restrict File and Directory Permissions).
  • Third-party script containment — Content-Security-Policy. Set a script-src/connect-src allowlist on every page embedding third-party JavaScript (Brevo or otherwise), so that if a trusted CDN is tampered with again, the browser itself blocks the injected script from loading new hosts or beaconing to unlisted domains. ⚠ best-practice, no formal CIS/vendor benchmark covers this specific supply-chain scenario — grounded in the W3C CSP specification and standard defense-in-depth practice, not a named framework control.
Strategic (1–3 months)
  • Subresource Integrity (SRI) on embedded third-party scripts where the vendor supports versioned/immutable script URLs — pins the exact byte content expected, so a CDN-edge rewrite (exactly this attack) causes the browser to refuse the script rather than execute it. ⚠ best-practice, no formal benchmark — W3C SRI spec. Requires coordination with any vendor (Brevo or otherwise) whose script URL is not a stable, hashable asset.
  • Vendor / third-party script risk management: stand up automated monitoring that diffs and hashes every third-party script your sites embed on a recurring basis, alerting on any change outside a known release cadence. MITRE M1047 (Audit) as applied to supply-chain surface.
  • If you manage your own Cloudflare (or any CDN) API credentials: replace any long-lived, full-permission Global API Key with narrowly-scoped, short-lived Cloudflare API Tokens; never hardcode them in application source — use a secrets manager, and run repository secret-scanning to catch the exact root-cause pattern that enabled this campaign. MITRE M1047 (Audit) / general credential-hygiene best practice for T1552.001.
13

Deployable Playbooks

Playbook A — Windows: block mshta.exe and harden PowerShell against ClickFix (AppLocker + registry)

MITRE: T1204.004 / T1218.005 / T1059.001 → M1038, M1040, M1042  |  Estimated deploy time: 1-2 hours (Immediate tier), 1 pilot ring for Constrained Language Mode  |  Prerequisites: Windows 10/11 or Server 2016+, Group Policy or Intune management, local admin on target endpoints  |  Reboot required: No (AppLocker/registry changes apply on next policy refresh or PowerShell session; no reboot needed)

# Step 1 -- AppLocker deny rule for mshta.exe (GPO path shown; PowerShell equivalent below)
# GPO path: Computer Configuration > Windows Settings > Security Settings >
#           Application Control Policies > AppLocker > Executable Rules
# Add a Deny rule: Path = %SYSTEM32%\mshta.exe, applied to Everyone

# PowerShell equivalent (local testing before GPO rollout):
New-AppLockerPolicy -RuleType Path -User Everyone -Action Deny `
  -Path "%SYSTEM32%\mshta.exe" -XMLPolicy | Set-AppLockerPolicy -Merge

# Verify:
Get-AppLockerPolicy -Effective -Xml | Select-String "mshta"

# Rollback:
# Remove the Deny rule from the linked GPO (or the local policy) and run:
gpupdate /force
# No reboot required; AppLocker re-evaluates on next process launch after policy refresh.
# Step 2 -- Enable PowerShell Script Block Logging (visibility even if execution isn't blocked)
$path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
New-Item -Path $path -Force | Out-Null
New-ItemProperty -Path $path -Name 'EnableScriptBlockLogging' -Value 1 -PropertyType DWORD -Force | Out-Null
Write-Output "PowerShell Script Block Logging enabled."

# Verify:
(Get-ItemProperty $path -Name EnableScriptBlockLogging -EA SilentlyContinue).EnableScriptBlockLogging
# Expect: 1

# Rollback:
Remove-ItemProperty -Path $path -Name 'EnableScriptBlockLogging' -EA SilentlyContinue
# No reboot required; takes effect for new PowerShell sessions.

Compatibility note: pilot the mshta.exe deny rule on a small ring first — a small number of legacy line-of-business HTA-based tools may depend on it. Search Event ID 8004 (AppLocker) for blocked launches during pilot.

Playbook B — WordPress: lock down plugin installation and monitor mu-plugins (shell / WP-CLI)

MITRE: T1505.003 → M1022, M1032, M1047  |  Estimated deploy time: 2-4 hours  |  Prerequisites: SSH/SFTP or hosting-panel file access, WP-CLI installed, ability to edit wp-config.php and web-server config  |  Reboot required: No

# Step 1 -- Audit current state: disk vs. admin-panel plugin list
wp plugin list --path=/var/www/html
ls -la /var/www/html/wp-content/plugins/ /var/www/html/wp-content/mu-plugins/
# Any plugin present on disk but NOT in the `wp plugin list` output is a hiding-plugin candidate -- investigate before proceeding.

# Step 2 -- Disable in-dashboard plugin/theme installation and file editing
# Add to wp-config.php (before "That's all, stop editing!"):
#   define('DISALLOW_FILE_MODS', true);   // blocks plugin/theme install+update+edit from wp-admin
# NOTE: this also blocks LEGITIMATE plugin updates from the dashboard -- pair with a
# controlled update process (WP-CLI, staging-then-deploy, or a managed host's own pipeline).

# Step 3 -- File-integrity baseline for wp-content
find /var/www/html/wp-content -type f \( -name "*.php" -o -name "*.zip" \) -exec sha256sum {} \; > /var/backups/wp-content-baseline-$(date +%F).sha256

# Step 4 -- Recurring integrity check (cron, e.g. daily)
sha256sum -c /var/backups/wp-content-baseline-$(date +%F).sha256 2>&1 | grep -v ": OK"
# Any FAILED or new/missing file warrants investigation.

# Verify Step 2:
grep DISALLOW_FILE_MODS /var/www/html/wp-config.php
# Expect: define('DISALLOW_FILE_MODS', true);

# Rollback:
# Remove (or set to false) the DISALLOW_FILE_MODS line in wp-config.php to restore
# dashboard-based plugin management. No service restart required.

Playbook C — Any site embedding third-party JavaScript: CSP + SRI containment

MITRE: T1195.002 → best-practice (W3C CSP/SRI specs; no single CIS control covers third-party-script supply chain)  |  Estimated deploy time: 2-6 hours plus a monitoring period for CSP report-only tuning  |  Prerequisites: ability to edit site HTTP response headers or HTML <head>; an inventory of every third-party script domain the site legitimately loads  |  Reboot required: No (web server / CDN config reload only)

# Step 1 -- Ship CSP in Report-Only mode first to avoid breaking legitimate embeds
# HTTP response header (nginx example):
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://sibforms.com https://cdn.brevo.com; connect-src 'self' https://cdn.brevo.com; report-uri /csp-violations;" always;

# Step 2 -- After a monitoring period with no unexpected legitimate violations, enforce it:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://sibforms.com https://cdn.brevo.com; connect-src 'self' https://cdn.brevo.com;" always;
# Any future attempt by a tampered/injected script to load a NEW attacker domain (e.g. a
# repeat of *.sendibt1.com-style abuse or the four ClickFix domains in this pack) is blocked
# by the browser itself, even though the script content changed at the CDN edge.

# Step 3 -- Where the vendor serves an immutable/versioned script URL, pin it with SRI:
# <script src="https://cdn.brevo.com/js/sdk-loader.js"
#         integrity="sha256-BASE64_OF_KNOWN_GOOD_HASH"
#         crossorigin="anonymous"></script>
# NOTE: SRI requires the vendor to serve a byte-stable script at that URL; if the vendor
# rotates content at that same URL for legitimate reasons, SRI will break the embed --
# validate with the vendor before enforcing.

# Verify:
curl -sI https://your-site.example.com/ | grep -i content-security-policy

# Rollback:
# Remove the add_header line (or revert to Report-Only) and reload the web server:
nginx -t && systemctl reload nginx
14

Containment Runbook

PhaseActionsOwnerEvidence
IsolateFalcon-contain any endpoint flagged by Q1/Q2/Q3/Q4; take any WordPress host with a confirmed Web Media Optimizer plugin off the public network or place behind maintenance mode pending eradication.SOC + Web/IT OpsContainment IDs, host list from Q1-Q6
EradicateRemove the plugin from both wp-content/plugins and wp-content/mu-plugins (check both — it hides from the admin list but not the filesystem); force-reset all WordPress admin credentials and invalidate sessions for any account active during 2026-09-14 16:00-21:00 UTC; on Windows endpoints, run a full AV/EDR scan and review Run-dialog/clipboard history for anyone who browsed an affected site that day.Web/IT Ops + IRRemoved-file list, credential-reset log, scan results
RecoverRestore plugin/theme state from a known-clean backup predating 2026-09-14 where available; re-enable dashboard plugin management only after DISALLOW_FILE_MODS-gated review; verify embedded Brevo (or other third-party) script hashes against §10's clean references before re-enabling normal operation.Web/IT OpsRestore logs, script-hash verification record
Post-incidentDeploy CSP/SRI (Playbook C) on all sites embedding third-party scripts; enable file-integrity monitoring on wp-content fleet-wide; if your organization manages its own Cloudflare/CDN API credentials, audit for hardcoded long-lived keys and rotate to scoped tokens (root-cause lesson from this campaign).SecEng + Web/IT OpsCSP header rollout record, FIM coverage report, credential-rotation log
15

Detection Coverage Map

TechniqueBehaviorCQLIOACoverage
T1584 / T1552.001Stolen Cloudflare API key, malicious Worker creation——GAP (vendor-side, off-sensor)
T1071.001DNS resolution to attacker/repurposed domainsQ1Brevo Campaign DNS ResolutionGood
T1204.004 / T1059.001 / T1218.005ClickFix clipboard-to-Run execution (explorer.exe path)Q2ClickFix Run-Dialog ExecutionGood
T1204.004 / T1059.001ClickFix browser-triggered variantQ3Browser-Spawned ShellPartial
T1105wm.zip download via script hostQ4—Good
T1505.003Plugin archive written to disk (hash/filename)Q5Web Media Optimizer Artifact DropPartial (Falcon-instrumented web hosts only)
T1505.003mu-plugins persistence writeQ6—Partial — ⚠ validate in tenant
T1505.003Admin plugin-upload POST / activation GET (native web log)——GAP (off-sensor; native log hunt §7 is primary)

Known gaps: the root cause (stolen Cloudflare API key, malicious Worker) and the highest-fidelity WordPress-side signal (admin plugin-upload POST) are both off-sensor for Falcon — recoverable only from Cloudflare account audit logs and web-server access logs respectively. Closing the primary WordPress gap means running §7's native log hunts on every site embedding a Brevo (or other third-party) snippet, not waiting on EDR coverage.

Validation: telemetry-ready and benign-baseline gates (§11) must pass before Q2/Q3/Q6 are promoted from Investigate to Detect.

16

Hunt Summary Ticket

TITLE:      Brevo CDN Supply-Chain Attack — ClickFix Lures & Web Media Optimizer WordPress Backdoor
SEVERITY:   High impact (~100,000 sites, per Sansec) / Critical for confirmed WP plugin installs
SCOPE:      Windows endpoints of visitors to Brevo-embedding sites 2026-09-14 16:00-21:00 UTC;
            WordPress hosts embedding Brevo forms/Conversations/SDK-loader scripts
HYPOTHESIS: Stolen Cloudflare API key -> malicious Worker rewrites trusted 3rd-party JS ->
            ClickFix clipboard execution (visitors) + silent plugin backdoor (WP admins)
QUERIES:    Q1 DNS-to-attacker-infra · Q2 ClickFix Run-dialog chain · Q3 browser-spawned shell ·
            Q4 wm.zip download · Q5 plugin artifact drop (hash/filename) · Q6 mu-plugins write
DO FIRST:   1) Run §7 WordPress log hunts on every Brevo-embedding site for 2026-09-14
            2) Deploy Q1/Q2/Q4/Q5 as Detect  3) Block mshta.exe via AppLocker (Playbook A)
            4) Check wp-content/mu-plugins on disk vs. admin panel on every WP host
FINDINGS:   <record DNS/process hits, plugin artifact matches, WP log signature hits>
GAPS:       Root cause (stolen API key/Worker) and admin plugin-upload POST are off-sensor;
            4 of 5 attacker domains + the plugin hash are single-sourced (detect-only, not prevent)
ACTIONS:    Falcon-contain flagged hosts; force WP admin credential reset for exposure-window
            sessions; deploy CSP/SRI (Playbook C) on all 3rd-party-script embeds
OWNER:      <assign>          VERSION: v0.1 · 2026-09-20
17

Changelog

v0.12026-09-20Initial HuntPack — Brevo (Sendinblue) CDN supply-chain attack: stolen Cloudflare API key, malicious Cloudflare Worker, ClickFix lures, and the "Web Media Optimizer" WordPress backdoor plugin. 6 CQL queries (DNS, ClickFix process chains x2, wm.zip download, plugin artifact drop, mu-plugins persistence), native WordPress/web-log hunts, tiered hardening (AppLocker, WP lockdown, CSP/SRI), 3 deployable playbooks with prerequisites/reboot/rollback, and a containment runbook. Two-source rule applied to §4/§10: only cdn10.sendibt1.com and its /p/wm.zip URL are corroborated by 2+ independent snapshots and ship as prevent/critical; the four other attacker domains and the plugin SHA-256 are single-sourced (BleepingComputer only) and ship detect-only.
18

References

TierSourceUsed forAccessed
1 VendorBrevo status.brevo.com incident write-upBrevo's own account of the related Sept 10 SSO incident (context; no 09-14 technical indicators)2026-09-20
2 PressBleepingComputer — Brevo supply-chain attack injected ClickFix scripts on customer sitesFull IOC set (4 domains, cdn10.sendibt1.com/wm.zip, plugin name + hash), root cause, affected properties2026-09-20
2 ResearchSansec — Brevo supply chain attack hits 100k+ sites with Wordpress backdoors and Clickfix malwareMinute-level timeline, injection mechanism, clean/injected script hashes, C2 API paths, WP log detection signature2026-09-20
2 PressSecurityWeek — Brevo Supply Chain Attack Injects Malware Into 100,000 WebsitesTimeline, root cause, scope corroboration2026-09-20
2 PressSecurityAffairs — Brevo Supply-Chain Attack Infected Over 100,000 WebsitesDirect quote of Brevo's incident notice; mu-plugins persistence detail; Sept 10/14 linkage question2026-09-20
3 PressCyberInsider — 100,000+ WordPress sites infected via Brevo supply chain attackCorroboration: cdn10.sendibt1.com, /p/wm.zip, f.js loader filename2026-09-20
3 PressIT-Connect.tech — Brevo ClickFix Attack Hits WordPress SitesCorroboration: cdn10.sendibt1.com, plugin name, ClickFix instruction wording2026-09-20
3 PressCyberNews — Brevo hack: 100,000+ websites serve malware for hours (search-summary; direct fetch returned HTTP 403)Narrative timeline/scope corroboration only2026-09-20