Malware en Linux: Rootkits, ocultación y detección

En pasados artículos Malware en Linux: Rootkits, introducción y clasificación y Malware en Linux: Rootkits en espacio de kernel, se describieron las principales estrategias utilizadas en la creación de rootkits y sus tipos. En este artículo se hablará de los mecanismos que se emplean para la ocultación así como las técnicas y herramientas para su descubrimiento.
Recordando los tipos más frecuentes de rootkits encontramos:
- Rootkits en espacio de usuario: Aquellos que se ejecutan en espacio de usuario (anillo-3) y que modifican librerías, archivos de configuración y binarios del sistema.
- Rootkits en espacio de kernel: Son los que se insertan en el código del kernel en ejecución bien directamente (vía /dev/kmem ) o a través de módulos dinámicos. Se ejecutan en el anillo 0 de máximo privilegio para interceptar llamadas al sistema y modificar el comportamiento del propio kernel.
Rootkits en espacio de usuario
En lo que se refiere a rootkits en espacio de usuario (anillo 3) los mecanismos de ocultación no son, por la propias limitaciones de privilegios, tan eficaces como sucede en espacio de kernel (anillo 0). Generalmente las estrategias para permanecer oculto se basan en utilizar enlaces simbólicos, cambios en las variables de entorno (LD_PRELOAD), alias de ficheros, así como la modificación de binarios, librerías y configuraciones (ld.so.preload, ld.so.cache, etc.).
Aunque es necesario un usuario privilegiado (root) para realizar estas modificaciones, éstas se mueven en el espacio de usuario y por ello este tipo de rootkits son relativamente sencillos de detectar.
Mediante comprobaciones de integridad (hashes de binarios) o utilizando herramientas compiladas estáticamente ajenas al sistema que se trata de analizar para comprobar diferencias con los resultados obtenidos en la ejecución de binarios nativos. Para ocultarse, estos rootkits suelen manipular los binarios utilizados para el mostrar de conexiones de red (netstat, lsof, tcpdump, ip…) , ficheros (ls, lsof, stat…) o procesos (ps, top.. ).
En el siguiente ejemplo vemos como detectar la existencia de un rootkit:
Otro método para detectar rootkits en espacio de usuario es verificar la integridad de los ficheros. Una herramienta como aide puede servir para realizar esta operación. Esta herramienta inicialmente hace un inventariado y obtiene un hash de cada fichero del sistema para almacenarlo en una base de datos. Cuando se realiza un test va comparando los resultados obtenidos con los almacenados en la base de datos informando de cualquier diferencia. Es necesario obtener una base de datos inicial del sistema con la certeza de que está libre de infección. Periódicamente es recomendable realizar un test, verificar los cambios y actualizar la base de datos.
- Resultado de un test de integridad con aide -
Es necesario tener en cuenta que ante la sospecha de cualquier intrusión se deben utilizar herramientas y binarios externos al sistema y que estén compilados estáticamente, para evitar cualquier interceptación de librerías dinámicas o interferencia por parte del rootkit. Si no se toman estas precauciones los resultados pueden resultar manipulados.
Rootkits en espacio de kernel
En este tipo de rootkit el enfoque cambia radicalmente puesto que es el mismo kernel el que está comprometido de modo que no es posible detectar de manera sencilla un comportamiento anómalo. Como se describió en el artículo Malware en Linux: Rootkits en espacio de kernel, estos rootkits se basan en interceptar las comunicaciones entre el espacio de usuario y el espacio de kernel a través de llamadas al sistema o syscalls. Un rootkit en espacio de kernel consigue eficazmente su ocultación al tener el control de las llamadas al sistema, las cuales constituyen el eslabón de enlace entre el kernel y el usuario.
Teniendo en cuenta que la detección de rootkits en espacio de kernel nunca estará 100% garantizada, las estrategias pasarán principalmente por:
- Monitorización de syscalls: Observar cambios en las direcciones de memoria de la tabla de syscalls. Contrastando con la tabla de símbolos de sistema original System.map con la actual tabla. En cualquier caso, ha de tenerse en cuenta que este fichero también ha podido ser modificado.
- Monitorización de cambios en la tabla de interrupciones (IDT): Muchos rootkits modifican la interrupción utilizada en las syscalls para que lleve a una tabla modificada en lugar de la tabla de llamadas original.
- Descubrimiento de módulos ocultos: Contrastar el listado de módulos dinámicos obtenido por lsmod, con los ficheros y directorios /proc/modules y /sys/module
- Utilizar herramientas diseñadas para la búsqueda de rootkits. Generalmente estas herramientas realizan verificaciones para descubrir discrepancias entre la información obtenida por comandos del sistema y la información disponible en /proc (unhide) así como anomalías en las syscalls (samhain, unhide). También se buscan ficheros y patrones reconocidos por rootkits ya descubiertos y documentados (rkhunter, chkrookit)
- Flujo de ejecución en una llamada al sistema -
Lógicamente en un sistema con el kernel comprometido esta tarea es complicada de realizar al tenerse que lidiar con elemento controlados al máximo nivel de privilegios. En caso de detección o sospecha de existencia de un rootkit en espacio de kernel es altamente recomendable una reinstalación del sistema.
Se puede concluir que, ya se trate de un rootkit en espacio de usuario o de un rootkit en espacio de kernel siempre enfrentamos una amenaza complicada de manejar y que, dependiendo de la importancia del sistema comprometido, requiere una reinstalación total del sistema su eliminación con total garantía.
Igualmente analizando una intrusión se puede obtener una información de gran valor para entender las deficiencias de seguridad que hicieron posible el compromiso de la plataforma afectada y corregir prácticas deficientes o erróneas. Se aprende siempre más de un error que de cien aciertos.
- Rootkits en espacio de usuario VS rootkits en espacio de kernel -