Mostrando las entradas con la etiqueta Upload. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Upload. Mostrar todas las entradas

martes, 4 de mayo de 2010

Revisar archivos con antivirus

En mi publicación anterior comenté como añadir un nivel extra de seguridad al guardar archivos de los usuarios en nuestras aplicaciones, en dicho articulo hablé de las validaciones de contenido, en esta publicación voy a hablar de un nivel mas avanzado de seguridad para que los archivos de los usuarios no signifiquen riesgos para nuestras aplicaciones ni para otros usuarios.


En el cliente donde se implementó el mecanismo de seguridad se plantearon las siguientes alternativas:

1- Guardar el archivo, esperar y ver si existe o no (asumiendo que el antivirus del servidor funciona), esto causa que dependamos que el antivirus del servidor efectivamente revise el archivo que se le hizo upload. Adicionalmente genera un tiempo de espera adicional fijo y existe la posibilidad que la espera sea menor al tiempo necesario por el antivirus.

2- Hacer llamado a un antivirus a través de un componente diseñado para tal fin como http://www.opswat.com/metascan.shtml el cual es pago, pero es una opción que da mucha seguridad

3- Hacer uso de antivirus free que provee API para ser llamado como http://www.wolfereiter.com/antivirus.aspx , pero se tiene el riesgo de la calidad de la detección de virus ya que no es una herramienta muy conocida

4- Utilizar Apis de antivirus como el que ustedes utilizan Symantec Scan Engine, es la opción mas segura ya que se utiliza una herramienta conocida en el mercado por su seguridad, lo malo es que hay que pagar licencia para usar ese api.

La recomendación al cliente fue:

Si se puede invertir dinero a nivel de licencias, recomendamos la opción 2 (licencia core o lite), de segundo recomendamos la opción 4. Si no se desea invertir dinero a nivel de licencias, por el desconocimiento de la confiabilidad del motor de antivirus de la opción 3, recomendamos la opción 1.

El cliente seleccionó la opción 4 ya que poseía ciertas licencias con ese proveedor. En este articulo voy a hablar de la opción de utilizar Symantec Scan Engine

La solución se basa en el uso del protocolo ICAP para mandar requests a un motor de antivirus para que se revise un archivo dado. Básicamente consiste en mandar mensajes con un formato en especifico vía Sockets a un servidor ICAP, en antivirus hace su trabajo y luego nos responde con un mensaje indicando el resultado de la revisión.

En este link pueden ver en detalle la especificación de ICAP para saber como armar los mensajes y como interpretar las respuestas. En este link pueden ver la especificación y ejemplos para Symantec

De este blog saqué el código sobre el cual se basó la solución ofrecida al cliente

Como probarlo sin ponernos en Riesgo?

EICAR, European Institute for Computer Antivirus Research (en español Instituto Europeo para la Investigación de los Antivirus Informáticos), desarrolló lo que hoy es conocido como EICAR test file, o archivo de prueba EICAR.

El EICAR test file sirve justamente para probar la funcionalidad del software antivirus, dándole a éste la oportunidad de detectarlo durante los procesos de escaneo, al mismo tiempo que no implica un riesgo para la seguridad de la computadora en la cuál se efectúa la prueba, sencillamente porque no se trata realmente de un virus.

Los mayores fabricantes de antivirus actuales, lo soportan. De todos modos es importante hacer notar, que no porque un antivirus detecte el EICAR test file, significa que ese antivirus es capaz de reconocer y bloquear todo tipo de código maligno (comúnmente llamado "malware", ya que involucra a todo tipo de software capaz de causar algún daño, y no solo a los virus).

La recomendación es usar el archivo EICAR, simplemente descargalo o genera un nuevo archivo EICAR. El software antivirus (API) debería detectar su presencia como la de un "virus" llamado "EICAR-AV-Test", "Eicar Archivo de prueba" (recordemos que NO es un virus). Ver el siguiente link para mayor información:

El EICAR test file consiste en 68 caracteres ASCII (70 si lo generamos con un editor de texto, debido a los códigos de retorno y final de línea que suelen insertar los editores).

Los caracteres son:
      X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

Todas las letras están en mayúsculas, y sin espacios. El tercer carácter (X5O...) es la letra "O" no el número cero).

Para crear un archivo de prueba, copia y pega la línea anterior al bloc de notas, y graba su contenido con el nombre que quiera y la extensión .COM

También puede descargarlo de las siguientes direcciones. El formato de la primera (.COM), puede servirle para examinar si su antivirus intercepta la descarga y posterior ejecución, la segunda simplemente visualiza el código en el navegador (como un archivo de texto, .TXT), y las demás implementan la acción con archivos comprimidos (.ZIP):

 Deberías recibir una advertencia de virus EICAR cuando descargue algunos de esos archivos (al menos del primero), o al intentar ejecutarlo, o descomprimirlo.

