BdThemes supply chain атака през JSON API: как да провериш сайта си
Компрометирана външна JSON емисия засегна седем разширения на BdThemes за WordPress. Атаката не променя нито един файл в хранилището на WordPress.org и не изисква обновяване на разширението, за да зарази сайт – достатъчно е администратор да отвори която и да е страница в wp-admin.
Нападателите са използвали XSS в компонента Biggopti, за да изпълнят JavaScript в сесията на влязъл администратор. После скриптът може да добави нов администратор, да качи разширение с webshell и да инсталира устойчиви задни врати като Must-Use разширения. Всички засегнати разширения временно са затворени в директорията на WordPress до приключване на проверката.
Риск от пълно превземане на сайта
Ако сайтът ти използва някое от изброените разширения, провери го незабавно за индикаторите по-долу. Не разчитай само на проверка за променени файлове: тази кампания работи през отдалечен API и може да не остави промени във файловете на самото разширение.
Засегнати разширения и оценка на риска
Уязвимостта в Biggopti има CVSS оценка 5,4 от 10 – средна тежест – и няма корекция. Тя засяга следните разширения:
- 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
Проблемът е Cross-Site Scripting (XSS): Biggopti приема полето display_id от Sigmative API и го добавя в HTML без достатъчно escaping. Всеки, който получи контрол над този API, може да инжектира скрипт, който браузърът изпълнява при отваряне на заразена административна страница.
Как отдалечен банер заразява wp-admin
Biggopti е вътрешен компонент, който показва рекламни банери в таблото на WordPress. Той взема данните от API на BdThemes, зад което стои статичен DigitalOcean Spaces bucket, защитен с Cloudflare. Това не е динамичен приложен сървър, а JSON файлове от object storage.
Всяко разширение, което използва Biggopti, добавя негов JavaScript asset чрез admin_init. Затова кодът се изпълнява безусловно при всяко зареждане на страница в wp-admin, извлича банера от API и сглобява контейнер в Document Object Model (DOM). Уязвимият път директно прави display_id част от HTML атрибута id:
// Стойността идва от отдалечения JSON без escaping.
var f = t.display_id || t.id || "default";
var m = "bdt-admin-biggopti-api-biggopti-" + f;
A = 'id="' + m + '"';В същия код data-display-id се escape-ва чрез функция, която заменя &, <, >, и двойните кавички с HTML entities. Това показва, че липсата на escaping при id не идва от техническа необходимост. Минифицирането или bundling-ът правят структурата на кода по-трудна за четене, но не премахват проблема.
function escapeHtml(value) {
return (value || "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}Историята на SVN показва, че Prime Slider 4.1.9 е получил незащитеното вмъкване на 1 март 2026 г., а после то е преминало и към други разширения. По-късните версии добавят sanitizer с DOMParser за полето със съдържанието на банера – той премахва опасни HTML елементи и inline handlers – но атрибутът id остава незащитен.
Нападател с достъп за запис до storage bucket-а е заменил легитимните JSON отговори със зловредни. Манипулираното display_id затваря атрибута id, добавя onanimationstart handler и активира CSS анимация. Събитието се задейства за около 10 милисекунди и стартира кода тихо при всяко отваряне на административна страница.
Към момента на улавяне на артефактите отговорът съдържа поле display_id, което започва с SAFE" onanimationstart=... и декодира JavaScript за изтегляне и изпълнение на външен скрипт от api.sigmative.io. Банерът е маркиран като adminDashboard и носи заглавие „Build more. Pay less. This Summer“.
Какво правят двата payload-а
Инжектираният handler избира външен скрипт според достъпността на инфраструктурата на нападателите. Кампанията използва два различни payload-а и изпраща резултатите от изпълнението към command-and-control (C2) сървър.
Основен payload: w2.js
Основният скрипт се подава към разширенията, които използват endpoint-а api-data-all-records. Той работи в автентикираната сесия на администратора и преминава през следната последователност:
- Проверява C2. Свързва се с
ia-cdn[.]com/fz/c, изпраща origin на сайта и взема инструкции за таргетиране. Ако C2 върнеskipилиdone, прекратява работата си. - Добавя неоторизиран администратор. Използва
X-WP-Nonceот активната администраторска сесия, за да създаде потребител през WordPress REST API. Ако това не успее, подава стандартни формуляри. - Инсталира webshell. Изтегля ZIP, представен като разширение, от C2 и го качва през обичайния формуляр за качване на разширения. Фалшивото разширение използва slug като
wp-smart-thumbnailsили друго неутрално име и съдържа webshellemer-run.php, който се извиква директно през URL. - Инсталира Must-Use задни врати. При извикване
emer-run.phpзаписва два модула в директорията за Must-Use разширения. И двата намерени образеца са с променено време до септември 2025 г., за да изглеждат като легитимни стари файлове; имената могат да се различават между инфекциите. Първият е magic-login заден вход през?_wplogin=<token>, насочен към администратора с най-ранна регистрация в сайта. Вторият прихваща заявки към базата от данни, скрива създадените акаунти от списъка с потребители и намалява показвания общ брой потребители. - Изнася резултатите. Изпраща статуса на всяка фаза към C2 чрез
navigator.sendBeacon.
Алтернативен payload: x.js
Вторият скрипт е бил хостван директно в инфраструктурата на BdThemes и се подава към разширенията, които използват api-data-records. Той генерира предвидими администраторски данни от hostname на жертвата: изчислява 32-битов hash, превръща абсолютната му стойност в base36 и взема първите шест знака.
Потребителското име има вид bd_ плюс шестзнаковия base36 hash, а паролата е Bd@26!, следвана от същия hash и x. Скриптът свързва акаунта с имейл в домейна @wordpress.org. Понеже данните са детерминистични, нападателите не трябва да пазят централен списък със заразените сайтове, а екипът по реакция може да изчисли търсения акаунт за проверяван домейн.
След като генерира тези данни, x.js отваря /wp-admin/user-new.php с credentials same-origin, извлича nonce от HTML и изпраща формуляр за създаване на потребител с роля administrator. Запазва флаг в localStorage, когато това е възможно, за да не повтаря операцията, и изпраща към C2 статуса, потребителското име, паролата, origin-а, URL на logout и URL на текущата страница. Първо използва navigator.sendBeacon, а при неуспех изпраща fetch POST заявка в режим no-cors с keepalive.
Обхват и индикатори за компрометиране
C2 домейнът се свързва със същите нападатели, които стоят зад supply chain атаките срещу Advanced Responsive Video Embedder и OptinMonster през предходните два месеца. Целта е масово и тихо запазване на администраторски достъп и отдалечено изпълнение на код в WordPress среди.
Тук не е нужен първоначален достъп до отделните сайтове. Компрометирането на рекламния feed е достатъчно, за да превърне доверените административни известия в канал за malware. Наличието на зловредните JSON записи и x.js направо в bucket-а на доставчика сочи сериозно компрометиране на cloud credentials или вътрешна инфраструктура на BdThemes.
Потърси следните мрежови индикатори:
- Основен payload:
ia-cdn[.]com/fz/w2.js - C2 beacon endpoint:
ia-cdn[.]com/fz/c - Компрометирани API endpoint-и, които вече връщат чист JSON:
api[.]sigmative[.]io/prod/store/api/biggopti/api-data-all-records,api[.]sigmative[.]io/prod/store/api/biggopti/api-data-recordsиapi[.]sigmative[.]io/prod/store/api/biggopti/x.js.
Провери файловата система и базата от данни за следните индикатори:
- Webshell
emer-run.phpс MD51024732009983dd5e54b4cf5593f04d4. - Must-Use magic-login модул
class-wp-token-validate.phpс MD57719cd98a35ffad2771f26d1ceab7d27. - Must-Use stealth модул
class-wp-query-9d127ff3.phpили подобно име от видаclass-wp-query-*.php, с MD59aadc3e5c5242b273bd17c5bdc358845. - Must-Use модул, представен като health check,
wp-cache-optimizer.php, с MD5e450ae5bc4bfc0d960dded06a76bb8e9. - Опция в базата от данни
fz_emer_login_tokens, която пази magic-login токени. - Опция в базата от данни
fz_emer_done_v1, която отбелязва завършено компрометиране. - Акаунти с имейл в
@wordpress.orgили@developer.wordpress.org. - Потребителски имена от вида
bd_и шест буквено-цифрови знака след префикса.
Времева линия
- 1 март 2026 г. – Biggopti API JavaScript влиза в Prime Slider 4.1.9 чрез SVN
r3471891.display_idсе добавя без escaping към атрибутid, а API endpoint-ът еapi-data-records. - 10 май 2026 г. – endpoint-ът се сменя с
api-data-all-records. Добавя сеDOMParsersanitizer за полето със съдържание, ноidостава незащитен. - 23 юни 2026 г. –
start_dateв компрометираната API кампания посочва „Summer Sale“ известие. Това е най-ранната възможна дата, на която XSS може да е бил активен. - 6 август 2026 г., 22:40 UTC – последната промяна на компрометирания
api-data-records. - 7 август 2026 г., 09:11 UTC – последната промяна на компрометирания
api-data-all-records. - 7 август 2026 г. – атаката е наблюдавана в реална среда и засегнатите разширения са затворени в директорията на WordPress до проверка.
- 7 август 2026 г., 16:56 UTC – запазени са артефакти от разследването.
- 8 август 2026 г. – и двата API endpoint-а вече връщат чист JSON.
Какво да направиш сега
Провери потребителите в базата от данни и в таблото, но не приемай списъка в wp-admin за достатъчен: stealth модулът може да скрие акаунт и да промени броя потребители. Търси директно в таблицата с потребители за посочените имейл домейни и потребителския шаблон bd_ плюс шест знака.
Прегледай директорията за разширения, директорията за Must-Use разширения и таблицата с опции за всички IoC. Провери web access и DNS логове за връзки към ia-cdn[.]com, както и дали няма директни заявки към emer-run.php. Ако откриеш какъвто и да е индикатор, третирай инсталацията като напълно компрометирана: премахни зловредните акаунти и файлове, прекрати активните сесии, смени администраторските пароли и всички тайни, до които сайтът може да е имал достъп.
Премахни или изолирай засегнатите разширения, докато няма потвърдена корекция, и провери бекъпите, преди да възстановяваш от тях. Само файлов integrity scan няма да хване първоначалната атака, защото тя идва от доверен отдалечен JSON отговор, а не от редактиран файл на диска.
Засичане
Правилата за WAF и сигнатурите за тази кампания са налични от 7 август 2026 г. за Wordfence Premium, Care, Response и платения Wordfence CLI. Безплатните потребители на Wordfence и Wordfence CLI ще ги получат след стандартно забавяне от 30 дни.
След инцидента добави проверка на външните ресурси, които разширенията зареждат в административната зона, към процеса си за security review. Supply chain рискът не свършва с подписания ZIP пакет: API отговор, CDN asset или статичен storage bucket също може да изпълни код в доверения браузърен контекст на администратора.
Препратки / Източници
- 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
Мария Иванова
Главен редактор на българския екип, разработчик на AI и машинно обучение. PyTorch и обработката на естествен език са моите основни области. Бъдещето вече е тук.
Всички публикации