Se
han publicado dos exploits y una prueba de concepto
para explotar una vulnerabilidad en el kernel Linux que podría permitir a un atacante local elevar privilegios a root.
La vulnerabilidad afecta a los
kernel Linux posteriores a la versión 3.4. El error fue introducido en la
función 'compat_sys_recvmmsg' en el
archivo '/net/compat.c' al agregar
código para manejar estructuras de tiempo de 64 bits.
Básicamente, el fallo consiste en
una ausencia de verificación en cierta estructura pasada desde el área de
usuario como argumento a la función '__sys_recvmmsg'.
Esta función terminará por usar la estructura pasada a espacio del kernel sin
ningún tipo de comprobación. Si observamos el código del commit:
En primer lugar vemos como la
función 'compat_sys_recvmmsg' recibe
en uno de sus parámetros (el último) un puntero a una estructura 'timespec'. Dicho parámetro está marcado por la macro '__user' que indica que dicho parámetro
procede del área de usuario.
Posteriormente vemos como si está
definido 'COMPAT_USE_64BIT_TIME' dicho
parámetro es usado en la llamada a la función '__sys_recvmmsg'. Ahí está el problema, y es grave. Jamás se debería acceder a la memoria del
kernel desde el espacio de usuario y no filtrar previamente dicha estructura
es lo que hace precisamente la función vulnerable.
Tal y como señalan en la listaoss-security (de lectura altamente recomendable) uno de los parches propuestos filtra dicho parámetro a través de la llamada a
la función 'copy_from_user' para
comprobar si las referencias a memoria se están haciendo al espacio de usuario
en vez de a la memoria del núcleo o si tiene capacidad para lectura/escritura.
En dicho caso se provocaría un fallo y se devolvería el error -EFAULT.
Vemos parcialmente el parche aquí
y observamos las llamadas a la función comentada y a su homónima 'copy_to_user' cuando la operación es a
la inversa:
En principio la vulnerabilidad
afecta a los kernel Linux desde la versión 3.4, aunque ha de estar definida la
opción 'CONFIG_X86_X32'. Esto podemos
comprobarlo en el archivo de configuración de arranque (en algunas
distribuciones):
/boot/config-* (donde * es la versión del
kernel que podemos ver también haciendo uname -r)
Como curiosidad lo que esta
opción permite es tener la capacidad de ejecutar binarios que usen punteros de
32 bits ejecutándose en arquitecturas de 64bits. (http://en.wikipedia.org/wiki/X32_ABI)
Más información:
Exploit 1
Exploit 2
PoC
David García
Twitter: @dgn1729


No hay comentarios:
Publicar un comentario