Rootkit ( eng. rootkit , es decir, " conjunto raíz ") es un conjunto de herramientas de software (por ejemplo, archivos ejecutables, scripts, archivos de configuración ) que proporcionan:
Históricamente, el término Rootkit proviene del mundo UNIX , y este término se refiere a un conjunto de utilidades o un módulo especial del kernel que un atacante instala en un sistema informático que ha pirateado inmediatamente después de obtener los derechos de superusuario. Este conjunto, por regla general, incluye una variedad de utilidades para cubrir las huellas de una intrusión en el sistema, haciendo invisibles a los rastreadores , escáneres, registradores de teclas , troyanos , reemplazando las principales utilidades de UNIX (en el caso de un rootkit no nuclear). El rootkit permite que un atacante se afiance en un sistema comprometido y oculte los rastros de sus actividades ocultando archivos, procesos y la presencia misma de un rootkit en el sistema.
Un rootkit se puede instalar en un sistema de varias maneras: descargándolo a través de un exploit , después de obtener acceso de shell (en este caso, se puede usar una herramienta como wget o el cliente FTP original para descargar el rootkit desde un dispositivo remoto), en el código fuente o los recursos del producto de software.
Existen varias tecnologías de rootkit, las más comunes son la captura de tablas de llamadas (IAT, IDT, SSDT, GDT ), interceptación de funciones (por ejemplo, modificación de bytes iniciales), modificación directa de objetos del sistema (DKOM), métodos de uso de controladores.
Captura de tablas de llamadasLa tabla de llamadas es una matriz en la que cada elemento almacena la dirección del procedimiento correspondiente. Dichas tablas existen tanto en modo kernel (IDT, CPU MSR, GDT, SSDT, tabla de despacho IRP) como en modo usuario (IAT).
La tabla de direcciones de importación (IAT) es la tabla principal de llamadas del módulo de modo de usuario. La mayoría de los archivos ejecutables tienen uno o más IAT integrados que contienen las direcciones de las rutinas de la biblioteca importadas de la DLL [2] .
En una máquina multiprocesador, hay varias instancias de tablas de llamadas (por ejemplo, IDT, GDT , MSR ). Dado que cada procesador tiene sus propios registros del sistema (en particular, GDTR, el registro de tabla de descriptor global (GDT), IDTR, el registro descriptor de tabla de interrupción (IDT) e IA32_SYSENTER_EIP, contiene la dirección virtual del punto de entrada del modo kernel (MSR)) , también tiene estructuras propias del sistema [3] .
Cuando se cambia una entrada en la tabla de llamadas, se controla la ejecución de los programas y, si es necesario, se redirige a las funciones requeridas. El procedimiento interceptado puede [4] :
La idea general de captura es la siguiente:
Si la función de intercepción involucra llamar al procedimiento original, entonces el bloqueo y el monitoreo se realizan antes de la llamada y el filtrado de parámetros después.
IAT es una tabla de llamadas ubicada en la estructura de archivos de la aplicación. El IAT almacena la dirección de los procedimientos exportados por una DLL en particular . Cada DLL a la que se vincula una aplicación en el momento del arranque tiene su propio IAT. Para capturar el IAT, debe hacer lo siguiente:
Para manipular el IAT se requiere acceso al espacio de direcciones de la aplicación a la que pertenece la tabla. Una forma es inyectar una DLL. Entre los métodos para inyectar una DLL en el espacio de direcciones de un proceso, uno puede especificar [5] :
El principio de funcionamiento se basa en el hecho de que los primeros bytes de las funciones interceptadas se reemplazan por el código del interceptor. Cabe recalcar que al instalar el interceptor no se analiza el código de la función interceptada: se modifican los primeros N bytes, y no las primeras N instrucciones máquina. La consecuencia de este hecho es [6] :
Algoritmo de rootkit:
Algoritmo de operación del interceptor:
Para interceptar, basta con modificar los primeros cinco bytes de la función, en cuyo lugar se escribe la operación jmp, transfiriendo el control al interceptor del rootkit.
Cabe señalar que los sistemas más simples para protegerse contra ataques de este tipo verifican el primer byte de las funciones llamadas para detectar la presencia del código de operación de la máquina jmp en ellas. Como contramedida, los desarrolladores de rootkits utilizan técnicas para “enmascarar” el código escrito al comienzo de la función interceptora (usando comandos como PUSH/RET, colocando varios operadores NOP o código basura como PUSH AX/POP AX, así como elementos de polimorfismo). ).
El método de modificar los primeros bytes de las funciones tiene una serie de desventajas, principalmente relacionadas con la necesidad de restaurar el código máquina de las funciones interceptadas antes de llamarlas y volver a interceptarlas después de la llamada. Estas operaciones reducen el rendimiento del sistema y pueden hacer que las aplicaciones de subprocesos múltiples se bloqueen .
DKOM (Manipulación Directa de Objetos del Kernel)Los sistemas operativos de la familia Windows NT utilizan modelos de objetos estándar. Varios componentes del sistema de ejecución definen uno o más tipos de objetos. Cada componente exporta en modo kernel un conjunto de funciones y propiedades compatibles, denominadas interfaz COM, para manipular ese tipo de objeto. Ningún componente puede acceder directamente a otro objeto componente. Los objetos típicos en modo kernel son [7] :
Este diseño proporciona flexibilidad y portabilidad, por ejemplo, las versiones futuras del sistema operativo pueden contener componentes del núcleo que definen objetos similares, pero tienen una estructura interna completamente diferente. Si dichos componentes exportarán funciones con nombres y parámetros preservados, el cambio no tendrá efecto [3] .
La manipulación directa de los objetos del kernel es una tecnología bastante poderosa que es difícil de descubrir. Sin embargo, hay una serie de desventajas, como la inestabilidad del método, la dependencia de la versión, la complejidad de la implementación debido a la falta de una descripción documentada de las estructuras y propiedades de los objetos. A pesar de estas limitaciones, este método le permite ocultar procesos, controladores de dispositivos, puertos y elevar los privilegios de los subprocesos (por lo tanto, los procesos).
EPROCESS es una estructura que sirve como representación interna de un proceso (objeto de proceso). Windows usa una lista circular doblemente enlazada de estructuras EPROCESS para realizar un seguimiento del progreso de la ejecución. Los enlaces que vinculan objetos EPROCESS están contenidos en el campo ActiveProcessLink, cuya estructura es LIST_ENTRY [8] :
estructura typedef _LIST_ENTRY { estructura _LIST_ENTRY * Flink ; estructura _LIST_ENTRY * Parpadeo ; } ENTRADA_LISTA , * ENTRADA_PLISTA ;El algoritmo de ocultación de procesos más simple:
Excluir un proceso de la lista de procesos no afecta su ejecución. En Windows, el código está programado para ejecutarse a nivel de subprocesos, los procesos definen el contexto en el que se ejecutan los subprocesos. Ocultar un proceso se realiza externamente en herramientas que se basan en objetos de proceso EPROCESS, como el Administrador de tareas. El distribuidor del núcleo utiliza un esquema de contabilidad diferente que se basa en otras estructuras de datos (principalmente el objeto ETHREAD). Este método le permite ocultar procesos sin perder funcionalidad [9] .
ControladoresEl modelo de controlador de Microsoft admite una arquitectura en capas, por lo que una solicitud de E/S (solicitud de E/S, intercambio de datos entre aplicaciones y controladores) puede ser atendida por una serie de controladores conectados , cada uno de los cuales realiza su propia tarea. Una cadena de controladores que sirven a un dispositivo físico se denomina pila. Este enfoque modular permite incluir nuevos controladores en la pila para aumentar la funcionalidad. En este caso, solo se cambia o agrega una sección separada de la cadena. Además, algunos periféricos utilizan los mismos controladores (y, por lo tanto, buses de E/S). La modularidad le permite optimizar el uso de los mismos bloques de código, en lugar de escribir un controlador separado para cada dispositivo.
En el modelo WDM se definen tres tipos de controladores: controlador de bus, controladores de función y controladores de filtro. Los controladores de filtro generalmente se ubican entre otros módulos y capturan los IRP que pasan a través de ellos . Antes de enviar el IRP al controlador adyacente, el filtro puede examinar el contenido o modificarlo para influir en el comportamiento del sistema. Por ejemplo, al tomar una imagen de disco de un servidor crítico en tiempo de inactividad, se puede usar un controlador de filtro para cambiar el flujo de datos para ocultar algunos archivos.
El paquete IRP (paquete de solicitud de E/S) es una estructura de datos del kernel de Windows que proporciona intercambio de datos entre las aplicaciones y el controlador, así como entre el controlador y el controlador. Cuando se recibe una solicitud de una aplicación, el administrador de E/S genera un IRP apropiado, que localiza y reenvía al objeto superior en la pila de controladores. Si el controlador superior pudo procesar el IRP entrante por sí mismo, completa la solicitud y devuelve el IRP al administrador de E/S. De lo contrario, el controlador realiza un procesamiento parcial, localiza el objeto subyacente en la pila y le pide al administrador de E/S que pase el IRP al siguiente controlador.
Al crear un IRP, el administrador de E/S reserva el área de memoria después del encabezado. La memoria asignada se usa para escribir una matriz de estructuras IO_STACK_LOCATION asignadas para cada controlador de pila:
El tamaño de la memoria corresponde al número de controladores en la pila. La matriz está numerada desde 1, correspondiente al controlador de pila inferior. La estructura contiene información sobre la función de control del controlador llamada por el administrador de E/S (los campos MajorFunction y MinorFunction), los parámetros pasados a la función (el campo Parámetros, el contenido varía según la función), un puntero al objeto del controlador (DeviceObject), un puntero a la función de finalización (el campo CompletionRoutine, esta función se encuentra en el controlador de nivel superior).
La función de control del controlador, al recibir por primera vez un IRP, restaura los parámetros desde la posición de pila de E/S adecuada llamando a IoGetCurrentIrpStackLocation(). A continuación, se realizan las acciones prescritas, después de lo cual, en el caso de reenviar el IRP al controlador de pila inferior, sucede lo siguiente:
Hay dos formas estándar de establecer la posición de la pila para el siguiente controlador [10] :
La función reduce el puntero a la matriz IO_STACK_LOCATION en uno. Por lo tanto, al reenviar el IRP, el puntero se restaurará (aumentado automáticamente en uno), como resultado, se utilizará la misma sección de la pila. Al usar este método, habrá un área sin usar al final de la pila.
El reenvío de un IRP al siguiente conductor se realiza mediante la función:
NTSTATUS IoCallDriver ( IN PDEVICE_OBJECT DeviceObject , IN OUT PIRP Irp );El primer argumento es un puntero al objeto controlador subyacente. El método para obtener dicha dirección está determinado por la función de control específica, no existe un método estándar.
Cada solicitud debe ser finalizada por el último controlador de la pila (no es posible reenviar más el IRP) o por uno de los controladores ascendentes.
El administrador de E/S inicia el proceso de finalización para un IRP determinado cuando cualquiera de los controladores de procesamiento de IRP llama a la función de finalización IoCompleteRoutine(). Cuando se le llama, el administrador de E/S llena la pila de E/S del controlador actual con ceros y luego llama al controlador de nivel superior con la función de terminación establecida en este IRP. Solo el bloque de estado de E/S en el IRP está disponible para determinar cómo maneja la solicitud el controlador de nivel inferior de la función de finalización del controlador de nivel superior.
En realidad, el controlador de filtro instalado de esta manera le permite procesar no solo los paquetes IRP entrantes (por ejemplo, bloquear la lectura de un determinado sector del disco), sino también administrar los resultados del procesamiento de los controladores posteriores al inicializar la función de terminación [11] .
Otro método para implementar rootkits es modificar el MBR e iniciar el kernel del sistema operativo: bootkits (por ejemplo, BackDoor.MaosBoot).
Este tipo de código malicioso en el entorno Windows se conoce desde principios de la década de 1990 con el nombre de virus sigilosos .
Además de sí mismo, un rootkit, por regla general, puede enmascarar la presencia en el sistema de cualquier directorio y archivo descrito en su configuración en el disco, claves en el registro . Por esta razón, las bibliotecas de rootkits "montadas" aparecieron naturalmente. Muchos rootkits instalan sus propios controladores y servicios en el sistema (por supuesto, también son "invisibles").
Los rootkits, de hecho, son la mayoría del software de protección contra copias (y medios para eludir estas protecciones, por ejemplo, emuladores de unidades de CD y DVD ) .
En 2005, Sony BMG Corporation incorporó protección basada en rootkit en sus CD de audio , que se instalaba sin el conocimiento del usuario.
Estas son utilidades o módulos residentes que detectan la presencia de rootkits en el sistema y (en diversos grados) los eliminan. Hay muchas herramientas que compiten para esto, tanto pagas como gratuitas, pero todas usan principios similares.
Métodos para detectar rootkitsExiste un algoritmo conocido para detectar rootkits MEP. Su esencia radica en el hecho de que la misma información se registra de varias maneras: utilizando la API y "directamente", después de lo cual se comparan los datos recibidos en busca de discrepancias. Las tablas de importación y las tablas de llamadas de la API nativa se exploran con mayor frecuencia , así como estructuralmente todo el sistema de archivos.
El arsenal básico de herramientas de captura de rootkits se basa en los siguientes métodos.
diccionarios y enciclopedias | |
---|---|
En catálogos bibliográficos |
Software malicioso | |
---|---|
Malware infeccioso | |
Ocultar métodos | |
Malware con fines de lucro |
|
Por sistemas operativos |
|
Proteccion |
|
contramedidas |
|