Отчёт о компрометации git-репозитория и базы пользователей проекта PHP

Опубликованы первые результаты разбора инцидента, связанного с выявлением в Git-репозитории проекта PHP двух вредоносных коммитов с бэкдором, активируемым при передаче запроса со специально оформленным заголовком User Agent. В ходе изучения следов деятельности атакующих был сделан вывод, что непосредственно сервер git.php.net, на котором был размещён git-репозиторий не был взломан, но была скомпрометирована база данных с учётными записями разработчиков проекта.

Не исключается, что злоумышленники смогли загрузить базу пользователей, хранившуюся в СУБД на сервере master.php.net. Содержимое master.php.net уже перенесено на новый сервер main.php.net, установленный с нуля. Все пароли разработчиков, использовавшиеся для доступа к инфраструктуре php.net, были сброшены и инициирован процесс их смены через специальную форму восстановления пароля. Репозитории git.php.net и svn.php.net остаются доступны в режиме только для чтения (разработка перенесена на GitHub).

После обнаружения первого вредоносного коммита, совершённого через учётную запись Расмуса Лердорфа, основателя PHP, было сделано предположение, что взломан его аккаунт и Никита Попов, один из ключевых разработчиков PHP, откатил изменения и блокировал права коммита для проблемной учётной записи. Через какое-то время пришло осознание, что блокировка не имела смысла, так как без верификации коммитов по цифровой подписи, любой участник с доступом к репозиторию php-src мог внести изменение, подставив фиктивное имя автора.

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

Оперативно был отключён сервер git.php.net, а первичный репозиторий переведён на GitHub. Впопыхах было упущено из виду то, что для доступа к репозиторию кроме SSH с использованием gitolite имелся ещё один вход, позволяющий отправлять коммиты через HTTPS. В данном случае для взаимодействия с Git использовался бэкенд git-http-backend, а аутентификация выполнялась при помощи HTTP-сервера Apache2, который проверял полномочия через обращение к базе данных, размещённой в СУБД на сервере master.php.net. Допускался вход не только по ключам, но и по обычному паролю. Разбор логов http-сервера, подтвердил, что вредоносные изменения были добавлены через HTTPS.

При изучении логов было выявлено, что атакующие подключились не с первого раза, а вначале пытались подобрать имя учётной записи, но после определения вошли с первой попытки, т.е. они заранее знали пароли Расмуса и Никиты, но не знали их логины. Если атакующие смогли получить доступ к СУБД, то непонятно, почему они сразу не использовали указанный там корректный логин. Данная несостыковка пока не получила достоверного объяснения. Взлом master.php.net рассматривается как наиболее вероятный сценарий, так как на данном сервере был использован очень старый код и устаревшая ОС, которые давно не обновлялись и имели неисправленные уязвимости.

Из предпринятых действий отмечается переустановка окружения master.php.net и перевод скриптов на новую версию PHP 8. Код для работы с СУБД переделан для использования параметризованных запросов, усложняющих подстановку SQL-кода. Для хранения хэшей паролей в БД задействован алгоритм bcrypt (ранее пароли хранились с использованием ненадёжного хэша MD5). Существующие пароли сброшены и предложено установить новый пароль через форму восстановления пароля. Так как доступ к репозиториям git.php.net и svn.php.net по HTTPS был привязан к хэшам MD5, решено оставить git.php.net и svn.php.net в режиме только для чтения, а также перенести все остающиеся на них репозитории расширений PECL на GitHub, по аналогии с основным репозиторием PHP.

Release. Ссылка here.