Liigu sisu juurde
BdThemesi pluginates avastati API-põhine tarneahela rünne
Liisa Tamm
Liisa Tamm 9. August 2026 · 8 min lugemist

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.

Haavatav `display_id`-väärtuse kasutus biggopti.js
// 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, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

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

  1. C2 kontroll. Skript saatis saidi origin’i C2-serverile ia-cdn[.]com/fz/c, et saada sihtimise juhiseid. Kui vastuseks tuli skip või done, lõpetas skript töö.
  2. 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.
  3. 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-thumbnails või muu neutraalse kõlaga nimega. Selles paiknes URL-i kaudu otse käivitatav webshell emer-run.php.
  4. MU-pluginate kaudu püsivuse loomine. emer-run.php paigaldas 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.
  5. 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-records ja api[.]sigmative[.]io/prod/store/api/biggopti/x.js.
  • Webshell emer-run.php, MD5 1024732009983dd5e54b4cf5593f04d4.
  • MU-plugina magic-login backdoor class-wp-token-validate.php, MD5 7719cd98a35ffad2771f26d1ceab7d27.
  • MU-plugina varjemoodul class-wp-query-9d127ff3.php või sarnase nimekujuga class-wp-query-*.php, MD5 9aadc3e5c5242b273bd17c5bdc358845.
  • MU-plugina „health check” moodul wp-cache-optimizer.php, MD5 e450ae5bc4bfc0d960dded06a76bb8e9.
  • 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.org võ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_id jõudis paotamata id-atribuuti ning API endpoint oli api-data-records.
  • 10. mai 2026: endpoint muudeti api-data-all-records-iks. content-väljale lisati DOMParseri puhastus, kuid id-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.

Liitu HelloWP kogukonnaga!

Vestle meiega WordPressist ja veebiarendusest ning jaga kogemusi teiste arendajatega.

- liiget
- võrgus
Liitu

Kasutame küpsiseid teie kogemuse parandamiseks. Jätkates nõustute meie Küpsiste poliitikaga.