Cuando el EICAR.COM se ejecuta, no hay peligro de daño alguno, debido a que NO se trata de un virus real), todo lo que ocurrirá será la aparición de una ventana DOS con este único texto:

       EICAR-STANDARD-ANTIVIRUS-TEST-FILE!


Si desea implementar un mecanismo de seguridad para los archivos que suben los usuarios a sus aplicaciones, por favor ponerse en contacto para realizar una evaluación de sus requerimientos

miércoles, 28 de abril de 2010

Validaciones de contenido de archivo para subir a la WEB

En muchas aplicaciones se necesitan guardar archivos de los usuarios y en la mayoría de los casos se implementa una simple validación de extensión, pero un usuario malicioso podría subir archivos dañinos con extensiones falsas de los archivos que permite nuestra aplicación (ejm: imagenes, pdf, etc) con la esperanza que de alguna manera se ejecute el código malicioso del archivo subido.

Para proteger un poco mas nuestras aplicaciones podemos implementar una o dos barreras adicionales de protección: Validación de contenido y scan con antivirus. En este artículo hablare de la primera opción.

La idea e implementación es muy sencilla, basicamente lo que hay que hacer es que dependiendo de la extensión del archivo se chequea la cabecera/estructura del archivo para determinar si cumple o no con los estandares establecidos para el formato de archivo utilizado.

Por ejemplo un GIF debe comenzar con la cabecera GIF89a o GIF89a o PNG , para BMP los dos primero bytes son 0x42 0x4D, para PDF los primeros 5 bytes son %PDF-

Las validaciones pueden ser mucho mas complejas que solo la cabecera pero la cabecera es buen inicio ya que aunque el archivo maligno le coloquen la cabecera correspondiente a su tipo de archivo, el mismo hecho de modificar la cabecera para que cumpla el estandar dañara el código maligno o por lo menos la forma en que se ejecuta.

Ejemplo en código:

///
/// Valida si el contenido del archivo corresponde o no con el tipo de archivo que se indica solo para gif, jpg y pdf
///

///
El tipo de archivo indicado a validar///
La data del archivo/// Devuelve False si el contenido del archivo no coincide con el tipo de archivo
static private bool ValidarTipoArchivoContenido(string sTipoArchivo, byte[] Archivo)
{
bool bResultado = true;
try
{
int TamanoValidar = 0;
Stream objStream = new MemoryStream(Archivo);
switch (sTipoArchivo.ToLower())
{
case ".gif":
TamanoValidar = 6;
break;
case ".jpg":
case ".jpeg":
TamanoValidar = 4;
break;
case ".pdf":
TamanoValidar = 5;
break;
case ".bmp":
TamanoValidar = 2;
break;
case ".tiff":
case ".tif":
TamanoValidar = 4;
break;
case ".txt":
TamanoValidar = int.Parse(objStream.Length.ToString());
break;

}
if (TamanoValidar > 0)
{
bResultado = false;
byte[] Buffer = new byte[TamanoValidar];
objStream.Read(Buffer, 0, TamanoValidar);
objStream.Close();

string sCabecera = System.Text.Encoding.ASCII.GetString(Buffer);

switch (sTipoArchivo.ToLower())
{
case ".gif":
if (sCabecera == "GIF87a" || sCabecera == "GIF89a" || sCabecera.Substring(1, 3) == @"PNG")
bResultado = true;
break;
case ".jpg":
case ".jpeg":
if (int.Parse(Buffer.GetValue(0).ToString()) == 255 && int.Parse(Buffer.GetValue(1).ToString()) == 216 && int.Parse(Buffer.GetValue(2).ToString()) == 255 && (int.Parse(Buffer.GetValue(3).ToString()) == 224 || int.Parse(Buffer.GetValue(3).ToString()) == 225))
bResultado = true;
break;
case ".pdf":
if (sCabecera == "%PDF-")
bResultado = true;
break;
case ".bmp":
if (sCabecera == "BM")
bResultado = true;
break;
case ".tiff":
case ".tif":
if (sCabecera.Substring(0,2) == "II" && int.Parse(Buffer.GetValue(2).ToString()) == 42)
bResultado = true;
break;
}
}
}
catch (Exception ex)
{
bResultado = false;
log4net.LogManager.GetLogger("root").Error("Error validación contenido", ex);
}
return bResultado;
}

Esto es solo un ejemplo sencillo de implementación, si desea consultoría sobre el tema por favor contacteme