Статья Воскрешение уязвимости PHPUnit RCE

Данная статья является переводом. Оригинал вот

Как только патч для ПО выпущен, мы думаем, что проблема решена, и баг теперь не работает. В большинстве случаев это не так. Для решения этой проблемы от всех разработчиков требуется использование последней версии патча. Поскольку обновление не является особенно тривиальным действием, разработчикам необходимо планировать заранее и вставлять изменения через процесс разработки, планируя подходящее время для применения. В примерах, приведённых ниже, вы увидите, что иногда, даже этого недостаточно.

В рамках исследования, проведенного в Imperva, наблюдается около 9 млн попыток атак с использованием уязвимости CVE-2017-9841. Являясь одним из наиболее эксплуатируемых CVE 2019 года, такая старая уязвимость была, по сути, воскрешена из мертвых, поэтому было любопытно, почему она стала такой популярна среди злоумышленников.

Попытки атак по годам:
  • 2019 - около 7 млн за последние шесть месяцев.
  • 2020 год - около 2 млн до января
График 1: Попытки атак по месяцам

1588238206623.png


Как мы видим, около 70% атак было совершено в период между последними двумя месяцами 2019 года по январь включительно.

Сфера применения CVE-2017-9841

Чтобы понять такую шумиху вокруг CVE, нужно понять смысл уязвимости, и посмотреть, как эта уязвимость может быть использована, и как её можно исправить. В данной статье мы рассмотрим все эти аспекты.

27 июня 2017 года, была выявлена уязвимость для удаленного выполнения кода (CVE-2017-9841) в PHPUnit, широко используемом фреймворке тестирования для PHP, который используется для выполнения юнит-тестов в цикле разработки приложений. К сожалению, многие процессы разработки не являются оптимальными, и этот фреймворк остается включенным в продакшене, что делает жизнь злоумышленников слаще.

С тех пор, как этот фреймворк начали использовать в популярных CMS (Content Management Systems), такими как WordPress, Drupal и Prestashop, а также многими модулями, созданными сторонними разработчиками, масштабы данной бреши в безопасности могут быть достаточно широкими.

Вот, например, несколько известных модулей, которые внедряются в продакшен - в том числе и в фреймворк PHPUnit:
  • Prestashop: (autoupgrade ,pscartabandonmentpro ,ps_facetedsearch, Gamification, ps_checkout)
  • WordPress: ( плагин Jekyll Exporter, Dzs-videogallery, cloudflare, MediaWiki, Moodle)
  • Drupal: (Mailchimp/Mailchimp commerce – Drupal опубликовал Public Service Announcement ( ) )
Следует учитывать, что даже если вы запатчите "PHPUnit" как таковой, вы все равно будете уязвимы при использовании фреймворка, который основан на старых версиях.

Исследование

Первым этапом нашего исследования был поиск данного CVE в средствах массовой информации.

В середине декабря 2019 года были опубликованы темы на форумах технологического сообщества, от пользователей, жаловавшихся на подозрительные файлы, которые, возможно, были встроены в папку PHPUnit.

Кроме того, 7 января 2020 года PrestaShop (предоставляющее решение для электронной коммерции, написанное на PHP) опубликовал об уязвимости PHPUnit, используемой вредоносной программой XsamXadoo Bot, которая могла быть использована для получения доступа к PHP-серверу и получения контроля над ним. Вредоносная активность была обнаружена 2 января.

Затем мы вернулись к нашим данным для анализа атак PHPUnit, нацеленных на наших пользователей, и обнаружили, что релиз Prestashop покрывал лишь верхушку айсберга - это была не единственная кампания, пытавшаяся воспользоваться этой уязвимостью.

На таблице под 2 номером, можно увидеть, что, как минимум десять кампаний, за последние три месяца использовали эту уязвимость. Хотя XsamXadoo и является одной из них, она определенно не самая крупная.

Прежде чем рассматривать кампании, важно их четко определить.

Кампания - это попытка атаки, которая использует одну и ту же полезную нагрузку, и используется несколькими IP-адресами для атаки на несколько сайтов.

Таблица 2: Статистика кампаний PHPUnit

Название кампанииКоличество запросовКоличество атакующих IPКоличество сайтовМаксимальное количество атак за день
sssp.php27,245,8292221,0638,192,880
traber12,523,2612171,2704,475,629
h0d3_g4nt3ng5,896,87010526,872433,069
Raiz0WorM1,367,67819118,31887,455
RCE_VULN1,762133,058105,131
kill.php164,2814713,01854,332
probing137,1381599,5947,831
0x66660,865522,6307,991
XsamXadoo_Bot8,83664502,997
Other Campaigns246,2309749,19510,743

Из вышеприведенных подробностей видно, что двумя самыми популярными кампаниями являются sssp.php и traber с максимальным количеством атак в восемь и четыре миллиона в день соответственно.

На графике под 3 номером, можно увидеть, статистику атак от этих кампаний:

График 3: Атаки PHPUnit-кампаний

1588238367183.png


Теперь давайте посмотрим на кампании за последние три месяца:

График 4: Временные рамки PHPUnit кампании

1588238388334.png


Из хронологии мы можем узнать, что многие кампании вели свою активность в течение длительного времени. Кроме того, мы можем увидеть два пика наших двух ведущих кампаний - sssp.php и traber - в две конкретные даты - 21 ноября 2019 года и 4 января 2020 года.

Таким образом, несмотря на то, что уязвимости уже более двух лет, хакеры все еще пытаются ее применять. Prestashop выявил одну кампанию, но этого мало, и необходимо гораздо больше , чем просто сидеть и ждать, пока сеть будет заражена уязвимым сервером.

