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
servu-cve-2026-28318-poc — SolarWinds Serv-U CVE-2026-28318: caída sin autenticación por Content-Encoding: deflate. Análisis de causa raíz (free no válido de un puntero interior -> corrupción del heap) + PoC solo de DoS. Corregido en 15.5.4 Hotfix 1. | Kitploit
Herramientas/GitHubGitHub/eaea0001/servu-cve-2026-28318-poc
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónPruebas de PenetraciónAnálisis de Binarios
GitHubeaea0001/servu-cve-2026-28318-poc

servu-cve-2026-28318-poc

SolarWinds Serv-U CVE-2026-28318: caída sin autenticación por Content-Encoding: deflate. Análisis de causa raíz (free no válido de un puntero interior -> corrupción del heap) + PoC solo de DoS. Corregido en 15.5.4 Hotfix 1.

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
Ver Repositorio
1hace 2 mesesAún no revisado

CVE-2026-28318 — SolarWinds Serv-U "Content-Encoding: deflate" caída pre-autenticación

Análisis de causa raíz + prueba de concepto de DoS. El aviso público clasifica esto como una denegación de servicio / consumo no controlado de recursos no autenticada. El análisis binario muestra que el defecto subyacente es de seguridad de memoria: una free() inválida de un puntero interior en la ruta de decodificación HTTP deflate, que corrompe el heap del proceso (STATUS_HEAP_CORRUPTION, 0xC0000374). No es una bomba de descompresión, y la caída es independiente del tamaño descomprimido.


⚠️ Descargo de responsabilidad / alcance

  • Esto es investigación de seguridad defensiva para una vulnerabilidad ya parcheada y divulgada públicamente (corrección publicada 2026-06-04 en Serv-U 15.5.4 Hotfix 1; incluida en CISA KEV).
  • El PoC aquí solo hace caer una instancia de Serv-U que usted posee o está explícitamente autorizado a probar. Es solo DoS — no se incluye ni se demuestra ejecución remota de código (consulte Severidad).
  • Úselo para validar el estado del parche y la detección en sus propios sistemas. No lo dirija a sistemas que no controle. Usted es responsable de cumplir con la ley aplicable.

Afectado / Corregido

Afecta solo al listener HTTP/HTTPS (la ruta web/de gestión). FTP/FTPS/SFTP no están en esta ruta de código.


TL;DR

Cualquier solicitud HTTP que lleve Content-Encoding: deflate con un cuerpo deflate válido hace caer el servicio. El manejador descomprime el cuerpo y luego libera el puntero al cuerpo comprimido e intercambia el búfer descomprimido — pero ese puntero es un puntero interior dentro del búfer de recepción HTTP (apunta al cuerpo, inmediatamente después del \r\n\r\n), no una base de asignación del heap. Llamar a free() sobre un puntero no base y desalineado corrompe el heap y el proceso muere.

Debido a que el error está en cómo se libera el puntero del cuerpo — no en cuántos datos se producen — incluso un cuerpo comprimido de ~25 bytes (que se descomprime a unos pocos KB) lo hace caer de forma fiable. El uso de memoria no crece; no es una "bomba zip/deflate".


Causa raíz

La rutina de decodificación deflate reside en RhinoNET.dll (la biblioteca de red de Serv-U) y se alcanza desde la ruta de recepción HTTP (ProcessReceive) una vez que el analizador de cabeceras establece la bandera "deflate" al ver Content-Encoding: deflate.

Simplificada, la rutina se invoca como decode(this, &bodyPtr, &bodyLen) y hace:

root@kitploit:~
1. inflate bodyPtr[0..bodyLen]  -> grows an accumulator buffer `acc`   (stock zlib, bounded, correct)
2. free(*bodyPtr)                <-- *bodyPtr is an INTERIOR pointer into the receive buffer
3. *bodyPtr = acc                // replace compressed body with decompressed buffer
4. *bodyLen = total

El paso 2 es el error. *bodyPtr no es un bloque asignado de forma independiente: apunta al cuerpo de la solicitud dentro del único búfer de recepción HTTP, es decir, receive_buffer + header_length. Liberar un puntero interior (y desalineado a 16 bytes) hace que el asignador interprete una región influenciada por el atacante como una cabecera de chunk del heap → corrupción de metadatos del heap → 0xC0000374.

Lo que se descartó (para que no persiga lo incorrecto)

Ambas hipótesis "obvias" son incorrectas, verificado en tiempo de ejecución:

  • No es un desbordamiento de inflate/descompresión. El descompresor es el zlib1.dll!inflate estándar y respeta avail_out en cada llamada (observado en más de 100 chunks; cero escrituras fuera de límites).
  • No es un desbordamiento del acumulador. El búfer de salida en crecimiento se asigna como prev_total + produced + 1 en cada ronda y se escribe exactamente esa cantidad — ajustado, sin desbordamiento.

La corrupción es únicamente la free() inválida del paso 2.


Evidencia

