Автор оригинала: David Wong.
Автор: лорена ‘@ знать Чжуанъю 404 Лабораторное время: 25 октября 2019 г. Оригинальная ссылка: https://paper.seebug.org/1063/
Когда Эндрю Данау, исследователь внешней безопасности, решил проблему CTF, он обнаружил, что при отправке символа% 0A на URL-адрес целевого сервера служба вернула исключение, подозреваемое в уязвимости.
23 октября 2019 года GitHub раскрыл подробности, связанные с уязвимостью и exp. Если nginx настроен неправильно, PHP FPM будет выполнять произвольный код удаленно.
Давайте взглянем на подробный анализ уязвимости. В части анализа уязвимостей статьи поблагодарите партнера по команде @ hcaael Чен за знание лаборатории Чжуанъюй 404
Чтобы легче воспроизвести уязвимость, мы используем vulhub для создания среды уязвимостей.
https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043
git pull и докер-составьте-d
Посетите http://{your_ip}:8080/
Загрузите exp, размещенный на GitHub (требуется среда go).
go get github.com/neex/phuip-fpizdam
Затем компилировать
go install github.com/neex/phuip-fpizdam
Использование exp для атаки на демонстрационный веб-сайт
phuip-fpizdam http://{your_ip}:8080/Успешная атака
Прежде чем анализировать принцип уязвимости, мы можем непосредственно проследить за фиксацией ремонта здесь
-https://github.com/php/php-src/commit/ab061f95ca966731b1c84cf5b7b20155c0a1c06a#diff-624bdd47ab6847d777e15327976a9227
Из фиксации мы ясно видим, что причиной уязвимости должна быть path_info Это вызвано контролируемым адресом, и это упоминается в информации об уязвимости, раскрытой обнаружителем уязвимостей
The regexp in `fastcgi_split_path_info` directive can be broken using the newline character (in encoded form, %0a). Broken regexp leads to empty PATH_INFO, which triggers the bug.
То есть, когда path_info При усечении на% 0A, путь_инфо Он будет оставлен пустым, так что мне не составит труда найти проблему в коде.
среди env_path_info Это переменная. путь_инфо Адрес, путь_инфо Для 0 плиен Для 0.
slen Переменная от длины URL – адреса после запроса
int ptlen = strlen(pt);
int slen = len - ptlen;среди
int len = script_path_translated_len; Len is the URL path length When the request URL is http://127.0.0.1/index.php/123% 0atest.php Script ﹣ path ﹣ translated comes from the configuration of nginx, which is / var / www / HTML / index. PHP / 123 \ ntest. PHP Ptlen is the content length before the first slash of the URL path When the request URL is http://127.0.0.1/index.php/123% 0atest.php PT is / var / www / HTML / index.php
Разница между этими двумя переменными заключается в длине последующего пути. Так как путь является управляемым, то путь_инфо Управляемый.
Потому что path_info Управляемый. В строке 1222 мы можем установить значение указанного адреса равным нулю. Согласно описанию обнаружителя уязвимостей, установив значение указанного адреса равным нулю, мы можем управлять _fcgi_data_seg Структурный символ* pos Ноль.
среди имя_скрипта Также из запрошенной конфигурации
И почему мы делаем _fcgi_data_seg Структурный символ* pos Ноль повлияет FCGI_PUTENV Как насчет результатов?
Давайте внимательно рассмотрим здесь FCGI_PUTENV Определение.
char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val);
Функция ввода каблука fcgi_quick_putenv
Функция ввода каблука || fcgi_quick_putenv
Функция напрямую работает с Env запроса, который был предопределен ранее.
Функция напрямую работает с Env запроса, который был предопределен ранее.
Продолжайте следить за функцией инициализации fcgi_hash_init .
Продолжайте следить за функцией инициализации || fcgi_hash_init || .
Другими словами запрос->env Это то, о чем я упоминал ранее fcgi_data_seg Структура, а здесь запрос->env – это глобальная переменная, которую nginx сохраняет при взаимодействии с fastcgi.
Некоторые глобальные переменные будут определены в конфигурации nginx
Где переменные хранятся в соответствующем месте в куче Вернемся к процессу использования, здесь мы контролируем путь_инфо точка запрос->env Чтобы сделать запрос->env->pos Ноль.
Вернитесь к функции назначения fcgi_hash_set функция
А затем вы заходите в fcgi_hash_strdup
Здесь h->данные-》pos Самый низкий бит установлен в 0, и STR управляется, что означает, что мы можем записывать данные спереди.
Вопрос в том, как мы можем записывать данные туда, куда нам нужно? Как записать файлы в указанную нами конфигурацию?
Давайте возьмем в качестве примера пакет использования, отправленный exp
GET /index.php/PHP_VALUE%0Asession.auto_start=1;;;?QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ HTTP/1.1 Host: ubuntu.local:8080 User-Agent: Mozilla/5.0 D-Gisos: 8=====================================D Ebut: mamku tvoyu
В пакете данных последние две части заголовка предназначены для завершения этой части функции D-Gisos Ответственный за перемещение, запишите данные в указанное место.
и Дебют Будет переведен в HTTP_BUT это fastcgi_param Одна из глобальных переменных в , и тогда нам нужно понять fastcgi Метод получения данных из глобальных переменных в.
Метод получения данных из глобальных переменных в.
Вы можете видеть, что когда fastcgi хочет получить глобальные переменные, он будет считывать символы длины указанного местоположения для сравнения, а затем считывать строку в качестве значения
другими словами, До тех пор, пока местоположение является разумным, значение VaR одинаковое и длина одинаковая, fastcgi будет считывать соответствующие данные 。
и HTTP_BUT и ЗНАЧЕНИЕ PHP_ Точно такой же длины, мы можем подтвердить это по изменению данных в куче.
Перед перезаписью соответствующие данные адреса
Затем выполните fcgi_quick_putenv
Соответствующие данные этого адреса становятся
Мы успешно написали ЗНАЧЕНИЕ PHP_ И контролировать его содержимое, что означает, что мы можем управлять любой глобальной переменной PHP.
Когда мы можем управлять любой глобальной переменной PHP, существует множество методов атаки. Здесь мы используем методы атаки, используемые в exp, в качестве примера.
Автор exp устанавливает каталог автоматического включения в /tmp , а затем установите адрес журнала в /tmp/a И запишите полезную нагрузку в файл журнала через auto_prepend_file Автоматическое включение /tmp/Файл создает файл бэкдора.
После углубленного изучения уязвимости мы рекомендуем два решения для ее устранения.
- Временный ремонт:
Измените соответствующую конфигурацию nginx и добавьте ее в конфигурацию, связанную с PHP
try_files $uri =404
В этом случае будет nginx, чтобы проверить, существует ли файл. Если файл не существует, запрос не будет передан в PHP FPM.
Официальный ремонт:
- Обновите PHP 7.1. X до 7.1.33 https://github.com/php/php-src/релизы/тег/php-7.1.33
- Обновите PHP 7.2. X до 7.2.24 https://github.com/php/php-src/релизы/тег/php-7.2.24
- Обновите PHP 7.3. X – 7.3.11 https://github.com/php/php-src/releases/tag/php-7.3.11
В сочетании с условиями использования, упомянутыми в exp GitHub, мы можем максимально обобщить условия использования и масштабы воздействия уязвимости.
1. Nginx + php_ fpm и настроить местоположение ~ [^/]\.php(/|$) Запрос пересылается в PHP FPM. 2. Конфигурация Nginx fastcgi_split_path_info И взять ^ Начните с $ , только при этом условии суждение о регулярных выражениях может быть прервано разрывами строк PS: разрешено index.php/321 -> index.php
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
3、 fastcgi_param в PATH_INFO Будет определен для передачи fastcgi_param PATH_INFO $fastcgi_path_info; Конечно, эта переменная будет fastcgi_params Определение по умолчанию. 4. Нет определения проверки файлов на уровне nginx, например try_files Если проверка файлов выполняется на уровне nginx, запрос не будет перенаправлен в PHP FMP.
Эта уязвимость наносит ограниченный вред реальному миру в процессе реальных исследований. Основная причина заключается в том, что большинство конфигураций nginx выполняют проверку файлов, а конфигурация nginx по умолчанию не содержит этой проблемы.
Однако по этой причине эта проблема возникает во многих онлайн-кодах примеров или в некоторых средах, которые не учитывают эту проблему, таких как пример конфигурации в официальном документе nginx и среда по умолчанию nextcloud. Эта уязвимость также представляет реальную угрозу безопасности многих серверов.
В этом случае уязвимость также подпадает под действие закона о темном лесу. Как только конфигурация с проблемами распространяется, это может привести к задействованию большого количества служб. Обеспечение своевременного обновления всегда является лучшим способом защиты: >
- Проблема уязвимости
- Среда, предоставляемая средством поиска уязвимостей
- Использование уязвимости
- Фрагмент кода, вызывающий уязвимость
- Фиксация исправления ошибки
- вулхуб
- [https://www.nginx.com/resourc…](https://www.nginx.com/resourc…
- Коллекция уязвимостей Seeburg
Если вам нужно перепечатать, пожалуйста, укажите источник
Оригинал: “https://developpaper.com/analysis-of-php-fpm-remote-code-execution-vulnerability-cve-2019-11043/”