Si vous utilisez iTerm2, même `cat readme.txt` n’est pas sûr
(blog.calif.io)- L’intégration SSH utilise des escape sequences du terminal pour communiquer avec le shell distant, et à cause de cette architecture, une sortie terminal ordinaire peut elle aussi être interprétée comme le protocole conductor
- Le problème central est un échec de confiance : non seulement le véritable conductor distant, mais aussi des fichiers malveillants, bannières, MOTD ou réponses serveur peuvent se faire passer pour conductor via de faux
DCS 2000petOSC 135 - Le simple fait d’exécuter
cat readme.txtpeut suffire : si un faux transcript conductor est rendu, iTerm2 enchaîne lui-même le fluxgetshell·pythonversion·run(...), et la sortie d’attaque n’a plus qu’à imiter les réponses - L’exploit tire parti d’une confusion autour du PTY : une commande base64 écrite dans le PTY tombe en entrée texte clair du shell local lorsqu’il n’y a pas de véritable SSH conductor, et peut être exécutée quand le dernier chunk est interprété comme le chemin
ace/c+aliFIo - Le correctif a été intégré dans le commit du 31 mars
a9e745993c2e2cbb30b884a16617cd5495899f86, mais au moment de la publication il n’était pas encore inclus dans une stable release, créant une fenêtre d’exposition avant la diffusion du patch
Contexte de l’intégration SSH d’iTerm2
- L’iTerm2 SSH integration est une fonctionnalité conçue pour mieux comprendre les sessions distantes, avec un fonctionnement basé sur l’envoi d’un petit script helper appelé conductor sur le shell distant
- démarrage de l’intégration SSH via
it2ssh - transmission de conductor, script distant de bootstrap, via la session SSH existante
- ce script distant joue ensuite le rôle de pair du protocole iTerm2
- démarrage de l’intégration SSH via
- iTerm2 et conductor distant ne communiquent pas comme un service réseau classique, mais en s’échangeant des escape sequences sur les E/S du terminal
- détection du shell de connexion
- vérification de la présence de Python
- changement de répertoire
- upload de fichiers
- exécution de commandes
Fonctionnement du PTY
- Les émulateurs de terminal modernes sont des versions logicielles des anciens terminaux matériels, chargés de l’affichage, de l’entrée clavier et de l’interprétation des séquences de contrôle du terminal
- Les shells et programmes en ligne de commande s’attendent toujours à un périphérique ressemblant à un vrai terminal, d’où l’usage d’un PTY fourni par l’OS
- le PTY est un pseudoterminal placé entre l’émulateur de terminal et le processus au premier plan
- Dans une session SSH classique, iTerm2 écrit des octets dans le PTY, puis le processus au premier plan,
ssh, les transmet à la machine distante, où conductor les lit sur stdin - Quand iTerm2 envoie une commande au conductor distant, localement cela revient donc à écrire des octets dans le PTY
Protocole conductor
- Le protocole de transport de l’intégration SSH repose sur des escape sequences du terminal
- Deux éléments sont centraux
DCS 2000psert à hooker le SSH conductorOSC 135sert aux messages conductor pré-encapsulés
- Au niveau du code source,
DCS 2000pamène iTerm2 à créer un conductor parser, qui traite ensuite les messagesOSC 135begin <id>- lignes de sortie de commande
end <id> <status> runhook
- Un conductor distant légitime peut donc communiquer avec iTerm2 uniquement par la sortie terminal
Vulnérabilité principale
- La vulnérabilité est fondamentalement un échec de confiance : iTerm2 accepte comme protocole SSH conductor des sorties terminal qui ne proviennent pas d’une véritable session conductor de confiance
- En conséquence, une sortie terminal non fiable peut se faire passer pour un conductor distant
- fichier malveillant
- réponse serveur
- bannière
- MOTD
- Une entrée d’attaque peut afficher un faux hook
DCS 2000pet de fausses réponsesOSC 135, et iTerm2 se comporte alors comme si un véritable échange d’intégration SSH était en cours
Fonctionnement de l’exploit
- Le fichier d’exploit contient un faux transcript conductor
- Quand l’utilisateur exécute
cat readme.txt, iTerm2 rend le fichier, mais celui-ci ne contient pas un simple texte : il inclut aussi- une fausse ligne
DCS 2000psignalant une fausse session conductor - de faux messages
OSC 135répondant aux requêtes d’iTerm2
- une fausse ligne
- Une fois le hook accepté, iTerm2 lance le workflow normal de conductor : dans le code amont,
Conductor.start()envoie immédiatementgetshell(), puis, en cas de succès,pythonversion() - L’attaque n’a pas besoin d’injecter ces requêtes : c’est iTerm2 qui les émet de lui-même, et la sortie malveillante n’a qu’à imiter les réponses
Déroulement de la machine à états
- Les faux messages
OSC 135sont minimaux, mais ordonnés avec précision- début du corps de commande pour
getshell - renvoi d’une ligne ressemblant à une sortie de détection du shell
- fin réussie de cette commande
- début du corps de commande pour
pythonversion - fin en échec de cette commande
unhook
- début du corps de commande pour
- Ce simple enchaînement suffit pour faire entrer iTerm2 dans son chemin de repli normal, puis lui faire considérer que le workflow d’intégration SSH a été suffisamment mené à bien pour passer à l’étape suivante
- L’étape suivante consiste à construire puis envoyer la commande
run(...)
Rôle de sshargs
- Le faux hook
DCS 2000pcontient plusieurs champs, dontsshargs, contrôlé par l’attaquant - Cette valeur est ensuite utilisée par iTerm2 comme matière première de commande lors de la construction de sa requête
run ...pour conductor - L’exploit choisit
sshargsde façon à ce qu’au moment où iTerm2 encode en base64 les données suivantesrun <padding><magic-bytes>
- le dernier chunk de 128 octets devienne
ace/c+aliFIo - Cette chaîne n’est pas arbitraire : elle est choisie pour satisfaire simultanément deux conditions
- être une sortie valide du chemin d’encodage de conductor
- être un nom de chemin relatif valide
La confusion PTY qui rend l’exploit possible
- Dans une session normale d’intégration SSH, iTerm2 écrit dans le PTY des commandes conductor encodées en base64, puis
sshles transmet au conductor distant - Dans le scénario d’exploit, iTerm2 écrit de la même manière les commandes dans le PTY, sauf qu’en l’absence de véritable SSH conductor, le shell local les reçoit comme une entrée en texte clair
- Dans la session enregistrée, on observe
getshellsous forme base64pythonversionsous forme base64- puis une longue payload
run ...encodée en base64 - dont le dernier chunk est
ace/c+aliFIo
- Les chunks précédents échouent comme commandes sans signification, mais le dernier s’exécute si ce chemin existe localement et est exécutable
Procédure de reproduction
- Le PoC original basé sur des fichiers peut être reproduit avec
genpoc.pypython3 genpoc.pyunzip poc.zipcat readme.txt
- Cette procédure génère deux fichiers
- un script helper exécutable nommé
ace/c+aliFIo - un
readme.txtcontenant les séquences malveillantesDCS 2000petOSC 135
- un script helper exécutable nommé
- Le premier fichier pousse iTerm2 à communiquer avec le faux conductor, et le second fournit au shell la cible réellement exécutée à l’arrivée du dernier chunk
- Pour que l’exploit réussisse,
cat readme.txtdoit être exécuté dans le répertoire où se trouveace/c+aliFIo, afin que le dernier chunk contrôlé par l’attaquant soit interprété comme un chemin réellement exécutable
Divulgation et calendrier du patch
- signalement du bug à iTerm2 le 30 mars
- correctif finalisé le 31 mars dans le commit
a9e745993c2e2cbb30b884a16617cd5495899f86 - au moment de la rédaction, le correctif n’était toujours pas inclus dans une stable release
- après l’intégration du commit de correctif, une tentative de reconstruction complète de l’exploit à partir du seul patch a été menée
- les prompts utilisés figurent dans
prompts.md - le résultat est
genpoc2.py - son fonctionnement est très proche de
genpoc.py
- les prompts utilisés figurent dans
Question sur le moment de la divulgation
- La divulgation est intervenue avant que le correctif n’atteigne une stable release, ouvrant une période où la plupart des utilisateurs ne pouvaient pas réellement être protégés alors même que la vulnérabilité devenait publique
- Une telle tension sur le calendrier de publication nécessite une justification claire
- Deux semaines, c’est à la fois trop court pour espérer une diffusion significative du correctif, et trop court aussi pour justifier qu’une divulgation anticipée était nécessaire pour forcer la réponse
- En pratique, cela a créé une fenêtre de divulgation où la faille était largement connue alors que le correctif n’était pas encore accessible aux utilisateurs qui en avaient réellement besoin
- Une meilleure option aurait été d’attendre que la version corrigée arrive réellement chez les utilisateurs, ou d’expliquer clairement pourquoi une exposition anticipée était nécessaire, mais aucune de ces deux conditions n’a été remplie
1 commentaires
Commentaires sur Hacker News
Je me suis demandé pourquoi cela avait été rendu public maintenant alors qu’aucun correctif n’était encore sorti sur la version stable. Cela ne faisait que 18 jours que c’était signalé en amont, et l’article de blog était bien plus détaillé que le commit public, au point de sembler augmenter la possibilité d’une exploitation réelle. L’auteur a montré qu’il avait pu produire un exploit à partir du seul commit amont avec un LLM, mais j’estime quand même que ce billet a davantage accru la visibilité de la faille
C’est un beau travail, mais ce n’était pas si surprenant. C’est un problème récurrent dans les applications de terminal riches en fonctionnalités, et plusieurs vulnérabilités similaires ont été publiées au cours des 15 dernières années. Des outils comme less ou vim n’y ont pas échappé, et une bonne partie de ces problèmes relèvent davantage de bugs logiques que de sécurité mémoire, donc les réécrire en Rust ne les résoudrait pas automatiquement. D’un côté, on veut que les outils au niveau de l’OS restent simples et prévisibles, mais de l’autre, on veut de jolies couleurs, des animations et une personnalisation sans fin. Et maintenant, on y ajoute même des agents IA, si bien qu’un fichier texte malveillant peut se contenter de contenir des phrases comme "ignore les instructions précédentes"
Cela m’a rappelé l’époque du PDP-10. Un collègue avait découvert qu’en maintenant la touche retour arrière, le gestionnaire de terminal effaçait aussi des caractères avant le début du tampon, puis qu’en utilisant le caractère d’échappement qui effaçait toute une ligne, on pouvait carrément faire tomber le système d’exploitation
Il y avait déjà eu quasiment le même problème de sécurité iTerm2 il y a 6 ans
Je suis l’auteur d’iTerm2. Ce problème peut servir de maillon dans une chaîne d’exploitation, mais dire comme dans le titre que c’est en soi un énorme danger me semble exagéré. Je suis actuellement en voyage en famille, et je publierai une version corrigée à mon retour
Je n’ai pas été surpris de voir un bug subtil apparaître dans un système complexe qui utilise des scripts de bootstrap, des agents conductor distants, des séquences d’échappement, etc. Quand on assemble des composants d’une manière qui n’était pas prévue à l’origine, ce genre de problème arrive facilement. Je comprends le problème comme suit : si une sortie non fiable affichée à l’écran, par exemple un fichier texte ou une bannière serveur, contient des codes spéciaux, la structure les traite sans vérifier leur provenance
J’ai eu l’impression d’avoir déjà vu cette histoire. L’intégration SSH d’iTerm2 avait déjà été à l’origine d’un CVE, et cela m’a rappelé CVE-2025-22275. Il y a eu d’autres cas auparavant, et l’ancien problème mentionné dans ce fil concernait l’intégration tmux. Peut-être vaudrait-il mieux intégrer ce genre de fonctionnalités d’intégration de façon un peu moins agressive
Le titre est trop sensationnaliste. Le problème, ce n’est pas cat, mais l’intégration SSH d’iTerm, et cette architecture avec un canal de contrôle non séparé du flux de données semble risquée. Si on n’utilise pas cette fonctionnalité et qu’on se contente de SSH classique, cela semble globalement aller
Les anciens émulateurs de terminal permettaient même le rebinding clavier via des codes d’échappement. C’est pour cela qu’il était quasiment évident de ne pas faire
catsur des fichiers non fiables, mais de les ouvrir avec des outils commelessLa formulation de l’article est imprécise. Le deuxième paragraphe se lit comme « utiliser iTerm2 n’est pas sûr », alors qu’en réalité, le problème semble surtout concerner l’usage de la fonctionnalité optionnelle Shell Integration. Si cette fonction est désactivée par défaut, la portée de l’impact est limitée, si je comprends bien. Je veux bien être corrigé si je me trompe