Rootkits: Funcionamiento Interno.

Articulo publicado en el 2008 en el cual abordo el tema que será retomado en futuros post’s:

Hoy abordaré otro interesante tema: los rootkits, el tema es trillado así que brincaré definiciones y ejemplos ficticios de su utilización para pasar directamente al funcionamiento interno de estas importantes herramientas, las cuales no solo funcionan como troyanos a nivel kernel: su importante uso compromete el sistema de manera irreparable, por ello es de suma importancia conocer su funcionamiento no solo para lograr defendernos… sino para lograr alterar su composición básica y lograr la mutación adecuada asegurando el acceso al sistema comprometido en distintas ocasiones.

Para esto me centraré en los rootkits que tienen como target principal los sistemas Windows. La actividad básica que realiza un rootkit para su correcto funcionamiento son la desactivación del registro de sucesos en el sistema para un usuario determinado (Administrator) refiriendose a la auditoria interna, permite el acceso al sistema como administrador utilizando un usuario/contraseña oculto. Desactiva de manera directa la seguridad mediante la aplicación parches en el kernel, tratandose esta, la acción mas disruptiva y sensible en la manera de operar de todo rootkit. Mediante estas actividades se asegura que el sistema vulnerado podrá ser accesado de nuevo por el intruso, sin que este de señales de alerta.

Para llevar a cabo estas tareas un rootkit posee un conjunto de herramientas las cuales son capaces de sustituir los archivos binarios por otros troyanizados, esto no es dificil de creer pues un rootkit se ejecuta una vez obtenida la cuenta de Administrador, lo cual permite sobreescribir y manipular los ejecutables del sistema.

Ahora bien, para lograr su cometido todo rootkit primero requiere ocultarse al sistema fuente. para ello realiza la captura de funciones a nivel sistema (INT2Eh). Las llamadas indispensables que se capturan para después troyanizarlas son las siguientes:

– ZwCreateFile
– ZwOpenFile
– ZwQueryDirectoryFil e
– ZwOpenProcess
– ZwQuerySystemInform ation

A nivel programación esto se logra en la gran mayoria de los casos con ansi C incrustando código ASM donde este último es el verdadero malicioso, este es un fragmento de código con el cual se realiza una captura de una llamada a sistema:

mov eax, 0x0000001A
lea edx, [esp+04]
int 0x2E
ret 0x2C

donde:

EAX –> Es el identificador de la funcion.
EDX –> Es un puntero a los parámetros en la stack.

Básicamente se deposita la dirección base de la IDT en la localización especificada en el segundo parámetro indicado por esp, a partir de la base se puede indexar el descriptor de una interrupción, manipulando su selector y su desplazamiento. Una vez alcanzado este nivel de privilegios, el sistema depende por completo de los descriptores y sus posibles desplazamientos llevados a cabo por el rootkit mediante el programa especifico destinado para esta función.

Las APIs de KERNEL32 son un envoltorio entorno a las APIs de NTDLL, mucho más primitivas. Por lo tanto cada servicio del sistema posee un identificador.

12bit > Identificador del servicio.
2bit > Tabla de servicios a emplear.
0 > Servicios del núcleo (NTDLL).
1 > Servicios del entorno gráfico (WIN32K).
2 y 3 > No se emplean.
18bit > Reservados

este identificador es utilizado por el rootkit para manipular e interceptar el servicio objetivo, para ello el código de una función comienza cargando dicho identificador del servicio en EAX, sabiendo esto de antemano la línea básica para lograr esto sería:

MOV EAX,id ; A5h XX XX XX XX

Ahora bien, cual es el verdadero proposito de todos estos conceptos? pongamos un ejemplo práctico, supongamos que deseamos ejecutar Vanquish Rootkit en un sistema Windows Server Enterprise 2003 R2, recién parcheado por el administrador de sistemas y puesto a disposición de un IPS, que pasaría al tratar de instalar nuestro rootkit? quizá la instalación procederia sin ningún problema pues el IPS entra en acción una vez que el los ejecutables que forman el rootkit comienzan a aplicar el payload, una vez instalado sería inútil pues Vanquish realiza la captura de las funciones del sistema alterando la tabla de servicios, para evitar esto Microsoft decidio denegar el acceso a la escritura a partir de Windows XP el cual es el sistema mas atacado pues es un blanco mas común entre intrusos. La versión Server de windows 2003 es una versión mucho mas robusta y modular de este SO que permite la ejecución de llamadas a sistema permitiendo sobreescribir el id de urgencia, pues son equipos que regurlarmente son conectados a otros equipos de storage. Los cuales requieren altos privilegios cuando realizan replicaciones relacionadas no solo con el storage sino también con el SO.

