lunes, 25 de agosto de 2014

Creando firmas de virus para ClamAV

ClamAv es un antivirus opensource y multiplataforma creado por Tomasz Kojm muy utilizado en los servidores de correo Linux. Este antivirus es desarrollado por la comunidad, y su utilidad práctica depende de que su base de datos de firmas sea lo suficientemente grande y actualizado. Para ello es necesario que voluntarios contribuyan activamente aportando firmas.
El presente artículo pretende describir de manera sencilla cómo crear firmas de virus para ClamAV y contribuir con ellas a la comunidad.



Los archivos de firma de ClamAV habituales son main.cvd y daily.cvd. En realidad son archivos comprimidos que contienen los auténticos ficheros de firmas. Para obtener información sobre el archivo podemos usar la utilidad sigtool con la opción -i.


sigtool -i daily.cvd


Si queremos ver los ficheros de firmas podemos usar esta misma utilidad con la opción -u para desempaquetar el archivo.


sigtool -u daily.cvd



Podemos observar como hay diferentes archivos con diferentes extensiones. Los más reseñables son los siguientes:

cdb: Contenedor de metadatos.
fp: Base de datos de ficheros buenos conocidos (lista blanca).
hdb: Hashes MD5 de ficheros maliciosos conocidos.
ldb: Firmas lógicas.
mdb: Hashes MD5 de secciones PE de ficheros maliciosos conocidos.
ndb: Firmas en hexadecimal.
rmd: Firmas de metadatos.
zmd: Firmas de metadatos.


Estos archivos contienen las firmas en formato de texto, con lo que podemos fácilmente ver su contenido.


cat daily.hdb


Hay varios tipos de firmas en ClamAV. Las más sencillas son las que se almacenan en los archivos .hdb, cuyo formato es el siguiente:


MD5:tamaño:nombre_malware


Analicemos un ejemplo:


bb14987ca0f354b72ba8433a878d7ca3:9319:Java.Trojan.Agent-32


El primer campo es el hash calculado del fichero malicioso, que tiene 9319 bytes y cuyo nombre (para ClamAV) es Java.Trojan.Agent-32.

Este tipo de firma es el más sencillo, ya que tiene en cuenta todo el fichero. La contrapartida es que es menos flexible. El comando para crear una firma para un supuesto virus que se encuentra en el fichero virus.exe es la siguiente:


sigtool --md5 virus.exe > test.hdb


Seguidamente, podemos ver como es detectado el archivo como virus usando el comando clamscan.


/usr/bin/clamscan -d test.hdb virus.exe



En caso de que estemos seguros de que de que realmente tenemos un malware entre manos, podríamos contribuir a la comunidad de ClamAV con nuestra firma mediante la siguiente URL.

http://www.clamav.net/lang/en/sendvirus/submit-malware/

El siguiente formato de firma que vamos a analizar es el que se almacena en archivos .mdb, en el que la firma se corresponde con una sección de un archivo ejecutable tipo PE (Portable Executable) de Windows. En este caso, la forma de obtener la firma no es tan directa. Para complicar un poco más la cosa, los programas ejecutables, y sobre todo los virus, suelen venir empaquetados con alguna utilidad del tipo UPX o similar.
Para obtener las firmas vamos a utilizar un script en perl llamado PESectionExtractor.pl, y que se puede obtener en la siguiente URL.

http://hexacorn.com/d/PESectionExtractor.pl

Analicemos primero el formato:


tamaño:MD5:nombre_malware


Por ejemplo, la siguiente firma es para una sección PE de 13312 bytes y el nombre del malware es Win.Trojan.Sharik-4.


13312:e80fc496d01e3d36a3c8578c48b3c275:Win.Trojan.Sharik-4


Para obtener la sección PE que nos interesa recurrimos a PESectionExtractor.pl de la siguiente manera.


PESectionExtractor.pl notepad.exe


Este script ha extraído todas las secciones PE del ejecutable. Para generar el hash volvemos a usar sigtool con la opción --md5, pero esta vez sobre la sección que nos interese.


A partir de aquí sólo hay que crear la firma con el formato que acabamos de ver más arriba.

El siguiente tipo de firma que vamos a analizar son las firmas extendidas, almacenadas en los archivos .ndb, y que nos permiten mayor flexibilidad, ya que en ellas no se especifica un checksum, sino directamente una serie de opcodes del malware (si es un ejecutable). El formato de la firma es el siguiente.


nombre_malware:tipo:offset:firma_hexadecimal[:MinFL:[MaxFL]]


Un ejemplo de este tipo de firma puede ser el siguiente.


XML.Exploit.CVE_2013_3137:0:*:3c21646f6374797065{-30}5b203c21656e746974792025{-30}73797374656d20(22|27)687474703a2f2f{-30}2e786d6c(22|27)3e{-30}3b205d3e


El campo tipo puede contener cualquiera de los siguientes valores:

0: Cualquier tipo de fichero.
1: Portable Executable (PE).
2: Componente OLE2 (por ejemplo VBA script).
3: HTML.
4: Archivo de correo electrónico.
5: Archivo gráfico (png, jpg, etc.).
6: Ejecutable tipo ELF.
7: Archivo de texto ASCII.


