
PoC en Python y laboratorio Docker para CVE-2026-61500: recupera el estado del PRNG de Rejetto HFS V8 para falsificar una cookie de sesión de administrador y lograr RCE mediante server_code.
CVE-2026-61500 es una vulnerabilidad de falsificación de sesión no autenticada en Rejetto
HFS 3.0.0 hasta 3.2.0. HFS generaba su clave de firma de cookies de sesión de Koa con
JavaScript Math.random() y exponía salidas del mismo PRNG de V8 en el handshake de inicio de sesión SRP no autenticado. Un atacante puede reconstruir el estado del PRNG,
recuperar la clave de firma, falsificar una sesión de administrador y usar la característica documentada de configuración server_code para ejecutar JavaScript del lado del servidor.
Este repositorio contiene una prueba de concepto en Python y una comparación desechable en Docker usando las imágenes oficiales de HFS 3.2.0 y 3.2.1. La compilación de publicación está intencionalmente restringida a objetivos HTTP en la interfaz de loopback local.
| Declaración | Estado |
|---|---|
| Recuperar el estado xorshift128+ de V8 a partir de respuestas de inicio de sesión no autenticadas | Confirmado |
| Recuperar la clave de firma de cookies activa de HFS | Confirmado |
| Falsificar una sesión aceptada como administrador de HFS | Confirmado |
Ejecutar un marcador server_code benigno en HFS 3.2.0 oficial | Confirmado |
| Recibir una reverse shell de root dentro de la red Compose aislada | Confirmado |
| Detenerse antes de la falsificación de sesión en HFS 3.2.1 oficial | Confirmado |
| Dirigirse a Internet o persistencia | No proporcionado ni reclamado |
loginSrp1 para la cuenta conocida admin.
Cada respuesta vulnerable coloca un loggingIn.sid numérico y su cookie de sesión firmada en las cabeceras Set-Cookie.randomId(30). El PoC
tiene en cuenta el redondeo de cadena más corta de V8 y verifica los candidatos contra un
HMAC hfs_http.sig observado, que también identifica el desplazamiento de inicio.username: admin, luego llamar a
get_config para probar que la cookie falsificada tiene acceso de administrador.set_config con un pequeño módulo server_code. La carga útil predeterminada
escribe un marcador benigno en /data; está disponible solo para
el laboratorio Docker en loopback.Esta es una cadena HTTP de caja negra: el PoC no lee archivos, memoria, variables de entorno ni estado de procesos del objetivo. El conocimiento del código fuente se usa para modelar el algoritmo vulnerable.
59472e534bf7e056d708382d02935c2eaf956927.La corrección reemplaza la clave de firma con 32 bytes de randomBytes() de Node.js y
reemplaza el identificador de inicio de sesión numérico expuesto con randomUUID(). Proporcionar un
valor explícito y fuerte de COOKIE_SIGN_KEYS mitiga la predicción de la clave de firma, pero
actualizar sigue siendo la remediación recomendada.
rejetto/hfs:v3.2.0, digest
sha256:d6765e93b68de222583be7788afad699695fd08aa2f56377337f5139779e0746.rejetto/hfs:v3.2.1, digest
sha256:61db4da1f494df254aa7f48889c676b424b413e45b7b92cf4276f4b8e632aaec.python:3.13-alpine, digest
sha256:1a63a53928ce53d2b0baf08092a703f4840ac5dfbd61fd48802dbf48e08c801e.Ambos servicios HFS se enlazan solo al loopback del host; el callback no publica ningún puerto.
El laboratorio crea un administrador sintético
porque loginSrp1 debe invocarse para un nombre de usuario existente; la
contraseña no es conocida ni usada por el exploit.
Los requisitos son Docker con Compose, Python 3.10 o superior y curl.
./verify.sh
El verificador elimina solo lab/runtime/vulnerable y lab/runtime/fixed,
inicia ambas imágenes fijadas por digest, ejecuta los controles positivos y negativos, y
detiene los contenedores de forma predeterminada. Use KEEP_LAB=1 ./verify.sh para dejar el laboratorio
en ejecución para inspección.
Con el laboratorio retenido, la invocación directa del marcador benigno es:
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--marker cve-2026-61500-rce-marker.txt
Para demostrar la ejecución de comandos dentro del contenedor de laboratorio propio:
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--command 'id > /data/cve-command-output.txt'
Cualquier nombre de host que no sea loopback, objetivo HTTPS o IP remota es rechazado por la validación
de argumentos. El exploit modifica server_code de HFS; use solo el laboratorio desechable
o un sistema para el cual tenga autorización explícita.
La demostración grabada va un paso más allá: demo.sh inicia el servicio callback
no expuesto en la red Compose y usa --command para conectar una reverse shell de Bash
a él. El callback envía solo id, uname -a, pwd y
exit, registra la transcripción bajo lab/runtime/ ignorado y cierra. Ningún
puerto de callback está enlazado al host.
La ejecución real del 2026-09-26 recuperó un estado del PRNG y su clave de firma, recibió
HTTP 200 para un get_config administrativo falsificado, instaló la carga útil del marcador,
y observó CVE_2026_61500_RCE_CONFIRMED en el contenedor vulnerable. Un
control separado --command 'id > /data/cve-command-output.txt' produjo
uid=0(root) gid=0(root) groups=0(root) dentro de ese contenedor oficial. La
reverse shell grabada solo con Docker devolvió independientemente la misma identidad de root
y el directorio de trabajo /data. Contra
3.2.1, la primera respuesta de inicio de sesión contenía un UUID opaco y el PoC salió con
estado 3 antes de intentar la falsificación de sesión. Consulte
docs/example-output.txt y
docs/e2e-results.json.
El 2026-09-26, se ejecutaron búsquedas exactas de CVE y exploit/PoC contra SearchSploit (índice local de Exploit-DB), resultados web indexados por GitHub, Packet Storm, Exploit-DB, y la web general. No se identificó ningún exploit público funcional en ese momento; los resultados encontraron solo metadatos de CVE/aviso y páginas de seguimiento de exploits. Este es un resultado con fecha y de mejor esfuerzo, no una afirmación de que no pueda existir otro exploit en otro lugar o aparecer más tarde.
<[email protected]>
(Twitter: @aramosf).Solo para investigación de seguridad autorizada, validación defensiva y educación. Usted es responsable de obtener permiso y cumplir con la ley aplicable.
--command