sábado, 24 de enero de 2009

Perl, MD5 y los drivers sospechosos de Windows

En Windows, los drivers que normalmente están alojados en

c:\windows\system32 y

c:\windows\system32\drivers,

pueden ejecutarse en el espacio de memoria del núcleo y por tanto, pueden hacer lo que quieran en el sistema. Estos archivos suelen tener la extensión .sys, y normalmente no se les presta atención.

Hay drivers que ya los pone Windows, otros se alojan ahí cuando instalamos algún dispositivo, y hasta hay programas que también dejan ahí su .sys para hacer cosas. Los virus también los utilizan para sus cometidos, y con más frecuencia que lo que creemos.

Se inicie el driver o no al encender el ordenador dependerá si el driver es llamado desde el registro. Para ver esto, aconsejo autoruns de Sysinternals.

A veces es difícil saber si un .sys es de fiar o no, aunque consultemos en la red. Una forma de averiguarlo es, si sospechamos de alguno, crear una carpeta en la misma carpeta donde se aloja el driver y moverlo ahí. Después reiniciamos y a ver que pasa. Si hemos movido un driver crítico del sistema, seguramente nos toque arrancar con un live-cd y volver a poner el driver en su ubicación original. Sino ocurre nada, podemos esperar a ver que pasa, y si sigue sin pasar nada, pues lo mismo ese driver no se usa.

Si da la casualidad de que hemos movido un driver que es utilizado por algún virus u otro programa malicioso, es posible que, si el virus está en memoria, lo vuelva a crear incluso con otro nombre, y aquí es donde entra el

MD5

El MD5 de un archivo es un resumen del contenido del archivo y además es único para ese archivo. Lo bueno es que ese resumen sólo ocupa 32 dígitos hexadecimales (128 bits), ocupe lo que ocupe el archivo. De esta forma, con estos 32 dígitos podemos verificar la integridad de un archivo.

Si hemos apartado los drivers sospechosos a una carpeta llamada "sospechosos", podemos calcular el MD5 de cada uno y crear un archivo de texto donde cada línea tendrá el nombre del archivo y su MD5. Después, si alguno de estos drivers sospechosos es el resultado de un virus y éste vuelve a crear el driver, aunque sea con otro nombre, para identificarlo podemos comparar los MD5 sospechosos que contiene nuestro archivo de texto con los MD5 de los archivos de las carpetas de sistema de Windows (system32 y system32\drivers) hasta que salte la coincidencia. Si el nuevo driver tiene otro nombre y el mismo MD5, se trata de un virus seguro.

Entrando en harina

Primero vamos a hacer un pequeño script en perl llamado md5.pl para sacar los MD5 de un archivo dado:

------- comienzo md5.pl -----------------------------------------------
# ramiro.encinas@gmail.com - 2009
# Tuya es la responsabilidad del buen o mal uso de este script

use Digest::MD5::File qw(file_md5_hex);

if ($ARGV[0]) {$archivo = $ARGV[0];}
else {print "\n";print "Sintaxis: perl md5.pl nombre_archivo.\n";exit;}

if ( -e $archivo )
{
    $md5 = file_md5_hex($archivo);
    print "\n";print "El MD5 de $archivo es: $md5\n";
}
else {print "\n";print "Sintaxis: perl md5.pl nombre_archivo.\n";exit;}
------- fin md5.pl ----------------------------------------------------


Con este script podemos sacar los MD5 de los archivos sospechosos. Después, en la carpeta de trabajo, creamos un archivo de texto llamado drivers-sospechosos.txt, donde cada línea contendrá cada nombre de archivo sospechoso y su MD5 correspondiente. Para separar el nombre del archivo y su MD5 utilizaremos "::" como vemos en este ejemplo:

data.sys::ee2f07a2d1f81e2f5a8a454f61d9395a

Cuando tengamos drivers-sospechosos.txt lleno con los archivos (drivers) sospechosos y sus MD5, y además tengamos movidos dichos archivos a la carpeta "sospechosos", podemos esperar unos días y ejecutar el siguiente script que realizará la búsqueda-comprobación:

------- comienzo drivers-sospechosos.pl ----------------------------------------

# Los drivers sospechosos de c:\windows\system32 y c:\windows\system32\drivers
# han sido movidos a la carpeta "sospechosos" que está en la misma carpeta donde
# estaba el driver sospechoso.

# Cada uno de los nombres de estos drivers sospechosos junto con su MD5 están en
# una línea de drivers-sospechosos.txt, y éste archivo está en la carpeta de trabajo.

# Este script busca los MD5 de los archivos de drivers-sospechosos.txt
# en c:\windows\system32 y c:\windows\system32\drivers
# para comprobar si existe alguna coincidencia.

# Este script asume que la carpeta de trabajo es 
# C:\WORKSPACE\drivers-sospechosos 
# y que dentro está el archivo drivers-sospechosos.txt con los nombres y MD5 
# de los archivos sospechosos, uno por línea y este mismo script, claro.

# Este script también asume que por cada línea de drivers-sospechosos.txt hay
# un nombre de driver sospechoso, una separación "::" y su MD5.

# ramiro.encinas@gmail.com - 2009
# Tuya es la responsabilidad del buen o mal uso de este script

use Digest::MD5::File qw(file_md5_hex);

# Ubicación del archivo con los archivos sospechosos

$path_filein = "C:\\WORKSPACE\\drivers-sospechosos\\drivers-sospechosos.txt";

# Función principal

sub todo 
{
    # Apertura drivers-sospechosos.txt
    open f_drivers, $path_filein or die "No puedo abrir $path_filein";
    $c = 0; #Número de coincidencias
 
    while( ) # Abro drivers-sospechosos.txt y lee línea a línea
    {
        chomp $_; # Quita el fin de línea, que si se queda esto no funciona
  
        $_ =~ /(.*)::/; # Extrae el nombre del archivo 
        $filein = $1; # y lo pone en $filein
  
        $_ =~ /::(.*)/; # Extrae el MD5 del archivo 
        $fileinmd5 = $1; # y lo pone en $md5
  
        $path = "C:\\WINDOWS\\system32\\"; 
        proceso($path,$filein,$fileinmd5); # Búsqueda en system32
  
        $path = "C:\\WINDOWS\\system32\\drivers\\";  
        proceso($path,$filein,$fileinmd5); # Búsqueda en drivers
    }
    close f_drivers; # Cierra drivers-sospechosos.txt
    print "\n";
    print "Coincidencias: $c\n"; # Muestra número de coincidencias
}
 
# Función de búsqueda por cada $path

sub proceso($path,$filein,$fileinmd5) 
{
    opendir DIRECTORY, $path or die; # Abre la carpeta $path
 
    # Recorre $path y deja en $file cada nombre de archivo
 
    while ($file = readdir(DIRECTORY)) 
    {  
        if ( -d $path.$file ){# $file es un directorio}
        else # $file es un archivo
        {  
            $filemd5 = file_md5_hex($path.$file); # Calcula el MD5 de $file
   
            if ($filemd5 eq $fileinmd5) # Si los MD5 coinciden, premio
            {
                print "\n";
                print "Cuidadito, $path$file tiene el mismo MD5 que $filein.\n";
                $c++;
            }
        }
    }
}

todo();

------- fin drivers-sospechosos.pl ---------------------------------------------

Este proceso normalmente tarda un buen rato, así que podeis ir a preparar un café y esperar a que a la vuelta no haya premio.

No hay comentarios: