{"id":264,"date":"2026-08-09T10:45:14","date_gmt":"2026-08-09T08:45:14","guid":{"rendered":"https:\/\/helloblog.io\/sl\/bdthemes-xss-napad-na-dobavno-verigo\/"},"modified":"2026-08-09T10:45:14","modified_gmt":"2026-08-09T08:45:14","slug":"bdthemes-xss-napad-na-dobavno-verigo","status":"publish","type":"post","link":"https:\/\/helloblog.io\/sl\/bdthemes-xss-napad-na-dobavno-verigo\/","title":{"rendered":"BdThemes: zastrupljeni API je prek XSS oku\u017eil WordPress administratorje"},"content":{"rendered":"\n<p>V ekosistemu vti\u010dnikov BdThemes je pri\u0161lo do napada na dobavno verigo, ki lahko oku\u017ei WordPress brez posodobitve vti\u010dnika in brez spremembe ene same datoteke na stre\u017eniku. Napadalci so zlorabili oddaljeni JSON s promocijskimi obvestili, ki se nalo\u017ei v prijavljeni skrbni\u0161ki seji, zato mora\u0161 prizadeta spletna mesta takoj pregledati tudi na ravni uporabnikov, MU-vti\u010dnikov in podatkovne zbirke.<\/p>\n\n\n\n<p>Vsi spodaj navedeni vti\u010dniki so v uradnem imeniku WordPressa za\u010dasno zaprti, dokler pregled in preiskava ne zaklju\u010dita. Napad cilja komponento Biggopti, ki jo uporabljajo vti\u010dniki BdThemes.<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-danger is-style-danger is-layout-flow wp-block-group-is-layout-flow\" style=\"border-width:1px;border-radius:8px;padding-top:1rem;padding-right:1.5rem;padding-bottom:1rem;padding-left:1.5rem\">\n\n<h4 class=\"wp-block-heading callout-title\">Zakaj je ta incident nevaren<\/h4>\n\n\n<p>Napad ne potrebuje posodobitve vti\u010dnika, da dose\u017ee spletno mesto. Ne spremeni datotek vti\u010dnika na disku, zato ga preverjanje integritete datotek praviloma ne zazna, po\u017earni zid za spletne aplikacije pa ga te\u017eko opazi.<\/p>\n\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Kako deluje kompromitirana dobavna veriga<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Oddaljeni promocijski JSON postane vektor napada<\/h2>\n\n\n\n<p>Vti\u010dniki BdThemes vklju\u010dujejo interno komponento <em>Biggopti<\/em>. Ta iz API-ja ponudnika pridobi promocijske pasice in jih prika\u017ee na nadzorni plo\u0161\u010di WordPressa. API ne poganja dinami\u010dne aplikacije, temve\u010d stre\u017ee stati\u010dne datoteke JSON iz prostora DigitalOcean Spaces, ki ga varuje Cloudflare.<\/p>\n\n\n\n<p>Napadalci niso spremenili izvorne kode v uradnem repozitoriju WordPress.org. Pridobili so zapisovalni dostop do vedra s stati\u010dnimi podatki oziroma do povezane infrastrukture in zamenjali legitimne odgovore JSON z zlonamernimi zapisi. To ka\u017ee na resen vdor v poverilnice shrambe v oblaku ali interno infrastrukturo BdThemes.<\/p>\n\n\n\n<p>Vti\u010dnik ob <code>admin_init<\/code> brezpogojno doda JavaScript v brskalnik. Skripta se zato za\u017eene pri vsakem nalaganju katerekoli strani <code>wp-admin<\/code>, pridobi podatke o pasici z API-ja in sestavi element HTML v DOM-u.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">XSS v atributu <code>id<\/code><\/h2>\n\n\n\n<p>Ranljivost cross-site scripting (XSS) nastane, ker koda polje <code>display_id<\/code> iz oddaljenega odgovora JSON brez ustreznega ube\u017eanja vstavi v atribut HTML <code>id<\/code>. \u010ce <code>display_id<\/code> manjka, uporabi <code>id<\/code>, nato pa vrednost <code>default<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Vrednost prihaja iz oddaljenega JSON-a.\nvar f = t.display_id || t.id || &quot;default&quot;;\n\n\/\/ Nevarno: vrednost se brez ube\u017eanja sestavi v atribut HTML.\nvar m = &quot;bdt-admin-biggopti-api-biggopti-&quot; + f;\nA = 'id=&quot;' + m + '&quot;';\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#6A737D\">\/\/ Vrednost prihaja iz oddaljenega JSON-a.<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">var<\/span><span style=\"color:#E1E4E8\"> f <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#E1E4E8\"> t.display_id <\/span><span style=\"color:#F97583\">||<\/span><span style=\"color:#E1E4E8\"> t.id <\/span><span style=\"color:#F97583\">||<\/span><span style=\"color:#9ECBFF\"> \"default\"<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#6A737D\">\/\/ Nevarno: vrednost se brez ube\u017eanja sestavi v atribut HTML.<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">var<\/span><span style=\"color:#E1E4E8\"> m <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#9ECBFF\"> \"bdt-admin-biggopti-api-biggopti-\"<\/span><span style=\"color:#F97583\"> +<\/span><span style=\"color:#E1E4E8\"> f;<\/span><\/span>\n<span class=\"line\"><span style=\"color:#79B8FF\">A<\/span><span style=\"color:#F97583\"> =<\/span><span style=\"color:#9ECBFF\"> 'id=\"'<\/span><span style=\"color:#F97583\"> +<\/span><span style=\"color:#E1E4E8\"> m <\/span><span style=\"color:#F97583\">+<\/span><span style=\"color:#9ECBFF\"> '\"'<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Ista skripta vrednost za atribut <code>data-display-id<\/code> pravilno ube\u017ei z zamenjavo znakov <code>&amp;<\/code>, <code>&lt;<\/code>, <code>&gt;<\/code>, in <code>&quot;<\/code>. Za atribut <code>id<\/code> tega ne naredi, \u010deprav bi morala enako obravnavati vsak podatek, ki prihaja iz zunanjega odgovora.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>function escapeHtml(value) {\n  return (value || &quot;&quot;)\n    .replace(\/&amp;\/g, &quot;&amp;amp;&quot;)\n    .replace(\/&lt;\/g, &quot;&amp;lt;&quot;)\n    .replace(\/&gt;\/g, &quot;&amp;gt;&quot;)\n    .replace(\/&quot;\/g, &quot;&amp;quot;&quot;);\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">function<\/span><span style=\"color:#B392F0\"> escapeHtml<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#FFAB70\">value<\/span><span style=\"color:#E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  return<\/span><span style=\"color:#E1E4E8\"> (value <\/span><span style=\"color:#F97583\">||<\/span><span style=\"color:#9ECBFF\"> \"\"<\/span><span style=\"color:#E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    .<\/span><span style=\"color:#B392F0\">replace<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#DBEDFF\">&#x26;<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#F97583\">g<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">\"&#x26;amp;\"<\/span><span style=\"color:#E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    .<\/span><span style=\"color:#B392F0\">replace<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#DBEDFF\">&#x3C;<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#F97583\">g<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">\"&#x26;lt;\"<\/span><span style=\"color:#E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    .<\/span><span style=\"color:#B392F0\">replace<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#DBEDFF\">><\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#F97583\">g<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">\"&#x26;gt;\"<\/span><span style=\"color:#E1E4E8\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    .<\/span><span style=\"color:#B392F0\">replace<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#DBEDFF\">\"<\/span><span style=\"color:#9ECBFF\">\/<\/span><span style=\"color:#F97583\">g<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#9ECBFF\">\"&#x26;quot;\"<\/span><span style=\"color:#E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Zgodovina SVN ka\u017ee, da je neube\u017een vnos v atribut <code>id<\/code> najprej pri\u0161el v Prime Slider 1. marca 2026, v razli\u010dici 4.1.9 in reviziji <code>r3471891<\/code>, nato pa \u0161e v druge vti\u010dnike. Poznej\u0161e izdaje so za polje vsebine pasice dodale \u010distilnik na osnovi <code>DOMParser<\/code>, ki odstrani nevarne oznake HTML in inline handlerje, vendar <code>display_id<\/code> v atributu <code>id<\/code> ni dobil ube\u017eanja.<\/p>\n\n\n\n<p>Zlonamerni <code>display_id<\/code> zapre atribut <code>id<\/code> in doda handler dogodka <code>onanimationstart<\/code>. CSS-animacija ga spro\u017ei v 10 milisekundah, zato se JavaScript izvede tiho vsaki\u010d, ko prijavljeni skrbnik odpre stran nadzorne plo\u0161\u010de. Tako napadalec izkoristi \u017ee overjeno skrbni\u0161ko sejo v brskalniku.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ranljivi vti\u010dniki in ocena tveganja<\/h2>\n\n\n\n<p>Biggopti Library je ranljiv za XSS prek parametra <code>display_id<\/code> iz API-ja Sigmative zaradi nezadostnega ube\u017eanja izhoda. Ocena CVSS zna\u0161a 5,4 oziroma srednje tveganje, popravek pa ob razkritju \u0161e ni obstajal. Podrobnosti ranljivosti so na <a href=\"https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/id\/7bf1d6f9-afe2-41c2-968b-20dbc474cd73\">strani Wordfence Threat Intelligence<\/a>.<\/p>\n\n\n\n<p>Prizadeti so naslednji vti\u010dniki in njihovi slugi:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Element Pack Addons for Elementor &#8211; <code>bdthemes-element-pack-lite<\/code><\/li>\n\n\n<li>Prime Slider Addons for Elementor &#8211; <code>bdthemes-prime-slider-lite<\/code><\/li>\n\n\n<li>Pixel Gallery Addons for Elementor &#8211; <code>pixel-gallery<\/code><\/li>\n\n\n<li>Ultimate Post Kit Addons for Elementor &#8211; <code>ultimate-post-kit<\/code><\/li>\n\n\n<li>Ultimate Store Kit &#8211; Addon For WooCommerce, EDD and Elementor &#8211; <code>ultimate-store-kit<\/code><\/li>\n\n\n<li>Live Copy Paste for Elementor &#8211; <code>live-copy-paste<\/code><\/li>\n\n\n<li>Smart Admin Assistant &#8211; <code>smart-admin-assistant<\/code><\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Ve\u010dstopenjska zlonamerna koda<\/h2>\n\n\n\n<p>Vbrizgani handler pridobi zunanjo skripto glede na dosegljivost infrastrukture napadalca. Napad uporablja dva toka: primarni <code>w2.js<\/code> za vti\u010dnike z endpointom <code>api-data-all-records<\/code> in alternativni <code>x.js<\/code> za vti\u010dnike z endpointom <code>api-data-records<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Primarni tok <code>w2.js<\/code><\/h3>\n\n\n\n<p>Glavna koda <code>w2.js<\/code> najprej po\u0161lje izvor spletnega mesta na C2 endpoint <code>ia-cdn[.]com\/fz\/c<\/code> in prejme navodila za ciljanje. \u010ce C2 vrne stanje <code>skip<\/code> ali <code>done<\/code>, izvajanje prekine.<\/p>\n\n\n\n<p>Nato koda uporabi <code>X-WP-Nonce<\/code> iz aktivne skrbni\u0161ke seje ter prek WordPress REST API-ja ustvari novega uporabnika z vlogo administrator. \u010ce REST API ne uspe, uporabi obi\u010dajne oddaje obrazcev WordPressa.<\/p>\n\n\n\n<p>S C2 nato prenese ZIP la\u017enega vti\u010dnika in ga namesti prek standardnega obrazca za nalaganje vti\u010dnikov. Vti\u010dnik se skriva za nevtralno zvene\u010dim slugom, na primer <code>wp-smart-thumbnails<\/code>, vsebuje pa spletno lupino <code>emer-run.php<\/code>, ki jo napadalec neposredno prikli\u010de prek URL-ja.<\/p>\n\n\n\n<p><code>emer-run.php<\/code> namesti dva modula za obstojnost v imenik Must-Use vti\u010dnikov. Oba zajeta primerka sta imela \u010dasovne \u017eige prestavljene v september 2025, da bi se zlila z legitimnimi datotekami; imena datotek se med oku\u017ebami lahko spremenijo.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Prvi MU-vti\u010dnik doda stranska vrata za prijavo brez avtentikacije prek parametra URL <code>?_wplogin=&lt;token&gt;<\/code>. Cilja administratorja, ki je na spletnem mestu registriran najdlje.<\/li>\n\n\n<li>Drugi MU-vti\u010dnik skriva sledi analitikom: priklopi se na poizvedbe podatkovne zbirke WordPressa, skrije ustvarjene la\u017ene ra\u010dune s seznama uporabnikov in ustrezno zmanj\u0161a prikazano skupno \u0161tevilo uporabnikov.<\/li>\n\n<\/ul>\n\n\n\n<p>Koda ob vsakem koraku po\u0161lje rezultat na C2 prek <code>navigator.sendBeacon<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Alternativni tok <code>x.js<\/code><\/h3>\n\n\n\n<p>Alternativna skripta <code>x.js<\/code> je gostovala neposredno v infrastrukturi BdThemes. Iz imena gostitelja spletnega mesta izra\u010duna deterministi\u010dne poverilnice: uporabni\u0161ko ime sestavi kot <code>bd_<\/code> in \u0161estznakovni hash base36, geslo pa kot <code>Bd@26!<\/code>, isti hash in kon\u010dni znak <code>x<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#24292e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#e1e4e8;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>function makeCreds() {\n  var host = siteKey();\n  var hash = 0;\n\n  for (var i = 0; i &lt; host.length; i++) {\n    hash = ((hash &lt;&lt; 5) - hash + host.charCodeAt(i)) | 0;\n  }\n\n  var n = Math.abs(hash).toString(36).slice(0, 6);\n  return {\n    user: 'bd_' + n,\n    pass: 'Bd@26!' + n + 'x'\n  };\n}\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#F97583\">function<\/span><span style=\"color:#B392F0\"> makeCreds<\/span><span style=\"color:#E1E4E8\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  var<\/span><span style=\"color:#E1E4E8\"> host <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#B392F0\"> siteKey<\/span><span style=\"color:#E1E4E8\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  var<\/span><span style=\"color:#E1E4E8\"> hash <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> 0<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  for<\/span><span style=\"color:#E1E4E8\"> (<\/span><span style=\"color:#F97583\">var<\/span><span style=\"color:#E1E4E8\"> i <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#79B8FF\"> 0<\/span><span style=\"color:#E1E4E8\">; i <\/span><span style=\"color:#F97583\">&#x3C;<\/span><span style=\"color:#E1E4E8\"> host.<\/span><span style=\"color:#79B8FF\">length<\/span><span style=\"color:#E1E4E8\">; i<\/span><span style=\"color:#F97583\">++<\/span><span style=\"color:#E1E4E8\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    hash <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#E1E4E8\"> ((hash <\/span><span style=\"color:#F97583\">&#x3C;&#x3C;<\/span><span style=\"color:#79B8FF\"> 5<\/span><span style=\"color:#E1E4E8\">) <\/span><span style=\"color:#F97583\">-<\/span><span style=\"color:#E1E4E8\"> hash <\/span><span style=\"color:#F97583\">+<\/span><span style=\"color:#E1E4E8\"> host.<\/span><span style=\"color:#B392F0\">charCodeAt<\/span><span style=\"color:#E1E4E8\">(i)) <\/span><span style=\"color:#F97583\">|<\/span><span style=\"color:#79B8FF\"> 0<\/span><span style=\"color:#E1E4E8\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  var<\/span><span style=\"color:#E1E4E8\"> n <\/span><span style=\"color:#F97583\">=<\/span><span style=\"color:#E1E4E8\"> Math.<\/span><span style=\"color:#B392F0\">abs<\/span><span style=\"color:#E1E4E8\">(hash).<\/span><span style=\"color:#B392F0\">toString<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#79B8FF\">36<\/span><span style=\"color:#E1E4E8\">).<\/span><span style=\"color:#B392F0\">slice<\/span><span style=\"color:#E1E4E8\">(<\/span><span style=\"color:#79B8FF\">0<\/span><span style=\"color:#E1E4E8\">, <\/span><span style=\"color:#79B8FF\">6<\/span><span style=\"color:#E1E4E8\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color:#F97583\">  return<\/span><span style=\"color:#E1E4E8\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    user: <\/span><span style=\"color:#9ECBFF\">'bd_'<\/span><span style=\"color:#F97583\"> +<\/span><span style=\"color:#E1E4E8\"> n,<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">    pass: <\/span><span style=\"color:#9ECBFF\">'Bd@26!'<\/span><span style=\"color:#F97583\"> +<\/span><span style=\"color:#E1E4E8\"> n <\/span><span style=\"color:#F97583\">+<\/span><span style=\"color:#9ECBFF\"> 'x'<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  };<\/span><\/span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Skripta novemu ra\u010dunu pripne e-po\u0161tni naslov z domeno <code>@wordpress.org<\/code>, nato pa izid po\u0161lje C2. V brskalnikov <code>localStorage<\/code> zapi\u0161e zastavico, \u010de je na voljo, da istega postopka ne izvaja znova.<\/p>\n\n\n\n<p>Ker algoritem vedno ustvari enake poverilnice za isto ime gostitelja, napadalcem ni treba centralno hraniti seznama kompromitiranih mest. Pri pregledu sumljive domene lahko zato natan\u010dno izra\u010duna\u0161 pri\u010dakovano uporabni\u0161ko ime in geslo ter ju poi\u0161\u010de\u0161.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Kazalniki kompromitacije<\/h2>\n\n\n\n<p>Pri pregledu stre\u017enika, podatkovne zbirke in omre\u017enih dnevnikov poi\u0161\u010di vse spodnje kazalnike. Najdba enega od njih zahteva celovit odziv na incident, ne le odstranitev posamezne datoteke.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Zunanji endpointi<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Primarna zlonamerna koda: <code>ia-cdn[.]com\/fz\/w2.js<\/code><\/li>\n\n\n<li>C2 beacon endpoint: <code>ia-cdn[.]com\/fz\/c<\/code><\/li>\n\n\n<li>Kompromitirani endpoint ponudnika: <code>api[.]sigmative[.]io\/prod\/store\/api\/biggopti\/api-data-all-records<\/code><\/li>\n\n\n<li>Kompromitirani endpoint ponudnika: <code>api[.]sigmative[.]io\/prod\/store\/api\/biggopti\/api-data-records<\/code><\/li>\n\n\n<li>Alternativna koda na infrastrukturi ponudnika: <code>api[.]sigmative[.]io\/prod\/store\/api\/biggopti\/x.js<\/code><\/li>\n\n<\/ul>\n\n\n\n<p>Oba endpointa JSON zdaj vra\u010data \u010diste podatke, vendar to ne odstrani \u017ee izvedene kode, ustvarjenih ra\u010dunov ali name\u0161\u010denih stranskih vrat. Endpointa sta bila v \u010dasu kompromitacije vir zastrupljenih podatkov.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Datoteke in zapisi v podatkovni zbirki<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Spletna lupina: <code>emer-run.php<\/code> z MD5 <code>1024732009983dd5e54b4cf5593f04d4<\/code>.<\/li>\n\n\n<li>MU-vti\u010dnik za magic login: <code>class-wp-token-validate.php<\/code> z MD5 <code>7719cd98a35ffad2771f26d1ceab7d27<\/code>.<\/li>\n\n\n<li>MU-vti\u010dnik za prikrivanje: <code>class-wp-query-9d127ff3.php<\/code> oziroma podobno ime po vzorcu <code>class-wp-query-*.php<\/code>, z MD5 <code>9aadc3e5c5242b273bd17c5bdc358845<\/code>.<\/li>\n\n\n<li>MU-vti\u010dnik, poimenovan kot health check: <code>wp-cache-optimizer.php<\/code> z MD5 <code>e450ae5bc4bfc0d960dded06a76bb8e9<\/code>.<\/li>\n\n\n<li>Mo\u017enost podatkovne zbirke <code>fz_emer_login_tokens<\/code>, ki shranjuje \u017eetone za magic login.<\/li>\n\n\n<li>Mo\u017enost podatkovne zbirke <code>fz_emer_done_v1<\/code>, ki ozna\u010duje dokon\u010dano kompromitacijo.<\/li>\n\n\n<li>Uporabni\u0161ki ra\u010duni z e-po\u0161tnim naslovom na domeni <code>@wordpress.org<\/code> ali <code>@developer.wordpress.org<\/code>.<\/li>\n\n\n<li>Uporabni\u0161ka imena po vzorcu <code>bd_<\/code> in \u0161est alfanumeri\u010dnih znakov.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u010casovnica incidenta<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n\n<li><strong>1. marec 2026:<\/strong> Biggopti API JavaScript pride v Prime Slider 4.1.9 (SVN <code>r3471891<\/code>). <code>display_id<\/code> se brez ube\u017eanja vstavi v atribut <code>id<\/code>, uporabi pa se endpoint <code>api-data-records<\/code>.<\/li>\n\n\n<li><strong>10. maj 2026:<\/strong> endpoint se spremeni v <code>api-data-all-records<\/code>. Za polje vsebine dodajo \u010distilnik <code>DOMParser<\/code>, atribut <code>id<\/code> pa ostane ranljiv.<\/li>\n\n\n<li><strong>23. junij 2026:<\/strong> zastrupljena kampanja v API-ju dobi <code>start_date<\/code> za obvestilo \u00bbSummer Sale\u00ab. To je najzgodnej\u0161i mo\u017eni datum aktivnega XSS-a.<\/li>\n\n\n<li><strong>6. avgust 2026 ob 22:40 UTC:<\/strong> zadnja sprememba zastrupljenega <code>api-data-records<\/code>.<\/li>\n\n\n<li><strong>7. avgust 2026 ob 09:11 UTC:<\/strong> zadnja sprememba zastrupljenega <code>api-data-all-records<\/code>.<\/li>\n\n\n<li><strong>7. avgust 2026:<\/strong> napad zaznajo v dejanskih oku\u017ebah, vti\u010dnike pa v imeniku WordPress zaprejo do pregleda.<\/li>\n\n\n<li><strong>7. avgust 2026 ob 16:56 UTC:<\/strong> zajamejo artefakte preiskave.<\/li>\n\n\n<li><strong>8. avgust 2026:<\/strong> oba API endpointa znova vra\u010data \u010dist JSON.<\/li>\n\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Kaj naredi zdaj<\/h2>\n\n\n\n<p>\u010ce uporablja\u0161 kateregakoli od prizadetih vti\u010dnikov, ne \u010dakaj na zgolj posodobitev. Preglej seznam uporabnikov, vklju\u010dno s skritimi oziroma sumljivimi administratorji, imenik <code>wp-content\/mu-plugins<\/code>, imenike vti\u010dnikov ter tabelo mo\u017enosti v podatkovni zbirki za vse navedene kazalnike.<\/p>\n\n\n\n<p>Preveri tudi dostopne dnevnike in DNS oziroma HTTP promet za povezave z <code>ia-cdn[.]com<\/code> ter pregledaj, ali je kdo neposredno klical sumljive PHP datoteke. Ker napad uporablja legitimno sejo administratorja in lahko za seboj pusti ve\u010d plasti obstojnosti, odstrani la\u017ene ra\u010dune, spletno lupino in MU-vti\u010dnike \u0161ele po forenzi\u010dnem zajemu dokazov ter rotaciji vseh skrbni\u0161kih poverilnic, gesel podatkovne zbirke, API-klju\u010dev in sej.<\/p>\n\n\n\n<p>C2 domena je povezana tudi z napadi na dobavno verigo vti\u010dnikov Advanced Responsive Video Embedder in OptinMonster v prej\u0161njih dveh mesecih. Cilj te kampanje je tiha, mno\u017ei\u010dna skrbni\u0161ka obstojnost in oddaljeno izvajanje kode v WordPress okoljih.<\/p>\n\n\n\n<div class=\"wp-block-group callout callout-warning is-style-warning is-layout-flow wp-block-group-is-layout-flow\" style=\"border-width:1px;border-radius:8px;padding-top:1rem;padding-right:1.5rem;padding-bottom:1rem;padding-left:1.5rem\">\n\n<h4 class=\"wp-block-heading callout-title\">Preveri ve\u010d kot le integriteto datotek<\/h4>\n\n\n<p>\u010ciste datoteke vti\u010dnika ne dokazujejo, da spletno mesto ni kompromitirano. Ta napad je zlorabil zaupanja vreden tok oddaljenih podatkov, nato pa je v prijavljeni seji ustvaril ra\u010dune, nalo\u017eil zlonamerno kodo in namestil obstojnost.<\/p>\n\n<\/div>\n\n\n<div class=\"references-section\">\n                <h2>Reference \/ Viri<\/h2>\n                <ul class=\"references-list\"><li><a href=\"https:\/\/www.wordfence.com\/blog\/2026\/08\/psa-supply-chain-compromise-in-bdthemes-ecosystem-via-poisoned-api-response\/\" target=\"_blank\" rel=\"noopener noreferrer\">PSA: Supply Chain Compromise in BdThemes Ecosystem via Poisoned API Response<\/a><\/li><li><a href=\"https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/id\/7bf1d6f9-afe2-41c2-968b-20dbc474cd73\" target=\"_blank\" rel=\"noopener noreferrer\">Biggopti Library (Various Versions) &#8211; Cross-Site Scripting via display_id from Sigmative API<\/a><\/li><\/ul>\n            <\/div>","protected":false},"excerpt":{"rendered":"<p>Napadalci so prek zastrupljenega promocijskega JSON-a v vti\u010dnikih BdThemes dobili skrbni\u0161ki dostop do WordPress mest. Preveri, kateri artefakti razkrijejo \u017ee izvedeno oku\u017ebo.<\/p>\n","protected":false},"author":47,"featured_media":263,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[144,11,71,10,134],"class_list":["post-264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-varnost","tag-dobavna-veriga","tag-varnost","tag-vticniki","tag-wordpress","tag-xss"],"_links":{"self":[{"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/posts\/264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/users\/47"}],"replies":[{"embeddable":true,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/comments?post=264"}],"version-history":[{"count":0,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/posts\/264\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/media\/263"}],"wp:attachment":[{"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/media?parent=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/categories?post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/helloblog.io\/sl\/wp-json\/wp\/v2\/tags?post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}