
Sliver HTTP(S) C2 PNG bomb DoS exploit — GHSA-663m-7x7m-g4fw (CVE-2026-77622)
Exploit de denegación de servicio para el listener HTTP(S) de Sliver C2. Fuerza bruta el nonce de codificación PNG por sesión y entrega una bomba de descompresión que agota la memoria del servidor.
Publicado como GHSA-663m-7x7m-g4fw.
El canal C2 HTTP(S) de Sliver envuelve los mensajes dentro de imágenes PNG. A cada sesión se le asigna un nonce aleatorio en el rango [1, 65537), y el servidor solo decodifica datos PNG de solicitudes cuyo parámetro de consulta ?n= coincida con el nonce de la sesión. Esto es un mecanismo de enrutamiento, no una verificación de autenticación: el espacio de claves es de 16 bits.
El servidor decodifica el PNG con image.Decode() de Go, que asigna ancho × alto × bytes_por_pixel en memoria. Un archivo PNG con dimensiones declaradas de 32767×32767 RGBA se comprime a aproximadamente 3 KB en la red, pero se descomprime a más de 4 GB en memoria. El servidor no impone ningún límite en las dimensiones decodificadas.
El exploit funciona en tres fases:
Versiones de Sliver C2 anteriores a la corrección referenciada en GHSA-663m-7x7m-g4fw. Cualquier servidor Sliver que ejecute un listener HTTP o HTTPS está expuesto.
go build -o pngboomer
Sin dependencias externas. Solo biblioteca estándar.
./pngboomer -url http://target:8080/ [opciones]
| Flag | Predeterminado | Descripción |
|---|---|---|
-url | http://127.0.0.1:8080/ | URL base C2 HTTP de Sliver |
-workers | 8 | Concurrencia de escaneo |
-probe-w | 2000 | Ancho del PNG de sonda |
-probe-h | 2000 | Alto del PNG de sonda |
-probe-color | 2 | Tipo de color de sonda (2=RGB, 6=RGBA) |
-kill-w | 32767 | Ancho del PNG de kill |
-kill-h | 32767 | Alto del PNG de kill |
-kill-color | 6 | Tipo de color de kill (2=RGB, 6=RGBA) |
-threshold-ms | 50 | Umbral mínimo de tiempo de respuesta para la detección de nonce |
-outlier-mult | 15.0 | Umbral adaptativo = p99 base × este valor |
-calibrate | 16 | Número de muestras de calibración |
-verify | 3 | Recuento de re-sondas por nonce candidato |
-max-nonce | 65537 | Límite superior del rango de nonces (módulo de Sliver) |
-probe-timeout | 5s | Tiempo de espera HTTP por sonda |
-kill-timeout | 180s | Tiempo de espera HTTP de la solicitud de kill |
-target-cap-mb | 10240 | Límite de memoria declarado del objetivo (verificación de seguridad) |
-nonce | 0 | Omitir escaneo, usar este nonce directamente |
-scan-only | false | Encontrar el nonce e imprimirlo sin enviar el kill |
-no-confirm | false | Omitir el sondeo TCP para la muerte del objetivo después del kill |
Escaneo y kill predeterminados contra un objetivo Docker local:
./pngboomer -url http://127.0.0.1:8080/ -target-cap-mb 10240
Solo escaneo (encontrar el nonce sin matar):
./pngboomer -url https://c2.target.com/ -scan-only
Omitir el escaneo cuando ya conoces el nonce:
./pngboomer -url http://target:8080/ -nonce 41337
La bomba de kill provoca una decodificación PNG de varios GB en el objetivo. Al realizar pruebas, ejecuta el servidor Sliver dentro de un contenedor Docker con --memory=<N>g y pasa -target-cap-mb N para que la herramienta rechace combinaciones peligrosas de worker/sonda que excederían la memoria del objetivo.
El PNG de sonda es lo suficientemente grande como para que su decodificación tarde notablemente más que el rechazo de ruta rápida del servidor ante un nonce incorrecto. El escaneo baraja el rango de nonces y lo distribuye entre goroutines de trabajo. Cada worker envía el PNG de sonda con un nonce candidato y mide el tiempo de respuesta.
Cuando una respuesta supera el umbral adaptativo (el mayor entre -threshold-ms y p99_base × outlier-mult), el candidato se re-sondea -verify veces. Si la mayoría de las re-sondas también superan el umbral, el nonce se confirma. Si no, el candidato se incluye en la lista negra y el escaneo continúa. Se toleran hasta 8 "parpadeos" de falsos positivos antes de que el escaneo se rinda.
Reportado a Bishop Fox a través del proceso de asesoría privada de GitHub. CalebKingan escribió el parche.
-no-color |
| false |
| Deshabilitar la salida de color ANSI |
-silent | false | Solo imprimir el nonce descubierto en stdout |