miércoles, 27 de enero de 2021

Vulnerabilidad en sudo presente desde 2011 permite elevar privilegios a root

Investigadores de Qualys han descubierto un heap overflow en sudo que, en su configuración por defecto, puede permitir a cualquier usuario local acceder como root en un sistema vulnerable. La vulnerabilidad ha sido etiquetada como CVE-2021-3156, referencia también como Baron Samedi, y estuvo ahí durante casi 10 años, desde el commit 8255ed69 hecho en junio de 2011. Concretamente afecta a las versiones de la 1.8.2 a la 1.8.31p2 y de la 1.9.0 a la 1.9.5p1 de sudo. Qualys desarrolló exploits para varias distribuciones de Linux, incluyendo Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27) y Fedora 33 (Sudo 1.9.2), y se cree que otras distribuciones también son vulnerables. La vulnerabilidad también afecta a Apple MacOS Big Sur (sin parchear en la actualidad), se puede habilitar la explotación del problema enlazando simbólicamente sudo a sudoedit



Impacto de la vulnerabilidad

El equipo de investigación de Qualys ha descubierto una vulnerabilidad de desbordamiento de pila en sudo, una utilidad casi ubicua disponible en los principales sistemas operativos similares a Unix. Cualquier usuario sin privilegios puede obtener privilegios de root en un host vulnerable utilizando una configuración sudo predeterminada aprovechando esta vulnerabilidad.


¿Qué es sudo?

Sudo es una alternativa a su para ejecutar comandos como superusuario. A diferencia de su, que lanza un shell de superusuario que permite que todos los demás comandos tengan acceso de superusuario, sudo ofrece una escalada temporal de privilegios a un solo comando. Al activar los privilegios de superusuario solo cuando es necesario, el uso de sudo reduce la probabilidad de que un error tipográfico o en un comando invocado arruine el sistema. 

Sudo es una poderosa utilidad que se incluye en la mayoría, si no en todos, los sistemas operativos basados ​​en Unix y Linux. Permite a los usuarios ejecutar programas con los privilegios de seguridad de otro usuario. La propia vulnerabilidad se ha estado escondiendo a plena vista durante casi 10 años. Se introdujo en julio de 2011 (commit 8255ed69) y afecta a todas las versiones heredadas de 1.8.2 a 1.8.31p2 y a todas las versiones estables de 1.9.0 a 1.9.5p1 en su configuración predeterminada.

La explotación exitosa de esta vulnerabilidad permite que cualquier usuario sin privilegios obtenga privilegios de root en el host vulnerable. Los investigadores de seguridad de Qualys han podido verificar de forma independiente la vulnerabilidad y desarrollar múltiples variantes de exploit y obtener privilegios de root completos en Ubuntu 20.04 (Sudo 1.8.31), Debian 10 (Sudo 1.8.27) y Fedora 33 (Sudo 1.9.2) . También es probable que otros sistemas operativos y distribuciones sean explotables.

Ejemplo fichero 

/etc/sudoers


Tan pronto como el equipo de investigación de Qualys confirmó la vulnerabilidad, Qualys participó en la divulgación responsable de la vulnerabilidad y se coordinó con el autor de sudo y las distribuciones de código abierto para anunciar la vulnerabilidad. 

Cuando sudo ejecuta un comando en modo shell , ya sea a través de la opción de línea de comando -s o -i , escapa los caracteres especiales en los argumentos del comando con una barra invertida. El complemento de política de sudoers eliminará los caracteres de escape de los argumentos antes de evaluarlo, cuando no espera los caracteres de escape.”, explicó el mantenedor de sudo, Todd C. Miller 

CVE-2021-3156  Detalle técnico explicado  por Qualys


Para ejecutar sudo en modo "shell" podemos usar los parámetros:

-s : flag MODE_SHELL
-i : flags MODE_SHELL y MODE_LOGIN_SHELL


y después el comando deseado. 

set_cmnd() es vulnerable a un desbordamiento de búfer en el heap, porque los caracteres out-of-bounds que se copian en el búfer "user_args" no se incluyeron en su tamaño (calculado en líneas 852-853).

En teoría ningún argumento pasado en la línea de comandos puede terminar con un solo carácter "\": si MODE_SHELL o MODE_LOGIN_SHELL están configurados (línea 858, una condición necesaria para llegar al código vulnerable), entonces MODE_SHELL está configurado (línea 571) y parse_args() ya se escapó de todos los metacaracteres, incluidos los "\" (es decir, se escapó de cada "\" con un segundo "\").

La pregunta es: ¿podemos configurar MODE_SHELL y MODE_EDIT o MODE_CHECK (para llegar al código vulnerable) pero no el MODE_RUN predeterminado (para evitar el código de escape)?

La respuesta, al parecer, es no: si configuramos MODE_EDIT (opción -e, línea 361) o MODE_CHECK (opción -l, líneas 423 y 519), entonces parse_args() elimina MODE_SHELL de "valid_flags" (líneas 363 y 424) ) y sale con un error si especificamos una flag no válida como MODE_SHELL (líneas 532-533): 

Qualys encontró una pequeña laguna: si ejecutamos Sudo como "sudoedit" en lugar de "sudo", entonces parse_args() establece automáticamente MODE_EDIT (línea 270) pero no restablece "valid_flags", y los "valid_flags" incluyen MODE_SHELL por defecto

Por lo tanto, si ejecutamos "sudoedit -s", entonces seteamos MODE_EDIT y MODE_SHELL (pero no MODE_RUN), evitamos el código de escape, llegamos al código vulnerable y desbordamos el heap "user_args" a través de nuestro argumento que termina con un solo carácter "\":

sudoedit -s '\' `perl -e 'print "A" x 65536'` 
malloc(): corrupted top size 
Aborted (core dumped) 


Desde el punto de vista de un atacante, este desbordamiento de búfer es ideal debido a las siguientes razones:

1) El atacante controla el tamaño del búfer “user_args” que puede desbordarse (el tamaño de nuestros argumentos de línea de comandos concatenados, en las líneas 852-854)

2) El atacante controla de forma independiente el tamaño y el contenido del desbordamiento en sí (nuestro último argumento de línea de comandos es seguido convenientemente por nuestras primeras variables de entorno, que no se incluyen en el cálculo de tamaño en las líneas 852-853);

3) El atacante puede incluso escribir bytes nulos en el búfer que se desbordó (cada argumento de línea de comando o variable de entorno que termine con una sola barra invertida escribe un byte nulo en "user_args", en las líneas 866-868).

 PoC Video

¿Cómo puedo comprobar si tengo una versión vulnerable?

Para probar si un sistema es vulnerable o no, inicie sesión en el sistema como usuario no root.

Ejecuta el comando

 sudoedit -s /

Si el sistema es vulnerable, responderá con un error que comienza con "sudoedit:"

Si el sistema está parcheado, responderá con un error que comienza con "usage:" 


Fuentes:
https://www.hackplayers.com/2021/01/publican-los-detalles-de-una.html

https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit

No hay comentarios:

Publicar un comentario