Debuggeando un poco un agente de storage podemos percatarnos que en algunos casos, estos desactivan la protección de escritura en el registro de control CR0 para realizar funciones de mantenimiento, esto  «supuestamente» es información confidencial de los fabricantes, pero al instalar dichos agentes es bastante predecible que lo hacen pues tratandose de storage de alto rendimiento Hitachi, EMC y SUN apuestan a la constancia en linea de sus equipos de storage que a la seguridad aplicativa/abstractiva… debuggeando un poco un agente de storage del cual guardaré su confidencialidad, encontramos lo siguiente:

#define WPOFF() \
_asm mov eax, cr0 \
_asm and eax, NOT 10000H \
_asm mov cr0, eax

#define WPON() \
_asm mov eax, cr0 \
_asm or eax, 10000H \
_asm mov cr0, eax

*Obtenido con CDB.

Esto es, la desactivación de la protección y escritura del registro de control CR0, basta crear las macros para su ejecución y despues modificar a nuestro gusto la tabla de servicios de la siguiente manera:

DbgPrint( ( «GKit: HookSystemService() Hooking SST %x Index %03x Old %08x\n»,
ulSST, ulIndex, ( ULONG) pfnOldHandler)) ;
__try
{
WPOFF() ;
pfnOldHandler = InterlockedExchange Pointer( pfnHandler, pfnNewHandler) ;
WPON() ;
DbgPrint( ( «GKit: HookSystemService() Done\n»));
//Si funciona
}
__except( EXCEPTION_EXECUTE_H ANDLER)
{
pfnOldHandler = pfnHandler ;
DbgPrint( ( «GKit: HookSystemService() Hook failed – can’t write\n»)) ;
//No funciona
}

No trataré de explicar el código anterior pues es muy predecible y esta no es el objetivo de este paper, empero, basta observar la función hook con la cual se parchea la tabla. Esto es lo que haría un rootkit luego de desactivar los registros de control, los cuales, en muchos sistemas se encuentran desactivados por software propietario de storage los cuales en algunas ocasiones hay que conocerlos para simplificar nuestro trabajo.

De esta manera un rootkit toma control del sistema, es importante conocer estos conceptos básicos para dejar de ser simples usuarios que al obtener un error de ejecución opta por cambiar de aplicación, en lugar de comprender el porque de ese error y cual es su posible solución.

Esto nos da un doble valor agregado… es mas probable que un rootkit se ejecute correctamente en un servidor de alto rendimiento que un equipo windows XP con todos los hotfix aplicados al día, debido a la gran cantidad de aplicaciones tipo socket controladores que poseen. Y, si tomamos en cuenta que en la actualidad los «agentes» (un simple socket) trabajan por UDP entre servidores que alcanzan la red externa de las empresas (discos por iscsi, servidores front-end con bases en oracle atacheadas a storage comunicado por agentes etc etc, pues se trata de una necesidad BASICA), se puede observar que el campo de posibles sistemas vulnerables a este tipo de accionar es muy amplio. Solo basta saber en donde buscar y como hacerlo. Por ejemplo: Operation Manager… software que sirve para obtener información acerca de la topología e infrastructura a nivel aplicativo y de storage en toda un red… trabaja por los puertos 8752 y 8753 de manera predeterminada para los sistemas hitachis UPS y estos a su vez poseen una consola basada en Windows 2000… el campo es muy amplio, obvio Vanquish es un rootkit antiguo, conseguir rootkits actuales no es imposible.

Fuí muy breve pues es muy dificil tratar de explicar todas y cada una de las acciones que toma en cuenta un rootkit para asegurar el sistema a un intruso, pero creo que los aspectos básicos de funcionameineto fueron abordados de manera concreta.

Saludos y espero haberme explicado correctamente.

Deja un comentario