BdThemesi pluginates avastati API-põhine tarneahela rünne
BdThemesi pluginates kasutatud haldusbänneri komponent võimaldas ründajatel võtta WordPressi sait üle ilma plugina faili või uuendust muutmata. Piisas sellest, et nad asendasid tarnija kaug-API JSON-vastuse pahatahtliku sisuga: iga sisselogitud administraatori wp-admin-i lehe avamine käivitas siis ründaja JavaScripti.
Mõjutatud pluginad on WordPressi pluginate kataloogis uurimise ajaks ajutiselt suletud. Kui sinu saidil töötab mõni neist, käsitle saiti kompromiteerimisohus olevana ning kontrolli kohe kasutajaid, pluginate katalooge ja andmebaasi.
Miks see rünnak on tavapärasest ohtlikum
Rünnak ei muutnud WordPress.org-i hoidlas ühtegi lähtekoodifaili ega pruukinud muuta saidi faile enne püsivuse loomist. Ainult failide tervikluse võrdlemisest ei piisa selle intsidendi avastamiseks.
Mõjutatud pluginad
- Element Pack Addons for Elementor (
bdthemes-element-pack-lite) - Prime Slider Addons for Elementor (
bdthemes-prime-slider-lite) - Pixel Gallery Addons for Elementor (
pixel-gallery) - Ultimate Post Kit Addons for Elementor (
ultimate-post-kit) - Ultimate Store Kit – Addon For WooCommerce, EDD and Elementor (
ultimate-store-kit) - Live Copy Paste for Elementor (
live-copy-paste) - Smart Admin Assistant (
smart-admin-assistant)
Kuidas mürgitatud API-vastus XSS-i käivitas
BdThemesi pluginad sisaldavad sisemist komponenti nimega Biggopti. See laadib tarnija API-st reklaambännereid ja kuvab need WordPressi haldusalas. API ei kasuta dünaamilist rakendusserverit, vaid Cloudflare’iga kaitstud DigitalOcean Spacesi objektihoidlas paiknevaid staatilisi JSON-faile.
Iga Biggoptit kasutav plugin lisab admin_init hook’i ajal kliendipoolse JavaScripti. Skript käivitub tingimusteta igal wp-admin-i lehelaadimisel, küsib API-st bänneriandmed ning koostab DOM-is teate HTML-i. Probleem tekkis väljal display_id: skript kirjutas selle väärtuse ilma paojuta HTML-i id-atribuuti.
// Väärtust ei paota enne HTML-atribuuti lisamist.
var f = t.display_id || t.id || "default";
var m = "bdt-admin-biggopti-api-biggopti-" + f;
A = 'id="' + m + '"';Samas koodis paotakse data-display-id-atribuudi väärtus korrektselt: funktsioon asendab märgid &, <, >, ja " nende HTML-olemitega. Bänneri content-väljale lisati hilisemates versioonides ka DOMParseril põhinev puhastus, mis eemaldab ohtlikud HTML-sildid ja inline-handlerid. id-atribuudi süstekoht jäi siiski paotamata.
function escapeAttribute(value) {
return (value || "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}Haavatavus sai alguse 1. märtsil 2026, kui Prime Slideri versioonis 4.1.9 lisati SVN-i commit r3471891. Seejärel jõudis sama muster teistesse pluginatesse. Ründaja sai kirjutusõiguse tarnija objektihoidlasse, asendas õiged JSON-vastused ründekoodiga ning murdis display_id abil id-atribuudist välja.
Süstitud väärtus lisas onanimationstart-i sündmuse töötleja. CSS-animatsioon kutsus selle umbes 10 millisekundi jooksul esile, nii et ründekood käivitus administraatori jaoks märkamatult igal haldusala lehel. Ühes nähtud API-vastuses algas väärtus kujul SAFE" onanimationstart=eval(String.fromCharCode(...)) style=animation:wrapperSlideInTop .01s ease-out both; dekodeeritud kood laadis välise JavaScripti URL-ilt https://api.sigmative.io/prod/store/api/biggopti/x.js?_ =1.
Haavatavus on XSS ehk cross-site scripting: kui ründaja kontrollib API serverit, saab ta lisada veebiskripti, mis käivitub iga kasutaja brauseris, kes nakatatud lehe avab. Selle juhtumi CVSS-i hinne on 5,4 ehk keskmine ning parandust polnud avaldatud.
Kaheastmeline ründevoog
Ründeahel kasutas sõltuvalt plugina API endpointist kahte payloadi. Peamine w2.js jõudis pluginateni endpointi api-data-all-records kaudu. Teine payload x.js paiknes otse BdThemesi infrastruktuuris ning jõudis ohvriteni endpointi api-data-records kaudu.
Peamine payload w2.js
- C2 kontroll. Skript saatis saidi origin’i C2-serverile
ia-cdn[.]com/fz/c, et saada sihtimise juhiseid. Kui vastuseks tuliskipvõidone, lõpetas skript töö. - Võltsadmini loomine. Skript kasutas aktiivse administraatoriseansi
X-WP-Nonce-i ja lõi WordPressi REST API kaudu uue administraatori. Kui see ei õnnestunud, proovis see standardset kasutaja lisamise vormi. - Webshelli paigaldus. Skript laadis C2-serverist alla võltsitud plugina ZIP-faili ning paigaldas selle tavapärase plugina üleslaadimise vormi kaudu. Plugin maskeerus näiteks slug’iga
wp-smart-thumbnailsvõi muu neutraalse kõlaga nimega. Selles paiknes URL-i kaudu otse käivitatav webshellemer-run.php. - MU-pluginate kaudu püsivuse loomine.
emer-run.phppaigaldas Must-Use pluginate kataloogi kaks püsivusmoodulit. Mõlemal uuritud näidisel oli failiaeg tagasikuupäevastatud 2025. aasta septembrisse, et need sulanduksid tavapäraste failisüsteemi ajatemplitega; failinimed võivad nakkuste vahel erineda. Esimene moodul lubas ilma autentimata administraatorisse siseneda URL-i parameetriga?_wplogin=<token>ning sihtis saidi kõige varem registreeritud administraatorit. Teine moodul hook’is WordPressi andmebaasipäringuid, peitis loodud võltskontod haldusala kasutajaloendist ja vähendas ka kasutajate koguarvu. - Tulemuste väljavedu. Skript saatis iga käivitusetapi tulemused C2-serverisse
navigator.sendBeacon-i abil.
Alternatiivne payload x.js
Teine skript arvutas administraatori kasutajanime ja parooli deterministlikult saidi hostinime põhjal. Kasutajanime kuju oli bd_ pluss kuuekohaline base36-räsi ning parool oli Bd@26! pluss sama räsi ja lõpus x. Konto e-posti aadressiks määrati sellele kasutajanimele vastav @wordpress.org aadress.
function makeCreds() {
var host = siteKey();
var hash = 0;
for (var i = 0; i < host.length; i++) {
hash = ((hash << 5) - hash + host.charCodeAt(i)) | 0;
}
var n = Math.abs(hash).toString(36).slice(0, 6);
return {
user: 'bd_' + n,
pass: 'Bd@26!' + n + 'x'
};
}Kuna algoritm annab sama hostinime korral alati samad kasutajaandmed, ei pea ründajad kompromiteeritud saitide loendit keskselt hoidma. Intsidendile reageerija saab kahtlusaluse domeeni põhjal täpse kasutajanime ja parooli välja arvutada ning nende järgi jahti pidada.
Seejärel laadis skript user-new.php lehe, otsis sealt nonce’i ja logouti URL-i ning saatis vormipäringu, mis lõi administraatorirolliga kasutaja. Tulemus, kasutajanimi, parool, saidi origin, logouti URL ja praegune lehe URL saadeti C2-le esmalt sendBeacon-iga; ebaõnnestumisel kasutati fetch-i no-cors-režiimis. Õnnestunud või juba olemasoleva konto järel salvestas skript brauseri localStorage-isse lipu, kui see oli võimalik.
Seos, ulatus ja risk
C2-domeen seostub samade ründajatega, kes korraldasid eelneva kahe kuu jooksul Advanced Responsive Video Embedderi ja OptinMonsteri tarneahela ründed. Kampaania eesmärk on luua suurel hulgal WordPressi keskkondades märkamatult administraatoritaseme püsivus ja kaugkäivitatav kood.
Ründajad ei pidanud saitidele eraldi ligi pääsema: usaldatud haldusbänneri andmevoo mürgitamine kasutas ära kuvamiskoodi vea. Pahatahtlike JSON-kirjete ja x.js-i üleslaadimine BdThemesi enda hoidlasse viitab sellele, et kompromiteeriti tõsiselt tarnija pilvesalvestuse volitusi või sisemist infrastruktuuri.
Kompromiteerimise indikaatorid
Kontrolli neid indikaatoreid nii failisüsteemist kui andmebaasist. Ära piirdu üksnes selle kontrolliga, kas plugina failid on muutunud.
- Peamine payload:
ia-cdn[.]com/fz/w2.js. - C2 beacon endpoint:
ia-cdn[.]com/fz/c. - Mürgitatud tarnija endpointid, mis on nüüdseks puhastatud:
api[.]sigmative[.]io/prod/store/api/biggopti/api-data-all-records,api[.]sigmative[.]io/prod/store/api/biggopti/api-data-recordsjaapi[.]sigmative[.]io/prod/store/api/biggopti/x.js. - Webshell
emer-run.php, MD51024732009983dd5e54b4cf5593f04d4. - MU-plugina magic-login backdoor
class-wp-token-validate.php, MD57719cd98a35ffad2771f26d1ceab7d27. - MU-plugina varjemoodul
class-wp-query-9d127ff3.phpvõi sarnase nimekujugaclass-wp-query-*.php, MD59aadc3e5c5242b273bd17c5bdc358845. - MU-plugina „health check” moodul
wp-cache-optimizer.php, MD5e450ae5bc4bfc0d960dded06a76bb8e9. - Andmebaasi suvand
fz_emer_login_tokens, kus hoitakse magic-login tokeneid. - Andmebaasi suvand
fz_emer_done_v1, mis märgib kompromiteerimise lõpetatuks. - Kontod, mille e-posti domeen on
@wordpress.orgvõi@developer.wordpress.org. - Kasutajanimed kujul
bd_ja sellele järgnev kuus tähe-numbrimärki.
Ajajoon
- 1. märts 2026: Biggopti API JavaScript lisati Prime Slideri versiooni 4.1.9 SVN commit’iga
r3471891.display_idjõudis paotamataid-atribuuti ning API endpoint oliapi-data-records. - 10. mai 2026: endpoint muudeti
api-data-all-records-iks.content-väljale lisati DOMParseri puhastus, kuidid-atribuut jäi paotamata. - 23. juuni 2026: mürgitatud API kampaania „Summer Sale” teate
start_date; see on varaseim võimalik kuupäev, mil XSS võis aktiivne olla. - 6. august 2026 kell 22.40 UTC: mürgitatud
api-data-records-i viimane muutmisaeg. - 7. august 2026 kell 09.11 UTC: mürgitatud
api-data-all-records-i viimane muutmisaeg. - 7. august 2026: rünnakust teatati ja seda nähti aktiivselt kasutuses; pluginad suleti WordPressi kataloogis ülevaatuseks.
- 7. august 2026 kell 16.56 UTC: uurijad kogusid ründe artefaktid.
- 8. august 2026: mõlemad API endpointid tagastasid taas puhta JSON-i.
Mida nüüd teha
Kui kasutad loetletud BdThemesi pluginaid, auditeeri viivitamata kõik WordPressi kasutajad, sealhulgas bd_-algusega kontod ja kahtlaste WordPressi domeenidega e-posti aadressid. Vaata üle tavaliste pluginate ning eriti mu-plugins-i kataloog, otsi nimetatud faile ja räsi ning kontrolli suvandeid fz_emer_login_tokens ja fz_emer_done_v1.
See rünne näitab, et usaldatud kaugandmestik võib olla sama kriitiline ründepind kui plugina lähtekood. Kuna XSS käivitub autentitud administraatori brauseris, võib tagajärg olla täielik saidi ülevõtmine: võltsadminid, webshellid ja püsivad tagauksed.
Tuvastusreeglite saadavus
Turvasignatuurid ja WAF-reeglid selle tarneahela ründe tuvastamiseks jõudsid Wordfence Premiumi, Care’i, Response’i ja tasulise Wordfence CLI kasutajateni 7. augustil 2026. Wordfence’i ja Wordfence CLI tasuta kasutajad saavad need tavapärase 30-päevase viitega.
Viited / Allikad
- PSA: Supply Chain Compromise in BdThemes Ecosystem via Poisoned API Response
- Biggopti Library (Various Versions) – Cross-Site Scripting via display_id from Sigmative API
- Wordfence Prism Detected Backdoored WordPress Plugin Within Two Hours of It Being Introduced
- Security Incident: Tampered Script Served via OptinMonster and TrustPulse
Liisa Tamm
Eesti meeskonna peatoimetaja, e-valitsuse ja digitaalse identiteedi ekspert. Turvaline autentimine ja digital-first lahendused on minu valdkond.
Kõik postitused