
Analyse éducative et PoC en mode test pour CVE-2026-92162, une traversée de chemin dans le paramètre arch de DeployAppstream de Flatpak permettant la création de répertoires racine.
Analyse pédagogique et preuve de concept en mode test pour une traversée de chemin dans le helper système de Flatpak (flatpak-system-helper). La méthode D-Bus DeployAppstream accepte une chaîne arch qui est placée dans un chemin de système de fichiers et créée en tant que root, sans aucune validation. Un utilisateur local actif peut fournir des composants ../ et provoquer la création par le service privilégié root de répertoires en dehors de l'arborescence appstream prévue.
Ce dépôt accompagne l'analyse technique complète et le post-mortem de recherche. Il existe à des fins pédagogiques, pour les défenseurs qui souhaitent comprendre le mécanisme, et pour les tests autorisés sur des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation écrite d'évaluation.
Ce contenu est publié après une divulgation coordonnée et après la mise à disposition d'une version corrigée de Flatpak. N'exécutez la preuve de concept que contre une machine de laboratoire que vous possédez ou que vous êtes explicitement autorisé à tester. Ne l'exécutez pas contre des systèmes que vous ne contrôlez pas. Il vous incombe de rester dans le cadre de la loi et dans le périmètre de toute autorisation dont vous disposez.
handle_deploy_appstream() dans le helper système valide l'argument origin mais pas l'argument arch. Pour un remote OCI, arch se propage dans flatpak_build_file puis g_mkdir_with_parents, qui s'exécute en tant que root et résout ../ de manière lexicale. L'action polkit pour la méthode est org.freedesktop.Flatpak.appstream-update, qui est allow_active=yes, donc une session locale active atteint le code sans demande de mot de passe. Sur un système qui possède déjà un remote OCI, comme un Fedora Workstation par défaut avec son remote fedora, un utilisateur peu privilégié peut créer des répertoires appartenant à root à un chemin arbitraire. La charge utile de ce dépôt cible /root/.ssh lui-même.
Cette vulnérabilité, Finding A, a été démontrée dans le cadre d'une chaîne de deux vulnérabilités utilisée pour élever les privilèges d'un utilisateur local non authentifié à root sur la machine, dans un laboratoire contrôlé et autorisé. La chaîne fonctionne comme suit : Finding A crée /root/.ssh en tant que root. Finding B, une primitive d'écriture secondaire, peut ensuite écrire du contenu contrôlé par l'attaquant dans ce répertoire. Ensemble, elles donnent à un attaquant un fichier appartenant à root à un chemin choisi par l'attaquant. Chaque bug pris isolément est limité : Finding A ne crée que des répertoires, et Finding B ne peut écrire que là où un répertoire parent existe déjà. Finding A fournit le répertoire parent dont Finding B a besoin, et la paire devient une écriture de fichier en root.
Finding B a été identifié indépendamment par cette recherche, mais ce n'est pas une nouvelle découverte : c'est la faiblesse connue et toujours non corrigée dans le chemin d'écriture de données supplémentaires de Deploy, documentée dans le post-mortem de recherche. Cette analyse couvre donc et crédite Finding A, et n'utilise Finding B que comme le composant connu et non corrigé sur lequel la chaîne repose.
Ce dépôt ne démontre que Finding A. La méthodologie de chaînage et les leçons défensives sont documentées dans le post-mortem de recherche.
Le projet fournit déjà flatpak_is_valid_arch, qui restreint un nom d'architecture à [A-Za-z0-9_]. La remédiation consiste à l'appeler sur l'argument arch à la frontière du handler et à l'intérieur des helpers de construction de chemin. Une valeur ../ ne peut pas passer ce prédicat. Mettez à jour vers la version corrigée de Flatpak.
.
├── README.md Ce fichier.
├── requirements.txt Prérequis des paquets système pour le PoC.
└── poc_arch_traversal.sh PoC pour le paramètre arch non validé.
Mode test en bac à sable par défaut, le mode
production cible /root/.ssh. Usage pédagogique uniquement.
requirements.txt
présents.allow_active=yes. Vérifiez avec :
loginctl list-sessions et confirmez que votre session affiche un seat./usr/libexec/flatpak-system-helper ; le
script cherche d'abord un helper fraîchement compilé dans builddir/ ou _build/ de
l'arborescence source de Flatpak, et FLATPAK_SYSTEM_HELPER a la priorité sur tout.
Voir requirements.txt pour les paquets système nécessaires.Le mode production détecte automatiquement un remote OCI existant sur l'installation système et l'utilise. N'importe quel remote OCI fonctionne, même un faux ou injoignable, car le mkdir se produit avant que le registre ne soit contacté. Si aucun remote OCI n'existe, le script s'annule avec un message « No OCI remote found » et n'envoie rien.
Fedora Workstation fournit déjà le remote OCI fedora, donc rien n'est nécessaire
à ce niveau. Vérifiez ce qui existe avec flatpak remotes --system (un remote OCI
affiche oci dans sa colonne d'options).
C'est la seule commande de tout le flux qui nécessite sudo, et le script ne l'exécute jamais pour vous. Ajoutez-en un avec :
sudo flatpak remote-add --system --no-gpg-verify oci-poc oci+http://127.0.0.1:19876
(flatpak n'a pas d'option --oci, du moins jusqu'à la version 1.19.0, la version sur laquelle ce travail
est basé ; le préfixe d'URL oci+ est ce qui fait du remote un registre OCI.) Un message « Warning: Could not update extra metadata »
est attendu lorsqu'aucun registre n'est en cours d'exécution ; le remote est tout de même ajouté.
bash poc_arch_traversal.sh
Le script démarre un bus D-Bus privé et un helper en mode --session, le tout
sous un répertoire temporaire. Il appelle DeployAppstream avec la charge utile
../../../../../root/.ssh et vérifie que le répertoire échappé a été créé
à <workdir>/root/.ssh, reproduisant la cible réelle. Attendez-vous à une erreur D-Bus au
milieu de la sortie : c'est la récupération de l'index OCI qui échoue après que le
répertoire a déjà été créé, et c'est le comportement attendu.
bash poc_arch_traversal.sh prod
Le script ne demande jamais de mot de passe. Il détecte automatiquement un remote OCI, déclenche
DeployAppstream sans authentification avec la charge utile de traversée, et affiche la
réponse du helper. Le helper root crée /root/.ssh puis échoue sur le
registre injoignable, ce qui affiche l'erreur D-Bus attendue. Si la réponse
est une erreur d'authentification à la place, vous n'êtes pas dans une session locale active ;
exécutez-le depuis la console de la machine. Un remote spécifique peut être forcé avec
bash poc_arch_traversal.sh prod <remote>.
Le déclencheur lui-même s'exécute sans privilèges, mais confirmer le résultat nécessite root, donc le script vous laisse le faire. Après l'exécution, sur la même machine :
sudo ls -laR /root/.ssh
sudo stat -c '%U:%G' /root/.ssh
Le répertoire doit exister et appartenir à root:root. L'erreur D-Bus dans la
sortie du script n'est pas un échec : elle prouve que le mkdir s'est exécuté avant la récupération, puisque
le répertoire échappé existe bien que l'appel de méthode ait échoué.
Si /root/.ssh existait déjà avant l'exécution (par exemple sur un hôte avec un
sshd en cours d'exécution), l'exécution est sans effet sur ce chemin et ne laisse rien derrière : le fichier lock
du helper est transitoire et est supprimé lorsque la méthode retourne, et
icons n'est écrit qu'après une récupération d'index réussie. Pour une vérification
propre, exécutez contre un chemin qui n'existe pas encore.
sudo rm -rf /root/.ssh # uniquement s'il n'existait pas avant l'exécution
sudo flatpak remote-delete --system oci-poc
Recherche et analyse par Yehia Ali Mohamed Ezzat.
La documentation et le code de ce dépôt sont fournis à des fins pédagogiques. Utilisez-les à vos propres risques et uniquement là où vous êtes autorisé.