Una vez entendido el funcionamiento de los malware que se instalan en el kernel del sistema, ya podemos pasar a la fase defensiva, en la que explicaré lo simple que resulta protegernos de un ataque tan sencillo como el que vimos en el round 1: Hijacking system call.
En esta PROC veremos las técnicas más usadas por algunos rootkits y cómo mitigarlas. Para los que no estén familiarizados con el comportamiento de los rootkits, les diré que es un tipo de malware difícil de detectar y de seguir el rastro. De hecho, los más avanzados pueden esconder tráfico de red, uso real de CPU, ocultar archivos, esconder PIDs, etc…
Existen muchos tipos de funcionamientos, pero los más poderosos se apoderan de la tabla de llamadas que el núcleo del sistema expone al usuario. En el kernel 2.4 esta tabla está abierta para ver las direcciones de memoria en las que cada llamada (sys_call) se encuentra, de modo que solo se tiene que modificar el puntero de la llamada a nuestra función maligna.
En el round 1 pusimos el ejemplo de ocultar archivos usando esta técnica, pero al igual que podemos hacer que no se muestren procesos corriendo en el sistema, también podemos desactivar los backups y hacer ver que las copias se están realizando correctamente. Como mencionamos, la única forma de hablar con en kernel es a través de esta tabla, de modo que se le puede pedir acciones de open(), write() … entre otras. Como habréis visto si tienes el control del núcleo, tienes poder absoluto dentro del sistema. Con este panorama en la versión 2.6 las direcciones de memoria ya no son tan fácilmente accesibles, pero mediante métodos de debugging que él mismo incorpora se pueden sacar 😉
El primer paso que suelen hacer los rootkits es compilar dentro del sistema infectado el módulo maligno con el que comunicarse con el kernel. Éstos tienen la extensión .ko (kernel object). Más tarde lo que el rootkit hace es insertarse dentro del kernel, a través del comando insmod. Éste permite insertar módulos en el sistema directamente. Debido a que el kernel es una pieza de software muy precisa, el mínimo fallo de programación en los módulos hará que cuando insertemos un módulo erróneo, el sistema crashee y en consecuencia tengamos que reiniciar el equipo o incluso podríamos perder información almacenada.
Como observamos en la imagen, una vez insertado el módulo maligno del rootkit en la lista de llamadas (insmod rootkit.ko), éste no se muestra en /proc/modules, tampoco con un lsmod, a no ser que manualmente lo desenmascaremos. Estos dos comandos anteriores sirven para listar los módulos cargados actualmente. Todos los parámetros en forma de argumentos que le pasamos al módulo se transfieren mediante un buffer. Con el procedimiento que hemos mencionado, el rootkit ya estaría dentro de nuestro sistema y listo para que un atacante pudiese interaccionar con él. Lo peor de todo es que ni el usuario ni el sistema se han percatado de tal infección, de modo que…
Este tipo de ataque (Hijacking system call) es el más común. Normalmente los paquetes básicos que las distribuciones modernas de Linux nos ofrecen para una protección básica son: chkrootkit y rkhunter. Antes de pasar a la parte defensiva, solo decir que el kernel de Linux es código abierto, es decir, cualquiera puede ver, comprobar y modificar su código.
De modo que: «Let’s go deeper!» Pero… esto será en el próximo POST de la serie.
NOTA: Si te perdiste el round 1, aún estás a tiempo: Blindando nuestro kernel. Round 1