El troyano ha sido probado con éxito en diversas distribuciones: Fedora, Arch Linux, Gentoo, Debian entre otras.
Una
de las técnicas tradicionales para evitar su análisis por parte de las
compañías antivirus es la detección de máquinas virtuales, esto es,
cuando el troyano se está ejecutando en un entorno virtualizado su
comportamiento pasa a ser inocuo o directamente finaliza su ejecución de
manera prematura. 'Hand of the Thief' detecta máquinas virtuales
VirtualBox, VMware, Power VM, IBM/S390, QEMU y Xen.
No vamos a describir aquí el comportamiento de este troyano, ya que
esto daría para otro post y además existe un excelente análisis
aquí.
Lo que vamos a ver son técnicas concretas que podemos usar para
esconder el entorno de virtualización, en concreto VirtualBox. Primero
introduciremos los términos que vamos a usar y posteriormente veremos
como el troyano intenta detectar la virtualización y como podemos evadir
dicha funcionalidad.
Definiciones
Las técnicas rootkit permiten ocultar la presencia de un malware,
explotar vulnerabilidades y escalar privilegios en un sistema (cuanto
más altos, mayor control sobre el sistema). Un rootkit puede cargarse
tanto en espacio de usuario como en el espacio del kernel (donde
siempre tendrá más control).
Una llamada al sistema o
system call, es una función que se
efectúa en el espacio de usuario para transferir momentaneamente el
control al kernel a través de una interrupción. Podemos ver una lista
de las llamadas al sistema realizadas por un proceso a través del
programa
strace.
El funcionamiento de una llamada al sistema es sencillo: Un proceso en
espacio de usuario necesita ejecutar una llamada al sistema, mete en
la pila su índice, parámetros y ejecuta una interrupción a través del
código ensamblador
INT 0x80. En ese momento el
kernel
recoge dicha petición, busca en el índice la función correspondiente,
la ejecuta con los parámetros provistos por el usuario y retorna el
resultado y el control de ejecución al proceso del usuario.
Un
driver es un módulo del
kernel. Un programa inyectado en el espacio del
kernel
teniendo acceso tanto a dicho espacio como al espacio del usuario.
Dispone de una variedad de instrucciones más amplia que un proceso de
usuario debido a los privilegios que dispone. Un módulo se carga en el
kernel con el comando
insmod o
modprobe y se desinstala con
rmmod.
Evitando la detección
Para detectar la máquina virtual VirtualBox, el troyano prueba la presencia de la cadena "VBOX" dentro del archivo
"/proc/scsi/scsi" que lista los discos SCSI usados (disco duro, disco de DVD, etc.). Si lo encuentra, el troyano termina su ejecución. Como
dijo
P. Kalni, podemos evitar esta prueba quitando el modo lectura de este
archivo para que el troyano no pueda leerlo. Sin embargo, este método
es limitado y no puede generalizarse a otro troyano ya que éste podría
probar si el archivo esta en modo lectura. Nuestra solución implica el
uso de un rootkit para modificar el contenido del archivo leído. Es
decir, que cuando el troyano lea el archivo, el rootkit va a buscar la
cadena VBOX y la reemplazará por otra cadena. De esta manera,
modificamos el contenido leído al vuelo y no el archivo. En este
ejemplo, modificamos la cadena VBOX por "____".
Cuando un programa lee un archivo, llama a la system call "read" de la
biblioteca libc que ejecuta la función del kernel "sys_read" a través
de la interrupción 0x80. En otras palabras, para modificar el contenido
al vuelo de un archivo leído se necesita hookear la función del
espacio de usuario "read" o del espacio del kernel "sys_read". Hemos
elegido hookear la función del kernel porque el programa podría escapar
del hook de la función "read" llamando a la función "sys_read"
directamente. Además, hookear la función "read" supone que el malware
use la biblioteca libc para leer un archivo.
Hookear la función "sys_read" significa cambiar el modo lectura de la
tabla de llamadas al sistema para poder escribir y cambiar el index en
dicha tabla de la función "sys_read" para redireccionarla a nuestra
función "new_sys_read". Hemos creado un driver para hookear la función
"sys_read" y crear la nueva función "sys_new_read". Cuando la función
"new_sys_read" sea llamada, ella va a (1) llamar a la función original
"sys_read" para recoger una parte del archivo o la totalidad del archivo
en un búfer, (2) reemplazará cada cadena VBOX por "____" del búfer y
(4) devolverá el búfer modificado.
Sin embargo, necesitamos conocer la dirección de la función "sys_read" para llamarla desde
"new_sys_read",
conocer la dirección de la tabla de llamadas al sistema para modificar
la entrada "sys_read", y también la dirección de la función
"lookup_address" que nos permite obtener la página correspondiente a la
tabla de llamadas al sistema para cambiarla del modo lectura y
escritura. Estas direcciones variarán de un sistema a otro. Se pueden
encontrar en el archivo
/boot/System.map.
Esto es solo una de las múltiples técnicas que podemos emplear para
evadir este tipo de detecciones. Por supuesto, ni es la única técnica
que emplean los troyanos para evadir la ejecución sobre una plataforma
virtualizada, ni es la única contramedida de las que disponemos.
Fuente:
Hispasec