Глубокое погружение в детали CVE-2017-9841


Что бы понять корень проблемы, приведшей к уязвимости, давайте сначала рассмотрим исправление для файла PHP-Unit eval-stdin.php от 11 ноября 2016 года:

1588238417440.png


Чтобы понять, что означает, и какие отличия от php://input и php://stdin, сначала нужно узнать, что такое SAPI.

Механизм, управляющий взаимодействием "внешнего мира" с движком PHP, SAPI означает "Server API".

php://input предназначен для использования с web-based (удаленным) SAPI.

php://stdin предназначен для использования с CLI (локальными) SAPI.

Функция file_get_contents() считывает весь файл в строку, затем eval() выполняет эту строку.

php://input - это поток, доступный только для чтения, который позволяет читать необработанные данные из тела запроса.

Таким образом, исходный PHP-код получает файл через входной поток, затем преобразует его в строку и выполняет его.

Это позволяет злоумышленнику выполнять произвольный код через HTTP-запрос к eval-stdin.php.

Изменение устраняет возможность передавать входной файл, отправленный в веб-контексте, так как файл ожидает входной код от STDIN (локальный).

10 декабря 2019 года в eval-stdin.php было добавлено дополнительное исправление, в котором CVE не указывало на этот патч безопасности.

1588238438753.png


Чтобы объяснить это изменение, нам нужно понять, что означает PHP_SAPI.

PHP может быть запущен как модуль веб-сервера, как Common Gateway Interface (CGI) Общий интерфейс шлюза - приложение из командной строки как CLI-скрипт. Поэтому, добавив это условие в файл eval-stdin.php, разработчик стремился исключить возможность выполнения PHP-файла в контексте, отличном от 'cli' или 'phpdbg'.

Напомним, что в предыдущем изменении разработчик изменил использование с php://input на php://stdin. Добавив ограничение только для 'cli' и 'phpdbg', они сужают доступ к запуску произвольного PHP на сервере.

Но зачем они это сделали?

Одно из предположений заключается в том, что существует возможность как-то использовать этот код, передавая произвольный код через stdin. Злоумышленник может использовать CGI для обхода ограничения stdin, так как CGI работает локально на сервере, он может передать параметр через STDIN, оставляя приложение уязвимым даже после применения вышеописанного исправления 2016 года.

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

Рисунок 5: Блок-схема новой PHPUnit-атаки

1588238467733.png


8 января мы увидели несколько , связанных с уязвимостью PHPUnit, в которых говорилось, об обнаружении дополнительной уязвимости в PHPUnit версий 7.5.19 и 8.5.1, которая еще не была опубликована. Сопровождающий PHPUnit подтвердил уязвимость, и был отправлен запрос на CVE.

Однако, в тот же день из репозитория PHPUnit был удален eval-stdin.php с комментарием - "больше не используется".

Но было ли это на самом деле так?

На самом деле, мы подозреваем, что он был удален из-за потенциального риска, как упоминалось выше, при локальном доступе к eval-stdin.php.

Давайте перечислим поэтапно все аспекты, указанные в этой статье:

1588238491232.png


Небольшая цепочка событий:
  • 2016-11-13 - CVE-2017-9841 Исправление уязвимости
  • 2017-06-27 - CVE-2017-9841 Опубликована информация об уязвимости
  • 2017-06-27 – Был опубликован ProofOfConcept
  • 2019-09-04 - Drupal опубликовал PSA-2019-09-04
  • 2019-11-25 - Начало кампании ботов XsamXadoo
  • 2019-11-21 – Первый пик кампании sssp.php и traber
  • 2019-12-10 - Выпущено дополнительное исправление, препятствующее выполнению в контексте веб-сервера.
  • 2020-01-04 - Второй пик sssp.php traber campaign
  • 2020-01-06 – Был добавлен комментарий в коммит Hopefully prevent execution of this script in a webserver context. · sebastianbergmann/phpunit@33585d9.
  • 2020-01-07 - PrestaShop
  • 2020-01-08 - Mathieu Ferment (@mathieuKs) об обнаружении новой уязвимости в PHPUnit.
  • 2020-01-08 - Файл удален из репозитория.
Выводы:

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

Обновление считается надоедливым, со своими бесконечными разработками, так как новые патчи постоянно публикуются, поэтому многие фреймворки и сторонние модули не используют последний обновленный код.

Хакеры это знают, и именно поэтому они до сих пор успешно проводят атки со старыми уязвимостями.

В дополнение к используемой старой уязвимости PHPUnit, есть предположения, что новая уязвимость в PHPUnit еще не опубликована. Если это так, то, возможно, затронуты все версии PHPUnit, содержащие eval-stdin.php.

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

Вы уязвимы?
  • Проверьте, существует ли PHPUnit на вашем веб-сервере.
  • Если да, и ваша версия PHPUnit до 7.5.19 и 8.5.1, то возможно, что вы уязвимы при определенных конфигурациях сервера.
  • Рекомендуется удалить его (хотя в некоторых наблюдаемых случаях удаление PHPUnit приводит к неожиданному поведению веб-сервера), но можно также заблокировать удаленный доступ к каталогу /vendor, который является корневым путем фреймворка PHPUtil.
Вы заражены?
  • Проверьте новые файлы по пути PHPUnit
  • Проверьте основные файлы, которые были изменены в последнее время.
Будьте в безопасности и сохранности,
Всего доброго.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!