Un rootkit es un conjunto de herramientas que ejecutas en una máquina de destino cuando de alguna manera obtuviste acceso a él con privilegios de nivel de raíz. El objetivo del rootkit es transformar ese acceso transitorio en una puerta siempre abierta. Un ejemplo de un rootkit sería una modificación del binario sshd
, de modo que siempre acepte " 8gh347vb45
" como contraseña para root
, independientemente de cuál sea la contraseña "normal" para root. Le permite al atacante volver más tarde, sin tener que pasar por los aros de la hazaña que utilizó primero.
La primera tarea de un rootkit es ocultarse y resistir las actualizaciones. Si el rootkit simplemente modifica sshd
(ese es un ejemplo), la próxima actualización del paquete openssh
eliminará el rootkit. Un rootkit más resistente también alteraría el administrador de paquetes, de modo que cuando se actualiza openssh
, el nuevo sshd
se modifica automáticamente para que el punto de acceso adicional para el atacante se mantenga abierto.
Los rootkits más potentes modifican el kernel , que es la pieza de software que realmente administra el hardware. Todos los procesos (para todos los usuarios, incluido el usuario root), cuando acceden a datos o recursos de hardware (por ejemplo, leer o escribir archivos), lo hacen preguntando amablemente al núcleo. Un rootkit instalado en el kernel puede ocultar archivos de manera bastante efectiva, y puede reinstalarse con cada actualización del kernel, ya que dicha actualización sería la sustitución del archivo que contiene el código del kernel con otra, es decir, una operación que necesariamente se realiza el núcleo.
Un módulo del kernel es un fragmento de código que se carga dinámicamente en el kernel. En Linux, hasta cierto punto en la serie 1.3.x, había un solo bloque de código monolítico que el cargador de arranque cargaba en la RAM de una sola vez. Los módulos son fragmentos de código que se pueden agregar en un punto posterior al kernel activo; inicialmente, su objetivo era permitir que el kernel potencialmente manejara cientos de tipos de hardware sin tener que contener el código del controlador correspondiente en la RAM en todo momento. La idea es que cuando se detecta una nueva pieza de hardware en la máquina, el código correspondiente se carga y se vincula al kernel, como si hubiera estado allí desde el principio.
El usuario root
tiene el poder de solicitar que se cargue un módulo. Así que esta es una forma de que algunos códigos con privilegios root
obtengan un código arbitrario insertado en el propio kernel y ejecutándose con los poderes otorgados al kernel, es decir, dominio sobre todo el hardware y los procesos (denominado 'anillo 0' en El mundo x86). Esto es exactamente lo que necesita un rootkit del kernel.
Editar: en cuanto a la tercera pregunta (¿puedes parchear contra rookits), la respuesta genérica es no ? (por construcción, en un sistema Unix, la raíz puede hacer todo en una máquina), pero la respuesta específica puede ser sí . Por ejemplo, hay marcos de seguridad que agregan restricciones a lo que la mayoría de los procesos raíz pueden hacer (por ejemplo, SELinux ), y pueden no permitir la carga del módulo del kernel. Esto significa que el acceso root temporal previsto por el atacante no es un acceso root true , solo un "root casi". Otra característica posible es módulos firmados (el núcleo rechazaría los módulos que no hayan sido firmados criptográficamente, por lo que el rootkit tendría que ubicar y use la clave privada antes de instalar su propio módulo, algo que tal vez no sea posible si esa clave no está almacenada en la propia máquina (no estoy seguro de que el soporte del módulo firmado esté actualmente integrado en el kernel de Linux). Además, los módulos deben vincularse con el código del kernel, lo que los hace bastante sensibles a las variaciones entre las versiones del kernel, por lo que incluso en ausencia de cualquier contramedida real, es difícil que un rootkit confíe nuevos kernels de nuevo. actualizaciones.