Всё как в филь­ме про хакеров: отпра­вил одно сооб­щение и получил пол­ноцен­ный RCE. Уяз­вимость в W3 Total Cache шокиру­ет не толь­ко прос­тотой ата­ки, но и мас­шта­бами, ведь этот пла­гин для WordPress уста­нов­лен на мил­лионы сай­тов.

W3 Total Cache — один из самых извес­тных пла­гинов для WordPress, пред­назна­чен для кеширо­вания и повыше­ния про­изво­дитель­нос­ти сай­та. Уско­ряет заг­рузку стра­ниц сай­та за счет кеширо­вания раз­личных ком­понен­тов (стра­ницы, объ­екты, базы дан­ных, бра­узер­ный кеш). При­чем каж­дый ком­понент име­ет свои тон­кие нас­трой­ки. Пла­гин уста­нов­лен более чем на мил­лионе WordPress-сай­тов.

warning

Статья име­ет озна­коми­тель­ный харак­тер и пред­назна­чена для спе­циалис­тов по безопас­ности, про­водя­щих тес­тирова­ние в рам­ках кон­трак­та. Автор и редак­ция не несут ответс­твен­ности за любой вред, при­чинен­ный с при­мене­нием изло­жен­ной информа­ции. Рас­простра­нение вре­донос­ных прог­рамм, наруше­ние работы сис­тем и наруше­ние тай­ны перепис­ки прес­леду­ются по закону.

В этой статье мы раз­берем недав­нюю уяз­вимость CVE-2025-9501, которая кро­ется в динами­чес­ких фраг­ментах W3TC. Наша цель — под­твер­дить воз­можность ата­ки и пос­мотреть, почему она работа­ет.

W3 Total Cache под­держи­вает так называ­емые динами­чес­кие фраг­менты — спе­циаль­ные мар­керы mfunc и mclude, которые поз­воля­ют выпол­нять PHP-код или под­клю­чать фай­лы даже внут­ри пол­ностью закеши­рован­ной HTML-стра­ницы. Эта воз­можность пред­назна­чена для вывода поль­зователь­ских дан­ных (нап­ример, име­ни авто­ризо­ван­ного поль­зовате­ля или содер­жимого кор­зины) без отклю­чения сер­верно­го кеширо­вания целиком.

Ес­ли такие фраг­менты не исполь­зовать или исполь­зовать некор­рек­тно, воз­можна типич­ная ошиб­ка кеширо­вания: пер­сональ­ные дан­ные одно­го поль­зовате­ля могут быть сох­ранены как ста­тичес­кие и показа­ны дру­гим. Это логичес­кая проб­лема кон­фигура­ции — еще не сама уяз­вимость.

Суть уяз­вимос­ти CVE-2025-9501 в дру­гом. Пла­гин обра­баты­вает мар­керы mfunc и mclude без жес­ткой при­вяз­ки к источни­ку кон­тента: ему неваж­но, были ли они добав­лены раз­работ­чиком в шаб­лон или попали в стра­ницу из поль­зователь­ско­го вво­да. При опре­делен­ных усло­виях это поз­воля­ет зло­умыш­ленни­ку внед­рить такие мар­керы и добить­ся выпол­нения про­изволь­ного PHP-кода на сер­вере, то есть при­вес­ти к уда­лен­ному выпол­нению кода.

Вот при­мер того, как может выг­лядеть встав­ка мак­росов:

<?-- mfunc secret -->...PHP code...<?-- /mfunc secret -->
<?-- mclude secret -->./path/to/file.php<?-- /mclude secret -->
 

Подготовка лаборатории

Для тес­та можешь уста­новить любую вер­сию WordPress. Дви­жок никак не защища­ет от инъ­екции, поэто­му в зоне рис­ка — любой сайт с пла­гином W3 Total Cache вер­сии ниже 2.18.13.

Поп­равь php.ini, что­бы пла­гин мож­но было заг­рузить из архи­ва. Слиш­ком малень­кие зна­чения кон­стант при­ведут к ошиб­ке «Ссыл­ка уста­рела».

upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 1024M
max_execution_time = 300
max_input_time = 300

Не забудь рес­тарта­нуть Apache.

Ка­чаем пла­гин:

curl -LO https://downloads.wordpress.org/plugin/w3-total-cache.2.8.12.zip

И уста­нав­лива­ем, заг­рузив архив через админку WordPress.

Пос­ле акти­вации перехо­дим в раз­дел Performance. Пла­гин авто­мати­чес­ки редирек­тит на мас­тер уста­нов­ки. Жмем Decline, что­бы отка­зать­ся от сбо­ра дан­ных о работе пла­гина. Затем най­дем ссыл­ку skip this setup guide, что­бы отклю­чить мас­тер уста­нов­ки. В Performance → General Settings вклю­чаем Page Cache и сох­раня­ем изме­нения (синяя кноп­ка ввер­ху).

Page Cache включен
Page Cache вклю­чен

Те­перь нуж­но добавить под­дер­жку динами­чес­ких фраг­ментов. Пла­гин W3TC смот­рит на кон­стан­ту W3TC_DYNAMIC_SECURITY: если она есть, ищет встав­ки кода на стра­ницах сай­та. Ищем в wp-config.php стро­ку define('WP_CACHE', true) и добав­ляем перед ней

// Значение 'secretic' привел для примера. Можно указать любое значение, которое не порушит регулярное выражение функции _has_dynamic*()
define('W3TC_DYNAMIC_SECURITY', 'secretic');

Ес­ли нет кон­стан­ты WP_CACHE, про­верь пра­ва на пап­ку с WordPress. Пра­ва на пап­ки дол­жны быть 755, на фай­лы — 644. Ина­че обно­ви пра­ва и пере­уста­нови пла­гин.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии