Cuando la mayoría de los usuarios de Linux escuchan "root", piensan en el máximo privilegio posible en una computadora. Algunos incluso piensan que la raíz se ejecuta en el anillo 0. Pero en realidad, la raíz es solo un usuario normal que se ejecuta en el anillo 3, aunque el kernel confía (muchas operaciones sensibles del kernel están protegidas con controles en las líneas de if (!uid_eq(current_uid(), GLOBAL_ROOT_UID)) return -EPERM;
para evitar el abuso , que simplemente devuelve un error si uid != 0
).
En la mayoría de los sistemas Linux, el kernel confía tanto en la raíz que puede explotar fácilmente el kernel y obtener acceso al anillo 0 a voluntad. Sin embargo, a menudo es posible con herramientas de seguridad como grsecurity, SELinux, etc., evitar esto al reducir las habilidades peligrosas de la raíz y hacer cumplir estas restricciones en el nivel del kernel.
Me gustaría enumerar una lista de métodos mediante los cuales la raíz podría explotar el kernel para obtener acceso al modo kernel y al anillo 0. Hasta ahora, estos son los métodos que he pensado o aprendido de los cuales esto podría suceder, junto con mitigaciones potenciales:
-
ioperm()
yiopl()
pueden establecer permisos de puertos de E / S y pueden abusarse para escribir en regiones arbitrarias de la memoria, incluida la memoria donde reside el núcleo. Estos syscalls se pueden desactivar eliminándolos de la tabla syscall o con grsecurity. - La raíz solo puede modificar la imagen del kernel en
/boot
oa través del dispositivo de bloque. Un MAC puede restringir el acceso de la raíz a ambos. -
/dev/{k,}mem
están diseñados para permitir el acceso rw a memoria arbitraria. Estos se pueden deshabilitar completamente en la configuración del kernel, usando grsecurity o con un MAC. - Algunos MSR se pueden usar para escribir en una memoria arbitraria. Negar la escritura a los MSR ya sea desactivándolos en la configuración del kernel o con grsecurity mitiga este problema.
-
kexec
permite que root seleccione un kernel alternativo para iniciar. Esta es una característica opcional del kernel, así que simplemente compilar el kernel sinkexec
es suficiente para que esto no sea un problema. -
sysfs
proporciona acceso de bajo nivel a gran parte del hardware, que puede secuestrar un BIOS / UEFI mal bloqueado en muchos sistemas vulnerables para ganar el anillo 0, o incluso el anillo -2. Un MAC puede restringir el acceso a/sys
, y varias herramientas pueden detectar vulnerabilidades en UEFI / BIOS. - Si la raíz tiene permiso para cargar tablas ACPI en tiempo de ejecución (DSDT, SSDT, etc.), puede hacer que el kernel ejecute AML, que es el código de bytes de ACPI, y cambiar la forma en que se comporta el kernel y reacciona al hardware en el que se ejecuta. Sé poco sobre ACPI y AML, pero esto parece una receta absoluta para el desastre. Deshabilitar el soporte de tabla ACPI cargable en el kernel debería mitigar esto.
- La carga de módulos maliciosos del kernel puede secuestrar directamente el kernel. Esto puede ser derrotado trivialmente requiriendo la firma del módulo, o construyendo un núcleo sin soporte de módulo.
Obviamente, usaré el principio de privilegio mínimo para root, en lugar de intentar incluir en una lista negra todas las formas posibles en que puede salir de sus cadenas. Eso no cambia el hecho de que sigue siendo extremadamente útil, y interesante , para comprender todas las formas en que puede abusar de la confianza del núcleo.
Y eso me lleva a mi pregunta: ¿Hay algún otro método que la raíz pueda usar para obtener acceso al anillo 0, sin usar 0 días y sin explotar los errores opsec, que no he cubierto aquí?