Rootkits
Hace algunos días asisti a una charla que dio runlvl, acerca de rootkits en procesadores Intel x86 en la Universidad de Belgrano, con motivo de las Jornadas Regionales de Software Libre, la verdad que fue un tema mas que interesante y por tal motivo escribire en este post un breve resumen de la misma.
¿Qué es un rootkit?
Según la sabia Wikipedia, un rootkit es:
Es una herramienta, o un grupo de ellas que tiene como finalidad esconderse a sí misma y esconder a otros programas, procesos, archivos, directorios, llaves de registro, y puertos que permiten al intruso mantener el acceso a un sistema para remotamente comandar acciones o extraer información sensible, a menudo con fines maliciosos o destructivos. Existen rootkits para una amplia variedad de sistemas operativos como Linux, Solaris o Microsoft Windows.
Un rootkit se usa habitualmente para esconder algunas aplicaciones que podrían actuar en el sistema atacado. Suelen incluir backdoors (puertas traseras) para ayudar al intruso a acceder fácilmente al sistema una vez que se ha conseguido entrar por primera vez. Por ejemplo, el rootkit puede esconder una aplicación que lance una consola cada vez que el atacante se conecte al sistema a través de un determinado puerto. Los rootkits del kernel o núcleo pueden contener funcionalidades similares. Un backdoor puede permitir también que los procesos lanzados por un usuario sin privilegios de administrador ejecuten algunas funcionalidades reservadas únicamente al superusuario Todo tipo de herramientas útiles para obtener información de forma ilícita pueden ser ocultadas mediante rootkits.
Los rootkits se utilizan también para usar el sistema atacado como “base de operaciones”, es decir, usarlo a su vez para lanzar ataques contra otros equipos. De este modo puede parecer que es el sistema inflitrado el que lanza los ataques y no el intruso externo. Este tipo de ataques podrían ser de denegación de servicio (DoS), ataques mediante IRC o mediante correo electronico (spam).
Bien teniendo ya los conocimientos necesarios comenzaremos a hablar especificamente de este rootkit en procesadores Intel x86.
System Management Mode
Extraido del manual de Intel:
El system management mode, SMM, es tipicamente usado para ejecutar rutinas especificas de manejo de energia ( power management ) luego de entrar en el SMM varias partes del sistema pueden ser apagadas o deshabilitadas para minimizar el consumo de energia.
El SMM opera independientemente de otros sistemas de software y puede ser usado para otros propositos tambien.
Cuando leemos algo como “y puede ser usado para otros propositos” nosotros
nos ponemos a pensar: WTF? Cuales son esos otros propositos?.
Es interesante que cualquier mapeo de busqueda en internet sobre SMM apunta solamente a manejo de energia y no dice absolutamente nada sobre estos otros propositos.
Los modos de operación de la familia de procesadores P6 a grandes rasgos son los siguientes:
(Mas info: hxxp://www.intel.com/design/Pentiumii/manuals/244001.htm)
- El modo real: es un modo de direccionamiento de 16 bit, guardado para compatibilidad y estos dias solo usado en el proceso de booteo.
- El modo protegido: es un modo de 32 bit y provee de un modelo de proteccion para los sistemas operativos modernos.
- El modo virtual 8086: fue introducido para garantizar eficiencia cuando corremos programas creados para viejas arquitecturas ( como 8086 y 8088 ).
- El System Management Mode ( SMM ): es otro modo de operación, como bien dijimos en la diapositiva anterior se supone que debe ser utilizado para funciones de manejo de energia.
Cuando el sistema entra a SMM, todo el contexto del procesador debe ser grabado de una forma en la cual pueda ser restaurado despues.
Para lograr esto el procesador puede entrar en un modo especial de contexto de ejecucion y ejecutar el SMI handler.
Para retornar desde este modo existe una instrucción especial RSM ( que puede ser usada solo dentro del SMM ) Esto va a leer el contexto grabado y retornar a la situacion previa del procesador.
El paginamiento en el modo SMM en deshabilitado y solo disponemos de un modo de operación de 16 bit, pero toda la memoria fisica puede ser direccionada. ;-)
No existen restricciones de puertos de E/S o memoria, asi que tenemos los mismos privilegios que en el RING 0 ( de hecho, desde el modo SMM alguien podria manipular toda la memoria del sistema )
Lo que en teoria se puede hacer es poner nuestro propio SMI handler forzar al procesador a entrar en modo SMM, cambiar la memoria del sistema para “bypassear”
una proteccion de seguridad y ejecutar nuestro codigo guardando nuestro propio contexto y apuntandolo para restaurarlo.
El System Management Mode tiene su propia zona de memoria dedicada, llamada como no podia ser de otra forma, SMRAM.
Esta alojada en 0×1FFFF bytes, empezando en SMBASE ( puede ser mayor si el sistema activa memoria extendida )
El valor por default para SMBASE es 0×30000, pero en chipsets modernos ofrece realojamiento. Esta comunmente visto en 0xA0000 ( osea que el BIOS realoja esta a la misma base de memoria mapeada a las direcciones utilizadas para los puertos de E/S de la placa de video )
El hub controlador de memoria, tiene un control de registro llamado “SMRAM Control Register” ( siempre nombres intuitivos :-P ) que ofrece un bit D_OPEN bit 6, que cuando es seteado hace que todo acceso a ese espacio de memoria, empezando en SMBASE, sea redirigido a SMRAM.
Por otra parte, si el procesador no esta en modo SMM y el bit de D_OPEN no esta seteado, todo acceso a la memoria SMRAM sea forwardeado a la placa de video, dandonos una proteccion al SMRAM, que puede ser utilizado para proteger el malware.
Otra cosa importante hacerca del handler es el bit numero 4 D_LCK, que cuando es seteado protege a la SMRAM.
Cuando esta seteado el bit D_OPEN se necesita alguna forma de evitar el uso del display porque todo acceso a la memoria de video va a ser forwardeada a la SMRAM y no a la placa de video. Se puede manipular los registros directamente usando libpci para garantizar que no haya problema con esto, descartando condiciones de carrera en el uso de recursos.
Tambien es mas portable porque libpci soporta diferentes tipos de sistemas operativos.
Entonces para insertar el handler se necesitaria:
- Verificar si el bit D_LCK no esta seteado
- Setear el bit D_OPEN
- Tener acceso de superusuario
- Tener acceso al espacio de direccion de memoria 0xA0000 – 0xBFFFF
Para acceder a la memoria podemos mapear los rangos usando el dispositivo /dev/mem
porque este provee acceso al espacio de memoria fisica. ( Nada que ver con la vision de memoria virtual mostrada en /dev/kmem )
Desde la señal SMI es una interrupcion generada por hardware, no hay instrucción para generarla por software, el chipset puede generarla, pero esto depende exclusivamente del
chipset.
Peeero… el SMI_STS guarda un track de cual dispositivo causo el ultimo SMI.
Estos registros pueden ser accedidos utilizando un mecanismo comun PCI, entrada y salida.
La posicion de estos registros es variable, pero estos pueden ser encontrados en las direcciones de PMBASE ( SMI_EN=PMBASE+0×30 y SMI_STS=PMBASE+0×34 )
El PMBASE puede ser accedido usando el bus 0, dispositivo 0×1F, funcion 0 y offset 0×40
Para mas detalles de las configuraciones y mecanismos PCI: Google.
Por ejemplo:
if(iopl(3) < 0 ) {
Para obtener acceso a la SMRAM, el D_OPEN tiene que estar seteado:
outl(data1, 0xcf8);
outl(data2, 0xcfc);
Que esto se puede hacer asi:
addr32 mov $test. %eax
mov %eax, %cs:0xfff0
( Ahora ejecutando la funcion test() )
Osea que accediendo a la E/S del puerto 0xB2 con el bit 5 del SMI_EN seteado vamos a generar un SMI
out(0x000000f, 0xb2);
Definitivamente es gracioso, pero que mas podemos hacer con esto?
La idea de utilizar el SMM para manipular la memoria del sistema puede ser realmente expandida para crear un malware corriendo dentro del SMM, o para bypassear las protecciones de booteo y muchas otras mas, como crear un sistema de proteccion corriendo dentro del propio malware.
Se puede aclarar algunos detalles importantes acerca de SMM y como funciona, esto puede ser muy importante para entender su desempeño y para analizarlo se puede utilizar libpci.
Es de gran ayuda entender el uso y funcionamiento de PCI.h y IO.h y por supuesto STDIO.h.
Cuando el procesador entra en modo SMM, este va a enviar un ping de señal aSMIACT#, para notificar al chipset que el procesador entro en modo SMM. La interrupcion SMI puede ser accedida en cualquier momento excepto cuando el procesador esta en modo SMM ( obvio ).
Esto va a causar que se ejecute el handler SMM ( osea el xploit ).
Desde que el SMIACT# es notificado por el chipset, toda memoria accedida sera redirigida a la memoria protegida SMRAM, despues de esto el procesador va a empezar a grabar el estado de la memoria interna en el SAVED_STATE MAP, adentro del SMRAM, entonces el handler empieza a ejecutarse.
Como dijimos, para salir del modo SMM la instrucción RSM es notificada por el handler y el procesador lee el SAVED_STATE MAP y restaura el sistema a la situacion previa.
El modo SMM escribe datos en el SAVED_STATE MAP exactamente igual que un stack ( pila ) lo hace, desde arriba hacia abajo, empezando por los registros SMBASE, estos permiten realojamiento y esto es importante saberlo cuando estamos manipulando el SAVED_STATE MAP.
Si el sistema entra en modo SMM por resultado de un halt o una instrucción de E/S el handler puede decirle al sistema que continue la ejecucion despues de entrar en el estado halt solo seteando un flag ( bandera ) en el SAVED_STATE MAP.
Se recomienda que para hacer cualquier tipo de prueba de realojamiento del SAVED_STATE MAP se utilicen maquinas antiguas tipo Pentium II / III porque no existe proteccion del SMM hecha por el BIOS, generalmente BIOS de 3 o 4 años de antiguedad.
Pero para obviar esta verificacion esto puede ser bypasseado si utilizamos un hook sobre la rutina del handler, asi esta rutina puede ser ejecutada inmediatamente despues del RSM y antes que el procesador empiece a apuntar codigo al SAVED_STATE MAP.
El SMM es hardware dependiente, el codigo podria funcionar si utiliza libpci, se supone que deberia de funcionar tanto en FreeBSD, OpenBSD, Solaris, Aix, GNU/Hurd, Microsoft Windows, GNU/Linux.
Mas información:
- Manual de Arquitectura INTEL:
hxxp://www.intel.com/products/processor/manuals/index.htm - LibPCI:
fxp://ftp.kernel.org/pub/software/utils/pciutils/ - GPLed: librerias que pueden mostrar algun tipo de manipulacion acerca de SMM, prestaciones,
acompañadas de algunos programas mostrando ejemplo de uso.
hxxp://stjude.sf.net