Capturado en tiempo de ejecución (Frida) contra Serv-U 15.5.4.108 mientras se enviaba una solicitud Content-Encoding: deflate cuyo cuerpo se descomprime a "A" * 8192:

  • El puntero liberado es …ce — mod 16 == 14. Las bases de asignación del heap están alineadas a 16 bytes, por lo que esto no es una base de asignación; es un puntero interior.
  • Los 48 bytes antes del puntero liberado son la cola de la cabecera HTTP, terminando en \r\n\r\n:
    root@kitploit:~
    …tream\r\nContent-Length: 26\r\nConnection: close\r\n\r\n
    
  • Los bytes en el puntero liberado son un flujo deflate crudo (ed c1 01 0d 00 …).
  • Firma de la caída: módulo infractor ntdll.dll, excepción 0xC0000374 (STATUS_HEAP_CORRUPTION), con la llamada originándose desde la free en el manejador deflate de RhinoNET.dll. La última operación del heap antes de la caída es exactamente esta free(bodyPtr).
  • Independencia del tamaño: un cuerpo que se descomprime a solo ~4 KB (comprimido ≈ unas pocas decenas de bytes) cae de forma idéntica; la memoria del working set no crece.

Severidad

  • Confirmado: caída remota no autenticada fiable del servicio Serv-U (DoS). El servicio puede reiniciarse automáticamente, pero las solicitudes repetidas lo mantienen caído y pueden agotar la recuperación del servicio de Windows.
  • Más allá del DoS — no probado. La "cabecera de chunk" liberada se superpone con bytes de la cabecera HTTP controlados por el atacante, lo que en principio es una primitiva más fuerte que un DoS simple. Sin embargo, en Windows moderno (Segment Heap) la free inválida falla rápidamente (0xC0000374) en nuestras pruebas, y no logramos ejecución de código. Trate esto como DoS por corrupción del heap pre-autenticación con causa raíz de seguridad de memoria; no asuma RCE.

Reproducción

Requiere Python 3 (solo biblioteca estándar). Apúntelo a un listener HTTP de Serv-U que esté autorizado a probar. En Windows utiliza una llamada a Get-NetTCPConnection para leer el PID del listener y el registro de eventos de Aplicación para confirmar la caída por corrupción del heap.

root@kitploit:~
python poc_verify.py                       # default 127.0.0.1:80, tiny packet, 1 shot
python poc_verify.py --host <ip> --port 80
python poc_verify.py --big                 # body decompresses to 8192 bytes
python poc_verify.py --shots 3
python poc_verify.py --no-events           # skip event-log check (no privileges needed)

El PoC construye una solicitud mínima:

root@kitploit:~
POST / HTTP/1.1
Host: <target>
Content-Encoding: deflate
Content-Type: application/octet-stream
Content-Length: <n>
Connection: close

<raw-deflate body — even a few dozen bytes is enough>

Reporta PASS si el servicio se cayó (el PID del listener cambió / apareció el evento 0xC0000374) y FAIL si sobrevivió (ya parcheado, no afectado, o el cuerpo no se procesó como deflate).


Mitigación

  1. Aplique Serv-U 15.5.4 Hotfix 1 (o posterior).
  2. Medida provisional: delante de Serv-U, elimine o rechace el Content-Encoding entrante en el listener HTTP/HTTPS, por ejemplo en un proxy inverso:
    root@kitploit:~
    if ($http_content_encoding) { return 400; }
    
  3. Restrinja la exposición de red del puerto web/de gestión de Serv-U.

Metodología (cómo se analizó esto)

  • Estático: desensamblado PE parametrizado de RhinoNET.dll / Serv-U.exe (base de imagen 0x180000000) para mapear la ruta receive → header-parse → deflate-decode y localizar la free errónea.
  • Dinámico: instrumentación con Frida del servicio en vivo — enganchando el descompresor para demostrar que zlib respeta avail_out, rastreando cada alloc/free/memcpy de la llamada de decodificación a disco, y un manejador de excepciones del proceso para capturar la instrucción infractora y la pila de 0xC0000374 en el momento de la corrupción. La liberación del puntero interior se confirmó luego volcando los bytes alrededor del puntero liberado (cola de cabecera HTTP + cuerpo deflate crudo, desalineado a 16 bytes).

Los offsets referenciados en el análisis son específicos de la compilación 15.5.4.108 y diferirán entre compilaciones.


Referencias

  • SolarWinds — notas de la versión de Serv-U 15.5.4 Hotfix 1
  • NVD — CVE-2026-28318
  • Catálogo CISA KEV — CVE-2026-28318

Publicado como investigación defensiva después de la disponibilidad del parche del proveedor. El PoC es solo DoS y está destinado a pruebas autorizadas.

Descargar herramienta
ProductoSolarWinds Serv-U (FTP / MFT / File Server)
Vulnerable15.5.4 y anteriores en esa rama sin Hotfix 1 (análisis realizado en la compilación 15.5.4.108)
CorregidoServ-U 15.5.4 Hotfix 1 (publicado 2026-06-04)
VectorNo autenticado, red (puerto HTTP/HTTPS de gestión/web)
Clase públicaCWE-400 Consumo no controlado de recursos · DoS · CVSS 7.5 · CISA KEV
Clase realCWE-763 Liberación de puntero inválido / CWE-590 Liberación de memoria que no está en el heap → corrupción del heap