El campo offset o desplazamiento indica a partir de qué posición del archivo debe darse la coincidencia de la firma. Tiene el siguiente formato.

*: En cualquier posición del archivo.
n: Un número entero que indica la posición absoluta.
EOF-n: Final del fichero menos n bytes.

Además, las firmas para los tipos PE y ELF soportan los siguientes formatos:
EP+n: Entry point mas n bytes (EP+0 para indicar el entry point del programa).
EP-n: Entry point menos n bytes.
Sx+n: Inicio de la sección x mas n bytes.
Sx-n: Inicio de la sección x menos n bytes.
SL+n: Inicio de la última sección más n bytes.
SL-n: Inicio de la última sección menos n bytes.

Finalmente, la firma va en hexadecimal y dependiendo del tipo de fichero, se corresponderá con una serie de opcodes si se trata de un ejecutable o los caracteres en hexadecimal si se trata de un archivo de texto.
Es posible añadir expresiones regulares (wildcards) que tiene el siguiente formato.

??: Coincidencia con cualquier byte.
a?: Coincidencia con el nibble más significativo.
?a: Coincidencia con el nibble menos significativo.
*: Coincidencia con cualquier número de bytes.
{n}: Coincidencia con exactamente n bytes.
{-n}: Coincidencia con n bytes o menos.
{n-}: Coincidencia con n bytes o más.
{n-m}: Coincidencia de entre n y m bytes (m > n).
(aa|bb|cc|..): Coincidencia con aa o bb o cc, etc.
!(aa|bb|cc|..): Coincidencia con cualquier byte excepto con aa y bb y cc, etc.
HEXSIG[x-y]aa o aa[x-y]HEXSIG: Coincidencia con aa adyacente a una firma hexadecimal.
(B): Coincidencia con fin de palabra.
(L): Coincidencia con CR, CRLF fin de fichero.

Los campos opcionales [:MinFL:[MaxFL]] sirven para especificar la máxima y mínima versión del motor de clamav que soporta esta firma.

La forma de obtener la firma es dependiente del tipo de archivo. Si se trata de un fichero de texto podemos usar sigtool para generar la cadena hexadecimal a partir de un texto.


sigtool --hex-dump cadena_caracteres


Para obtener los opcodes de un ejecutables, tendremos que localizar la porción de código característica del malware y usar un desensamblador para obtener los opcodes. En Linux puede usarse objdump.


objdump -d MiMalware


Supongamos que el siguiente código obtenido con objdump fuera descriptivo de un malware.


41d4b3: e8 b8 df fe ff        call   0x40b470
  41d4b8: 8b 7d 08              mov    0x8(%ebp),%edi
  41d4bb: 59                    pop    %ecx
  41d4bc: e9 05 04 00 00        jmp    0x41d8c6
  41d4c1: 8b 45 14              mov    0x14(%ebp),%eax
  41d4c4: 3b c6                 cmp    %esi,%eax


En este caso, la firma hexadecimal podría ser la siguiente.


MiMalware:6:*:e8b8dffeff8b7d0859e9050400008b45143bc6


El último formato de firma que presentamos son los almacenados en los archivos .ldb, que son las llamadas firmas lógicas y cuyo formato general es el siguiente.


nombre_malware;BloqueDescriptorDeObjetivo;Expresión_Lógica;Firma0;Firma1;Firma2;...


La siguiente es un ejemplo de firma lógica.


Unix.Trojan.Hanthie-3;Engine:51-255,Target:0;(0&(1|2));6d792024706964203d20666f726b3b206578697420696620247069643b(0a|20)2430203d2022(70307374666978|756e69782d6461656d6f6e|756e697864)5c3022;5b48616e64206f662054686965665d;2462756666203d20225c7830355c7830305c783030222e247261775f686f73742e247261775f706f72743b


El primer campo corresponde al nombre. En el segundo campo podemos indicar información adicional además de las firmas. En este caso Engine especifica las capacidades que debe cumplir el motor de clamAV y Target está indicando el tipo de archivo (los mismos que los vistos para las firmas extendidas).
Como podemos observar, este formato soporta múltiples firmas separadas por punto y coma (;), y el campo Expresión_Lógica permite especificar como se relacionan estas firmas. Se usan las típicas expresiones lógicas al estilo de C o Java.
En el ejemplo de arriba se usa la siguiente expresión (0&(1|2)), que significa que se debe coincidir con la firma0 Y con la firma1 O la firma2 (una de las dos).

Ya no tienes excusa para que la próxima vez que encuentres un malware o cualquier tipo de exploit te animes a contribuir con la comunidad de este magnífico proyecto.

4 comentarios:

  1. Muy bueno. No es tan fácil conseguir este tipo de información y menos con ejemplos. Gracias.

    ResponderEliminar
  2. Muy buena la información.
    Tengo una inquietud cuales serían las partes de esta firma: HTML.Phishing.Bank-216:3:*:6163636f756e743{-5}a206120726563656e74{-5}20726576696577206f6620796????572206163636f756e??74206465746572
    Agradecería si alguien me puede dar una guia.

    ResponderEliminar