Tuesday 20 April 2010

Script para comprobar la integridad de procesos en Debian GNU/Linux

Hola,

Desde que me uní al Ethical Hacking Team de IBM y me vine a vivir a Dublín, he andado bastante liado y no he dedicado mucho tiempo a postear en el blog ni en twitter, cosa que voy a intentar cambiar poniendome rápidamente al día. Por aqui todo anda de maravilla :)

Hoy, quiero compartir un script que escribí cuando leí un post de @secbydefault sobre cómo comprobar la integridad de procesos en sistemas basados en rpm (tales como RedHat o CentOS). Lo que hice básicamente es migrar el script que proponían de sistemas RedHat a Debian debido a que varias personas dejaron comentarios en el post interesadas en una versión para Debian y a mi también me interesaba disponer de una versión funcional que funcionara correctamente en mi sistema.

Lo primero es comentar que haciendo unas pruebas, el script propuesto por @secbydefault falla en ciertas situaciones. Si un atacante en lugar de modificar un binario lo que hace es eliminarlo del sistema de ficheros directamente, el script no parsea adecuadamente los nombres de los binarios. Esta sería la entrada que tomaría el script en caso de que eliminaramos un binario:

$ perl procy.pl 
/sbin/init
(deleted) /usr/sbin/apache2
/bin/bash
(deleted) /usr/sbin/apache2
/bin/bash
(...)
etc

Como se puede ver el script extrae como nombre de binario en caso del proceso de apache2 "(deleted) /usr/sbin/apache2" lo cual es incorrecto. Este fallo, podemos arreglarlo aplicando este fix; modificar las siguientes dos líneas (correspondientes según este link a la 22 y 24):

$status =~ /-> (.*)$/;
my $binary = $1 ;

a:

$status =~ /->( \(.*\))? (.*)$/;
my $binary = $2 ;  

Nota: Avisé a @secbydefault por aquel entonces sobre estos detalles y quedaron en actualizarlo pero nunca lo hicieron.
UPDATE: ya han actualizado la entrada en SbD, gracias!

En mi caso, para migrarlo a Debian he traducido el script de perl a bash script, ya que me siento más cómodo con este lenguaje, y usando bash ha quedado bien sencillo :)

El objetivo es encontrar procesos ejecutandose en la máquina cuyos binarios se hayan modificado, para conseguirlo el funcionamiento básico del sistema es en primer lugar listar los procesos de la máquina mediante ps, a través de /proc/[pid]/exe extraer la ruta del binario en el filesystem y realizar un dpkg -S  para ver en que paquete se encuentra, para seguidamente aplicar debsums y comprobar la integridad del fichero.


El script para debian hace uso del paquete debsums, el cual se encarga de comprobar la integridad de los ficheros instalados en el sistema por los paquetes mediante sumas de comprobación MD5.

Un paso necesario antes de usar este script es instalar el paquete debsums y generar las firmas md5, para esto tan sencillo como lanzar el siguiente comando desde usuario root:

apt-get install debsums && debsums_gen

Veamos un ejemplo de ejecución en el cual he eliminado (de forma intencionada) el binario /usr/sbin/apache2 y he modificado el binario /usr/sbin/named:

$./procy.sh
El proceso [ 11569 /var/ossec/bin/ossec-maild ] no pertenece a ningún paquete

El proceso [ 11573 /var/ossec/bin/ossec-execd ] no pertenece a ningún paquete

El proceso [ 11577 /var/ossec/bin/ossec-analysisd ] no pertenece a ningún paquete

El proceso [ 11580 /var/ossec/bin/ossec-logcollector ] no pertenece a ningún paquete

El proceso [ 11584 /var/ossec/bin/ossec-syscheckd ] no pertenece a ningún paquete

El proceso [ 11588 /var/ossec/bin/ossec-monitord ] no pertenece a ningún paquete

El proceso [ 23557 /usr/sbin/named ] ha sufrido modificaciones en su paquete base (bind9): /usr/sbin/named                                                           FAILED

El proceso [ 23815 /usr/sbin/apache2 ] ha sufrido modificaciones en su paquete base (apache2-mpm-prefork): debsums: can't open apache2-mpm-prefork file /usr/sbin/apache2 (No existe el fichero o el directorio)

El proceso [ 6570 /usr/sbin/apache2 ] ha sufrido modificaciones en su paquete base (apache2-mpm-prefork): debsums: can't open apache2-mpm-prefork file /usr/sbin/apache2 (No existe el fichero o el directorio)


El proceso [ 6998 /usr/sbin/apache2 ] ha sufrido modificaciones en su paquete base (apache2-mpm-prefork): debsums: can't open apache2-mpm-prefork file /usr/sbin/apache2 (No existe el fichero o el directorio)

El script detecta que hay unos binarios que no pertenecen a ningún paquete (pertenecen al software OSSEC, un HIDS Open Source, y es debido a que se instaló de forma manual), también detecta que el binario named se ha modificado y que el binario de apache2 se ha eliminado. Por lo tanto cumple su función, por supuesto es muy sencillo y se puede mejorar con más detalles, los comentarios son bienvenidos.

El código es el siguiente:



Descarga del script para Debian GNU/Linux


Espero que os sea útil.