
Exploit de escalada de privilegios en Linux mediante snapd (CVE-2019-7304)
En enero de 2019, se descubrió que las versiones actuales de Ubuntu Linux eran vulnerables a la escalada de privilegios locales debido a un error en la API de snapd. Este repositorio contiene el POC original del exploit, que se pone a disposición para investigación y educación. Para un recorrido detallado de la vulnerabilidad y el exploit, consulte la publicación del blog aquí.
Ubuntu incluye snapd por defecto, pero cualquier distribución debería ser explotable si tiene este paquete instalado. Puede verificar fácilmente si su sistema es vulnerable. Ejecute el siguiente comando. Si su snapd es 2.37.1 o más reciente, está seguro.
$ snap version
...
snapd 2.37.1
...
Tenga en cuenta que algunos sistemas devuelven la versión del paquete de distribución de snapd cuando ejecuta este comando, en lugar de la versión ascendente que se muestra en el ejemplo anterior. Si su versión de snapd tiene una referencia a algo como un número de versión de Ubuntu adjunto (ejemplo: 2.34.2ubuntu0.1 o 2.35.5+18.10.1), consulte este enlace para determinar si está ejecutando una versión parcheada.
Este exploit evade las comprobaciones de control de acceso para utilizar una función de API restringida (POST /v2/create-user) del servicio snapd local. Esto consulta el SSO de Ubuntu para obtener un nombre de usuario y una clave SSH pública de una dirección de correo electrónico proporcionada, y luego crea un usuario local basado en estos valores.
La explotación exitosa de esta versión requiere una conexión a Internet saliente y un servicio SSH accesible a través de localhost.
Para explotar, primero cree una cuenta en el Ubuntu SSO. Después de confirmarla, edite su perfil y cargue una clave SSH pública. Luego, ejecute el exploit de la siguiente manera (con la clave privada SSH correspondiente a la clave pública que cargó):
python3 ./dirty_sockv1.py -u "[email protected]" -k "id_rsa"
[+] Slipped dirty sock on random socket file: /tmp/ktgolhtvdk;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Sending payload...
[+] Success! Enjoy your new account with sudo rights!
[Script will automatically ssh to localhost with the SSH key here]
Este exploit evade las comprobaciones de control de acceso para utilizar una función de API restringida (POST /v2/snaps) del servicio snapd local. Esto permite la instalación de snaps arbitrarios. Los snaps en "devmode" evitan el sandbox y pueden incluir un "install hook" que se ejecuta en el contexto de root durante la instalación.
dirty_sockv2 aprovecha la vulnerabilidad para instalar un snap "devmode" vacío que incluye un hook que agrega un nuevo usuario al sistema local. Este usuario tendrá permisos para ejecutar comandos sudo.
A diferencia de la versión uno, esta no requiere que el servicio SSH esté en ejecución. También funcionará en versiones más recientes de Ubuntu sin conexión a Internet, lo que la hace resistente a cambios y efectiva en entornos restringidos.
Nota para mayor claridad: Esta versión del exploit no se oculta dentro de un snap malicioso. En su lugar, utiliza un snap malicioso como mecanismo de entrega para el payload de creación de usuario. Esto es posible debido al mismo error uid=0 que la versión 1
Este exploit también debería ser efectivo en sistemas que no son Ubuntu pero que tienen instalado snapd y no soportan la API "create-user" debido a una sintaxis de shell de Linux incompatible.
Algunos sistemas Ubuntu más antiguos (como 16.04) pueden no tener los componentes de snapd necesarios para la carga lateral. Si este es el caso, esta versión del exploit puede desencadenar la instalación de esas dependencias. Durante esa instalación, snapd puede actualizarse a una versión no vulnerable. Las pruebas muestran que el exploit sigue teniendo éxito en este escenario. Consulte la sección de solución de problemas para más detalles.
Para explotar, simplemente ejecute el script sin argumentos en un sistema vulnerable.
python3 ./dirty_sockv2.py
[+] Slipped dirty sock on random socket file: /tmp/gytwczalgx;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Deleting trojan snap (and sleeping 5 seconds)...
[+] Installing the trojan snap (and sleeping 8 seconds)...
[+] Deleting trojan snap (and sleeping 5 seconds)...
********************
Success! You can now `su` to the following account and use sudo:
username: dirty_sock
password: dirty_sock
********************
Si usa la versión dos y el exploit se completa pero no ve su nueva cuenta, esto puede deberse a algunas actualizaciones de snap en segundo plano. Puede verlas ejecutando snap changes y luego snap change #, haciendo referencia a la línea que muestra la instalación del snap dirty_sock. Eventualmente, estas deberían completarse y su cuenta debería ser utilizable.
La versión 1 parece ser la más fácil y rápida, si su entorno lo soporta (servicio SSH en ejecución y accesible desde localhost).
Los sistemas no vulnerables generarán algo como lo siguiente:
[!] System may not be vulnerable, here is the API reply:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
Date: Mon, 18 Feb 2019 07:07:12 GMT
Content-Length: 119
{"type":"error","status-code":401,"status":"Unauthorized",
"result":{"message":"access denied","kind":"login-required"}}
Por favor, abra issues para cualquier cosa extraña.
El problema se informó directamente al equipo de snapd a través del rastreador de errores de Ubuntu. Puede leer el hilo completo aquí.
Quedé muy impresionado con la respuesta de Canonical a este problema. El equipo fue increíble para trabajar, y en general la experiencia me hace sentir muy bien al ser yo mismo un usuario de Ubuntu.
Enlaces de aviso público:
Nota: Solo estoy publicando información en este repositorio de GitHub, mi blog en initblog.com y el blog de mi equipo en shenaniganslabs.io. Cualquier sitio que se haga pasar por una fuente oficial está, desafortunadamente, fuera de mi control.