
Write-up educativo y PoC en modo de prueba para CVE-2026-92162, un path traversal en el parámetro arch de DeployAppstream de Flatpak que permite la creación de directorios root.
Análisis educativo y prueba de concepto en modo de prueba de un path traversal en el
helper del sistema de Flatpak (flatpak-system-helper). El método D-Bus DeployAppstream
acepta una cadena arch que se coloca en una ruta del sistema de archivos y se crea
como root, sin validación alguna. Un usuario local activo puede proporcionar componentes
../ y provocar que el servicio con privilegios de root cree directorios fuera del árbol
appstream previsto.
Este repositorio acompaña el análisis técnico completo y el post-mortem de la investigación. Existe con fines educativos, para defensores que quieran entender el mecanismo, y para pruebas autorizadas en sistemas que poseas o para los que tengas permiso por escrito de evaluar.
Este material se publica tras la divulgación coordinada y después de que se pusiera a disposición una versión corregida de Flatpak. Ejecuta la prueba de concepto solo contra una máquina de laboratorio que poseas o que estés explícitamente autorizado a probar. No la ejecutes contra sistemas que no controles. Eres responsable de mantenerte dentro de la ley y dentro del alcance de cualquier autorización que poseas.
handle_deploy_appstream() en el helper del sistema valida el argumento origin
pero no el argumento arch. Para un remoto OCI, arch fluye hacia
flatpak_build_file y luego hacia g_mkdir_with_parents, que se ejecuta como root y
resuelve ../ de forma léxica. La acción de polkit para el método es
org.freedesktop.Flatpak.appstream-update, que es allow_active=yes, por lo que una
sesión local activa alcanza el código sin solicitud de contraseña. En un sistema que
ya tiene un remoto OCI, como un Fedora Workstation predeterminado con su remoto fedora,
un usuario con pocos privilegios puede crear directorios propiedad de root en una ruta
arbitraria. El payload de este repositorio apunta al propio /root/.ssh.
Esta vulnerabilidad, el Hallazgo A, se demostró como parte de una cadena de dos
vulnerabilidades utilizada para escalar desde un usuario local no autenticado hasta root en
la máquina, en un laboratorio controlado y autorizado. La cadena funciona de la siguiente manera:
el Hallazgo A crea /root/.ssh como root. El Hallazgo B, una primitiva de escritura secundaria,
puede entonces escribir contenido controlado por el atacante en ese directorio. Juntos
proporcionan al atacante un archivo propiedad de root en una ruta elegida por el atacante. Cada fallo por sí solo
es limitado: el Hallazgo A solo crea directorios, y el Hallazgo B solo puede escribir
donde ya existe un directorio padre. El Hallazgo A proporciona el directorio
padre que el Hallazgo B necesita, y el par se convierte en escritura de archivos como root.
El Hallazgo B fue identificado de forma independiente por esta investigación, pero no es un
hallazgo nuevo: es la debilidad conocida y aún sin parchear en la ruta de escritura de datos
extra de Deploy documentada en el post-mortem de la investigación. Este análisis, por lo tanto,
cubre y acredita el Hallazgo A, y utiliza el Hallazgo B solo como el componente conocido
y sin parchear en el que se apoya la cadena.
Este repositorio demuestra únicamente el Hallazgo A. La metodología de encadenamiento y las lecciones defensivas están documentadas en el post-mortem de la investigación.
El proyecto ya incluye flatpak_is_valid_arch, que restringe un
nombre de arquitectura a [A-Za-z0-9_]. La remediación consiste en llamarlo sobre el argumento
arch en el límite del handler y dentro de los helpers de construcción de rutas. Un valor
../ no puede pasar ese predicado. Actualiza a la versión corregida de Flatpak.
.
├── README.md Este archivo.
├── requirements.txt Paquetes de sistema prerequisitos para el PoC.
└── poc_arch_traversal.sh PoC para el parámetro arch no validado.
Modo de prueba en sandbox por defecto, el modo
de producción apunta a /root/.ssh. Solo para uso educativo.
requirements.txt
presentes.allow_active=yes. Compruébalo con:
loginctl list-sessions y confirma que tu sesión muestra un seat./usr/libexec/flatpak-system-helper; el
script primero busca un helper recién compilado en builddir/ o _build/ del
árbol de fuentes de Flatpak, y FLATPAK_SYSTEM_HELPER anula todo lo anterior.
Consulta requirements.txt para los paquetes de sistema necesarios.El modo de producción autodetecta un remoto OCI existente en la instalación del sistema y lo utiliza. Cualquier remoto OCI sirve, incluso uno falso o inalcanzable, porque el mkdir ocurre antes de que se contacte con el registro. Si no existe ningún remoto OCI, el script se cancela con un mensaje "No OCI remote found" y no envía nada.
Fedora Workstation ya incluye el remoto OCI fedora, así que no hay que hacer
nada allí. Comprueba lo que existe con flatpak remotes --system (un remoto OCI
muestra oci en su columna de opciones).
Este es el único comando de todo el flujo que necesita sudo, y el script nunca lo ejecuta por ti. Añade uno con:
sudo flatpak remote-add --system --no-gpg-verify oci-poc oci+http://127.0.0.1:19876
(flatpak no tiene un flag --oci, al menos hasta la 1.19.0, la versión en la que se basa
este trabajo; el prefijo de URL oci+ es lo que convierte el remoto en un registro OCI). Un mensaje "Warning: Could not update extra metadata"
es esperado cuando no hay ningún registro en ejecución; el remoto se añade igualmente.
bash poc_arch_traversal.sh
El script inicia un bus D-Bus privado y un helper en modo --session, todo
bajo un directorio temporal. Llama a DeployAppstream con el payload
../../../../../root/.ssh y verifica que el directorio escapado se creó
en <workdir>/root/.ssh, reflejando el objetivo real. Espera un error de D-Bus en
mitad de la salida: es la descarga del índice OCI fallando después de que el
directorio ya se creara, y es el comportamiento esperado.
bash poc_arch_traversal.sh prod
El script nunca pide una contraseña. Autodetecta un remoto OCI, dispara
DeployAppstream sin autenticación con el payload de traversal, e imprime la
respuesta del helper. El helper de root crea /root/.ssh y luego falla en el
registro inalcanzable, lo que imprime el error de D-Bus esperado. Si la respuesta
es un error de autenticación en su lugar, no estás en una sesión local activa;
ejecútalo desde la consola de la máquina. Se puede forzar un remoto específico con
bash poc_arch_traversal.sh prod <remote>.
El disparador en sí se ejecuta sin privilegios, pero confirmar el resultado necesita root, así que el script deja eso en tus manos. Después de la ejecución, en la misma máquina:
sudo ls -laR /root/.ssh
sudo stat -c '%U:%G' /root/.ssh
El directorio debe existir y ser propiedad de root:root. El error de D-Bus en la
salida del script no es un fallo: demuestra que el mkdir se ejecutó antes de la descarga, ya que
el directorio escapado existe aunque la llamada al método fallara.
Si /root/.ssh ya existía antes de la ejecución (por ejemplo, en un host con un
sshd en ejecución), la ejecución no hace nada en esa ruta y no deja nada atrás: el archivo
lock del helper es transitorio y se elimina cuando el método retorna, y
icons solo se escribe tras una descarga exitosa del índice. Para una verificación
limpia, ejecútalo contra una ruta que aún no exista.
sudo rm -rf /root/.ssh # solo si no existía antes de la ejecución
sudo flatpak remote-delete --system oci-poc
Investigación y análisis por Yehia Ali Mohamed Ezzat.
La documentación y el código de este repositorio se proporcionan con fines educativos. Úsalos bajo tu propio riesgo y solo donde estés autorizado.