hfwr )lq gh &duuhud ,qjhqlhutd gh...

93
Trabajo Fin de Grado Ingeniería de Telecomunicación Desarrollo de un motor de análisis de ficheros distribuido para la identificación de malware con Apache Spark y MongoDB Autor: Juan Luis Pérez Carretero Tutor: Pablo Nebrera Herrera Dep. Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2016

Upload: vukhanh

Post on 29-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Proyecto Fin de CarreraIngeniería de Telecomunicación

Formato de Publicación de la Escuela TécnicaSuperior de Ingeniería

Autor: F. Javier Payán Somet

Tutor: Juan José Murillo Fuentes

Dep. Teoría de la Señal y ComunicacionesEscuela Técnica Superior de Ingeniería

Universidad de Sevilla

Sevilla, 2013

Trabajo Fin de GradoIngeniería de Telecomunicación

Desarrollo de un motor de análisis deficheros distribuido para la identificación demalware con Apache Spark y MongoDB

Autor: Juan Luis Pérez CarreteroTutor: Pablo Nebrera Herrera

Dep. Ingeniería TelemáticaEscuela Técnica Superior de Ingeniería

Universidad de Sevilla

Sevilla, 2016

Trabajo Fin de GradoIngeniería de Telecomunicación

Desarrollo de un motor de análisis de ficherosdistribuido para la identificación de malware

con Apache Spark y MongoDB

Autor:

Juan Luis Pérez Carretero

Tutor:

Pablo Nebrera HerreraProfesor Asociado

Dep. Ingeniería TelemáticaEscuela Técnica Superior de Ingeniería

Universidad de SevillaSevilla, 2016

Trabajo Fin de Grado: Desarrollo de un motor de análisis de ficheros distribuido para la identi-ficación de malware con Apache Spark y MongoDB

Autor: Juan Luis Pérez CarreteroTutor: Pablo Nebrera Herrera

El tribunal nombrado para juzgar el trabajo arriba indicado, compuesto por los siguientes profesores:

Presidente:

Vocal/es:

Secretario:

acuerdan otorgarle la calificación de:

El Secretario del Tribunal

Fecha:

A mis padres y mi hermana

Agradecimientos

En primer lugar y como no podía ser de otra manera, agradecer a mis PADRES todo su apoyo y esfuerzopara que haya podido llegar hasta aquí. Ellos son los únicos imprescindibles sin los cuales jamás podría

haber llegado a realizar este trabajo.

Por otro lado quiero agradecer a TODO el equipo de redBorder su ayuda y colaboración. Ha sido un placertener mi primera experiencia laboral es un sitio así. Desde el primer día me he sentido muy a gusto y hastayo mismo me sorprendo de todo lo que he aprendido en estos meses.

Por último agradecer a mis HERMANOS de siempre por su apoyo, y por supuesto a los que me heencontrado y conocido en esta maravillosa cuidad y exigente escuela, en la que he visto a mucha gente quemerecía la pena perder años de su vida. No me olvido de ellos.

Juan Luis Pérez CarreteroSevilla, 2016

III

Resumen

En este documento se describe el estudio, desarrollo y conclusiones del proyecto rb-spark. Corresponde aun producto realizado para la empresa redBorder, cuyo objetivo es la identificación de ficheros malware

mediante su envío a dos servicios web, virustotal y metascan, y el servicio de linux clamscan, para realizarun procesado por lotes con el framework de análisis distribuido en memoria Apache Spark. Posteriormentese almacena la información en la base de datos distribuida y NoSQL MongoDB, para que finalmente losdatos puedan ser visualizados directamente en formato BSON mediante la herramienta MongoDB Compass,o a través de reports generados por la herramienta Pentaho.

V

Abstract

This document explains the design, development and conclusions of rb-spark project, which is a productdeveloped for the redBorder company.The main objective of this project is to identify malware files by

sending these to two web services, virustotal and metascan, and by using the clamscan Linux service. Thesetools are using by a batch processing analysis on the ditrubuted analysis framework in memory Apache Spark.Later, the information is stored in the distributed and NoSQL database MongoDB and is shown in BSONformat in MongoDB Compass tool or in a report generated by Pentaho.

VII

Índice Abreviado

Resumen VAbstract VIIÍndice Abreviado IXÍndice XIII

1 Introducción 31.1 Motivación 31.2 Objetivos 41.3 Estructura del Proyecto 4

2 Base Teórica 72.1 Análisis de Malware 72.2 Batch processing 82.3 Ficheros secuenciales de Apache Hadoop 8

3 Herramientas Utilizadas 113.1 Apache Spark 113.2 Apache Hadoop 133.3 MongoDB 153.4 Herramientas Análisis Malware 163.5 Herramientas visualización para las pruebas 173.6 Lenguaje de programación 18

4 Implementación del Sistema 194.1 Estado de arte: BinaryPig 194.2 Punto de Partida inicial : rb-sequence-oozie 204.3 Implementacion de rb-Spark 22

5 Pruebas 315.1 Escenario 315.2 Resultados y visualización 325.3 Conclusiones Pruebas 34

6 Presupuesto 377 Conclusiones 39

7.1 Conclusión 397.2 Líneas de desarrollo 39

8 ANEXOS 41Anexo I 428.1 Código Fuente del Proyecto 42

Anexo II 52

IX

X Índice Abreviado

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 52

Bibliografia 64

Índice de Figuras 67Índice de Tablas 69Índice de Códigos 71Bibliografía 73Índice alfabético 73Glosario 73

Índice Abreviado XI

Índice

Resumen VAbstract VIIÍndice Abreviado IXÍndice XIII

1 Introducción 31.1 Motivación 31.2 Objetivos 41.3 Estructura del Proyecto 4

2 Base Teórica 72.1 Análisis de Malware 7

2.1.1 Análisis Basado en Firmas 72.1.2 Análisis Estático 7

2.2 Batch processing 82.3 Ficheros secuenciales de Apache Hadoop 8

3 Herramientas Utilizadas 113.1 Apache Spark 11

3.1.1 Apache Spark 2.0.0 123.2 Apache Hadoop 133.3 MongoDB 15

3.3.1 Conector MongoDB Spark 163.4 Herramientas Análisis Malware 16

3.4.1 VirusTotal 163.4.2 Opswat Metascan 173.4.3 Clamscan 17

3.5 Herramientas visualización para las pruebas 173.5.1 MongoDB Compass 173.5.2 Pentaho 17

3.6 Lenguaje de programación 183.6.1 Scala 18

4 Implementación del Sistema 194.1 Estado de arte: BinaryPig 19

4.1.1 Arquitectura BinaryPig 204.2 Punto de Partida inicial : rb-sequence-oozie 20

4.2.1 Arquitectura y Funcionamiento rb-sequence-oozie 204.3 Implementacion de rb-Spark 22

4.3.1 Arquitectura y Funcionamineto rb-Spark 22Ingesta 22Diseño Cargadores Malware 22

XIII

XIV Índice

Operaciones de tipo batch 27Serialización 29Almacenamiento 29

5 Pruebas 315.1 Escenario 315.2 Resultados y visualización 325.3 Conclusiones Pruebas 34

6 Presupuesto 377 Conclusiones 39

7.1 Conclusión 397.2 Líneas de desarrollo 39

8 ANEXOS 41Anexo I 428.1 Código Fuente del Proyecto 42

8.1.1 Cargador VirusTotalLoader 428.1.2 Cargador MetascanLoader 448.1.3 Cargador ClamScanDaemonLoader 498.1.4 Objeto Main de la aplicación 50

Anexo II 528.2 Articulo sobre Apache Spark escrito para el blog de redBorder 52

Bibliografia 64

Índice de Figuras 67Índice de Tablas 69Índice de Códigos 71Bibliografía 73Índice alfabético 73Glosario 73

1

1 Introducción

We are moving slowly into an era where Big Data is the startingpoint, not the end.

Pearl Zhu (Autora del conjunto de libros DigitalMaster)

1.1 Motivación

La revolución digital y el Big Data están cambiando por completo la manera en la que se recopila yutiliza la información. Ésto implica una gran oportunidad para organizaciones, empresas y usuarios de

aprovechar la ingente cantidad de nuevos datos que antes no se conocían o no se utilizaban, para convertirlosen información útil y conocimiento que aporte valor añadido.

En los próximos años la tendencia es hacia una sociedad hiperconectada, en la que las ciudades inteligentesy la generación e intercambio masivo de datos entre dispositivos conectados entre si llevará a una mejora dela calidad de vida de los ciudadanos. En el sector de la industria, los avances tecnológicos y mejor uso yaprovechamiento de los datos gracias a las tecnologías cognitivas, supondrá un aumento considerable dela productividad, que provocará un crecimiento de la economía mundial [1]. Es imprescindible asegurar laconfidencialidad y protección de esos datos para que sólo sean utilizados por las entidades las cuales seanpropietarias de ellos, y que además sean datos verídicos sin ningún tipo de anomalía provocada por agentesexternos.

Según BI Intelligence, el servicio de investigación de Business Insider, para 2020 habrá 34 billones dedispositivo conectados a Internet, lo que pone de manifiesto la necesidad de la creación de un clima deconfianza digital. La evolución tecnológica tiene que ir necesariamente ligada con la ciberseguridad paraasegurar la confidencialidad, privacidad y un uso ético de los dispositivos y del tráfico que éstos generan.

En la era de la información las credenciales y datos de usuarios tienen vital importancia, lo que ha provocadoque el número de ataques a sistemas informáticos no haya hecho más que aumentar en los últimos años. Espor eso que los costes de inversión de las empresas en tecnologías Big Data debe a ir acompañada de unaestrategia de seguridad para los datos de usuarios, y asi poder evitar por ejemplo un robo de información quepodría desprestigiar su imagen ante sus clientes y sufrir pérdidas millonarias.

3

4 Capítulo 1. Introducción

Figura 1.1 Estimación número de dispositivos conectados a Internet.

Así la ciberseguridad será un elemento clave e imprescindible en el desarrollo de las nuevas tendenciastecnológicas, como la computación en la nube, internet de las cosas, las redes sociales, las tecnologíascognitivas, las smart cities o los nuevos modelos de pagos, entre muchas otras.

1.2 Objetivos

Con este trabajo se pretende diseñar y desarrollar una herramienta que sea capaz de detectar los ficherosmaliciosos que se encuentran en un determinado escenario o entorno de red, para poder actuar los más rápidoposible sobre ellos.

Estos ficheros son almacenados en un determinado directorio, procedente de sensores localizados porla red que se encargan de capturarlos y guardalos en un sistema de ficheros distribuido. Posteriormenteson analizados mediante operaciones de tipo batch a por una serie de herramientas de análisis de malware,para posteriormente guardar los datos recibidos en una base de datos desde la que se puedan visualizarla información de los ficheros de una manera eficiente, y comprobar si corresponde o no con archivos decontenido sospechoso.

1.3 Estructura del Proyecto

En este capítulo se ha hecho una pequeña introducción a los motivos que me han llevado a realizar estetrabajo como mi proyecto final de grado y los objetivos que se marcaron al comienzo de éste, a continuaciónse define el contenido del resto de capítulos:

• Capítulo 2 , Base Teórica : Se introducirán los conceptos teóricos claves que son necesarios comorequisito para el desarrollo del proyecto.

• Capítulo 3 , Herramientas utilizadas : Se realizará una introducción y definición de las característicasde las herramientas usadas para este proyecto.

• Capítulo 4 , Implementación del Sistema : Se explicará el diseño, desarrollo, estado de arte y puntoinicial del proyecto.

• Capítulo 5 , Pruebas : Se presentarán las pruebas realizadas, asi como el escenario dónde se han llevadoa cabo y la visualización de los resultados obtenidos.

1.3 Estructura del Proyecto 5

• Capítulo 6 , Presupuesto : Desglose por horas y coste del trabajo realizado.

• Capítulo 7 , Conclusiones : Se explican las conclusiones obtenidas tras la realización del trabajo y seprofundizará en posibles mejoras.

2 Base Teórica

The world is one big data problem

Andrew McAfee (Fundador de McAfee Antivirus)

Este trabajo está basado en varios conceptos teóricos claves que son importantes conocer. Primero sedetalla una explicación teórica del procesamiento por lotes o batch processing, para continuar con el

analisis de ficheros malware y por el último se comenta la estructura y ventajas de los ficheros secuenciales.

2.1 Análisis de Malware

El análisis de malware es el estudio de un fichero sospechoso de poder realizar acciones que el usuariou organización no demanda ni desea que se produzcan, tales como daños en el sistema operativo o en elhardware, robo de información o procesos en segundo plano con cualquier otro objetivo, para poder detectarloy clasificarlo ya sea por su tipo (Virus, gusanos, troyanos, rootkits,etc.), nombre o cualquier otra característicaque interese.

Para poder determinar la función u objetivo de éstos existen tres tipos de análisis [2]. Los más comunes ytradicionales son el basado en firmas y el análisis estático. Por otro lado está el análisis dinámico, en el cualse ejecuta el malware en un entorno aislado o sandbox y se observa su comportamiento. En este trabajo seusarán los dos primeros, que serán explicados en este capítulo.

2.1.1 Análisis Basado en Firmas

Este tipo de análisis está basado en la comprobación de algún elemento que identifique al fichero en cuestiónde manera única, como por ejemplo su cifrado sha1, sha256 o md5, con una base de datos en la que estánalmacenados los identificadores junto con el comportamiento del fichero, ya sea porque ha sido compartidopor alguien anteriormente o debido a análisis anteriores.

2.1.2 Análisis Estático

El análisis estático de malware consiste en el estudio del fichero sin tener que ejecutarlo [3] para obtenerinformación sobre su estructura, funcionalidad, aspectos que ya hayan sido compartido por otros usuarios odetalles útiles de éste como su md5, sha1, etc. Se basa en la carga del fichero a analizar en un desensambladory a partir de técnicas de ingeniería inversa obtener las instrucciones máquina del programa para analizarsu comportamiento. Normalmente se suele realizar este tipo de análisis para obtener la mayor cantidad deinformación posible sobre el fichero para posteriormente realizar un análisis dinámico conociendo ya lascaracterísticas estáticas del ejecutable.

En este trabajo se parte de un fichero secuencial que contiene un conjunto de ficheros con pares clavevalor formados por el md5 del fichero y su contenido en binario. Como complemento al análisis estático, lasherramientas utilizadas usan también el tradicional método basado en firmas.

7

8 Capítulo 2. Base Teórica

2.2 Batch processing

Batch processing o procesamiento por lotes es un tipo de ejecución de software en el que se realizan variosprocesos (llamados también trabajos) al mismo tiempo, sin ser necesaria la interacción del usuario, demanera que cada uno de los datos de entrada son divididos en “batches” que son analizados por los trabajospreviamente programados para generar una salida conjunta. Dependiendo de la forma de ejecución sedistinguen tres tipos[4]:

• Procesamiento por lotes simultáneo : Se dice que instancias de una actividad están realizando unprocesamiento por lotes simultáneo cuando éstas son ejecutadas por los mismos recursos exactamenteal mismo tiempo.

• Procesamiento por lotes secuencial : Se dice que instancias de una actividad están realizando unprocesamiento por lotes secuencial cuando son ejecutadas por el mismo recurso inmediatamente o casiinmediatamente una después de otra.

• Procesamiento por lotes concurrente : Se dice que instancias de una actividad están realizando unprocesamiento por lotes concurrente cuando éstas son ejecutadas por los mismos recursos parcialmentesolapadas en el tiempo unas con otras.

Figura 2.1 Ejemplo método identificación de batch processing.

En 2004 un equipo de ingenieros de Google publicó un paper que definía el primer modelo de procesamientopor lotes computacional distribuido llamado MapReduce, que junto con el sistema de ficheros distribuidoHDFS formaron Hadoop. Hadoop ha sido la tecnología referencia en el mundo Big Data para operaciones detipo batch desde su aparición, pero las necesidades actuales han cambiado y sus limitaciones sobre todo entérminos de velocidad debido a su modelo de procesamiento en disco, son cada vez más evidentes. Es por elloque para este trabajo se usará como herramienta Apache Spark, un motor de procesamiento distribuido enmemoria lanzado en 2014 que puede llegar a ser hasta cien veces más rápido que Hadoop en algunos casos.

2.3 Ficheros secuenciales de Apache Hadoop

Los ficheros secuenciales de Hadoop proveen una estructura de datos de pares binario clave-valor en el quelos elementos son guardados uno después de otro de una manera secuencial [5]. A diferencia de otro tipo deestructuras clave-valor , no se puede buscar una determinada clave editando, borrando o añadiendo ésta. Estetipo de ficheros son de tipo append-only.

Exiten tres formatos distintos de este tipo de ficheros con una cabecera común:

• Uncompressed : Cada llamada al método append añade un elemento al fichero que contiene el tamañocompleto del elemento, formado por la suma del tamaño de la clave y del valor.

2.3 Ficheros secuenciales de Apache Hadoop 9

Figura 2.2 Cabecera de un fichero secuencial.

• Record Compressed : Es similar al anterior sólo que en este caso el campo valor que contiene los datosestá comprimido.

• Block-Compressed : Este formato no escribe los datos hasta que alcanza un umbral y cuando éste esalcanzado todas las claves son comprimidas juntas. Lo mismo ocurre para los valores.

3 Herramientas Utilizadas

The goal is to turn data into information, and information intoinsight

Carly Fiorina, (former chief executive ofHewlett-Packard Company)

En este capítulo se listan y detallan las herramientas usadas para la realización de este trabajo. Seempezará introduciendo el motor de procesamiento distribuido utilizado, posteriormete se hablará de

Apache Hadoop y su sistema de ficheros distribuido de ficheros, para después continuar con la tecnología dealmacenamiento elegida, las herramientas de análisis de ficheros maliciosos y por último las de visualizaciónutilizadas para las pruebas.

3.1 Apache Spark

Apache Spark es un framework de procesamineto distribuido open source que destaca por su velocidad deejecución gracias al almcenamiento en caché en memoria[6]. Es compatible con el procesamiento generalpor lotes (Spark Core), el aprendizaje autómatico (MLlib), el análisis de transmisiones (Spark Streaming),las bases de datos de grafos (GraphX) y las consultas ad-hoc (Spark SQL).

Figura 3.1 Núcleo y librerias de Apache Spark.

11

12 Capítulo 3. Herramientas Utilizadas

Fue creado por el AMPLab de la Universidad de Berkeley en California en 2009 y donado a la comunidadopen source bajo licencia BSD en 2010. En 2013 fue donado la fundación Apache Software y desde 2014 esel proyecto top.

Apache Spark comenzó como un subproyecto de Apache Hadoop que trataba de mejorar el rendimiento dela capa de computación MapReduce, manteniendo la escalabilidad lineal y la tolerancia a fallos. Para ello sebasa en dos mejoras fundamentales, los DAGs y los RDDs.

Un DAG (Directed Acyclic Graph) es un grafo dirigido que no tiene ciclos. Para cada nodo del grafo no hayun camino directo que comience y finalice en dicho nodo, un vértice se puede conectar a otro pero nunca a simismo. Cada tarea de Spark crea un DAG de etapas de trabajo para que sean ejecutados en un determinadoclúster. MapReduce sólo crea un DAG con dos estados predefinidos, Map y Reduce, sin embargo los grafosDAG creados por Spark puede tener cualquier número de etapas. Además los DAGs de Spark son mucho másrápidos porque no tienen que escribir los resultados de cada etapa en disco,

Un RDD (Resilent Distribuited Dataset) es la unidad mínima de abstracción de Spark. Se trata de unacolección de objetos Scala inmutables y distribuidos a lo largo de un clúster. Cada RDD es dividido en variasparticiones, que son procesadas por los distintos nodos. Se pueden realizar dos tipos de operaciones sobreun RDD, las transformaciones que crean un nuevo RDD a partir del que se ha realizado la operación, y lasacciones las cuales devuelven un resultado.

Otra de las características de Apache Spark es capacidad de soporte para todo tipo de datos, tanto estructu-rados como no estructurados , que pueden ser cargados desde muy diversas tecnologías de almacenamientocomo HDFS, Cassandra, HBase, S3, Hive, Tachyon, MongoDB y cualquier fuente de datos de Hadoop.

Su núcleo está escrito casi integramente en Scala, pero posee APIs de programación para los lenguagesJava, R y Python. Lo cual le aporta mucha flexibilidad a la hora de crear aplicaciones y la capacidad deaprovechar la multitud de librerías ya desarrolladas en estos lenguajes.

3.1.1 Apache Spark 2.0.0

El 26 de julio de 2016 se lanzó a la comunidad la release 2.0.0 de Apache Spark, una de las actualizacionesmás relevantes que trae consigo importantes mejoras en varios frentes. Una de ellas ha sido el progreso de lareducción del tiempo de procesamiento, con incorporaciones a la tecnología como el Catalyst Optimizer yel proyecto Tungsten. Por ello a pesar de lo reciente de su lanzamiento ha sido la versión utilizada en estetrabajo.

Figura 3.2 Comparativa rendimiento versiones Apache Spark 1.6 y 2.0.

3.2 Apache Hadoop 13

3.2 Apache Hadoop

Apache Hadoop es un framework de procesamiento distribuido escrito en Java, escalable y open source[9] lanzado en 2005, que permite procesar grandes volúmenes de datos a lo largo de un clúster. Hadoopsepara y distribuye los archivos que contienen los datos, es capaz de dividir el trabajo en tareas más pequeñas,ejecutarlas de manera distribuida y recuperarse de posibles fallos automáticamente y de forma transparenteal usuario. Está basado en dos papers publicados por Google. Uno de ellos definía el paradigma MapReducey el otro el sistema de ficheros distribuidos GFS (Google File System). Consta de cuatro módulos explicadosa continuación.

• Hadoop Common: Es el núcleo del framework,proporciona acceso a los sistemas de ficheros soportadospor Hadoop y contiene los ficheros JAR y scripts necesarios para arrancarlo.

• Hadoop Distributed File System (HDFS): Es un sistema de ficheros distribuido, tolerante a fallos yfiable gracias a la replicación de sus bloques. Posee una arquitectura maestro/esclavo formada por unúnico NameNode, que es el maestro que maneja los espacios de nombres y regula el acceso de losclientes a los ficheros. Por otro lado están los DataNodes, normalmente uno por nodo, que gestiona elalmacenamiento en los nodos donde se ejecuta.

Figura 3.3 Arquitectura de HDFS.

• Hadoop MapReduce: MapReduce es un framework de procesamiento paralelo distribuido para ficherosde gran tamaño, que consta de dos fases. Una primera fase map en la que mapea los datos iniciales queaparecen en el fichero de entrada a pares clave/valor intermedios con los que sea más fácil trabajar. Y unsegunda fase llamada Reduce en la que se reducen los pares intermedios a un conjunto de datos menorque el inicial en el que se agrupan aquellos elementos que comparten las misma clave. El ejemplo máscomún de una operación de tipo MapReduce es el contador de palabras de un fichero.

14 Capítulo 3. Herramientas Utilizadas

Figura 3.4 Contador de palabras MapReduce.

• HadoopYARN: YARN es unmanejador de recursos el cual es unamejora de la arquitecturaMapReduce,que fue introducido a partir de la segunda versión de Hadoop, para separar en dos demonios diferentesla gestión de recursos y la capa de procesamiento. Estas tareas las realizaba ambas anteriormenteel NameNode de MapReduce, con YARN se obtiene independencia entre las tareas además de lacapacidad de integración de otra herramientas de procesamiento que no sean MapReduce.De esta división surgen los elementos ResourceManager, el cual se encarga de la gestión de los recursos,y ApplicationMaster que se encarga de la planificación de las tareas.

Figura 3.5 Arquitectura de YARN.

Asi el el ResourceManager y el NodeManager esclavo de cada nodo establecen el entorno de trabajo, elResourceManger se encarga de gestionar los recursos, mientras que el ApplicationMaster se encarga dela negociación de recurosos con el ResourceManager y los NodeManger para poder ejecutar y controlarlas tareas.

3.3 MongoDB 15

Figura 3.6 Ejemplo tecnologias ecosistema Hadoop.

3.3 MongoDB

MongoDB es una base de datos NoSQL open source y orientada a documentos[12] escrita en C++. Alcontrario que las bases de datos tradicionales, no guarda los datos en registros, sino en documentos que sonalamacenados en objetos BSON, una representación binaria de JSON.

Estos documentos son entidades con un conjunto de atributos sin tipos definidos y que no poseen unaesquema fijo en los que son clasificados los datos, lo que aporta mucha flexibilidad a la hora de crear losmodelos y la capacidad para de cambiarlos de manera sencilla, incluso en producción. Los documentos seindexan bajo una clave única que tiene un índice asociado, con la ventaja que se puede crear tantos índicescomo se quiera, lo que aporta un espectro muy amplio a la hora de realizar queries.

Figura 3.7 Ejemplo docuemento BSON de MongoDB.

Las bases de datos orientadas a documentos están enfocadas a una fuerte consistencia de sus datos,replicados de forma distribuida, de manera que cuando se inserta un dato en un nodo se replica en los demás

16 Capítulo 3. Herramientas Utilizadas

de forma consecutiva, lo que penaliza la escritura pero nos aporta una alta disponibilidad de la información.

MongoDB utiliza mapeo en memoria para almacenar los datos, de manera que asigna archivos a un bloquede memoria con correlación byte por byte. Usa mapeado en memoria para el manejo e interacción con todoslos datos, lo que le proporciona un alto rendimiento tanto en lectura como en escritura.

Además MongoDB posee la capacidad de escalar linealmente de manera sencilla gracias a un tipo dearquitectura denominada sharding, que particiona los datos entre nodos repartiéndose uniformemente lascargas de trabajo mediante balanceo de carga y permitiendo escalar horizontalmente.

Así la base de datos MongoDB nos ofrece ventajas propias de las bases de datos tradicionales SQL comouna fuerte consistencia de los datos y la capacidad de realizar consultas complejas definiendo índices. Éstosumado a las ventajas propias de las bases de datos NoSQL como flexibilidad de los modelos de datos,escalabilidad, alto rendimiento y alta disponibilidad.

3.3.1 Conector MongoDB Spark

El 28 de junio de 2016 fue lanzada la version 1.0.0 del conector de MongoDB con Apache Spark, queproporciona integración nativa para todos los tipos de datos de Spark con Mongo, pudiéndose guardardirectamente como documentos en una colección de MongoDB.

Figura 3.8 Ejemplo integración de MongoDB y Apache Spark.

3.4 Herramientas Análisis Malware

A continuación se definen las herramientas utilizadas para el análisis de malware :

3.4.1 VirusTotal

VirusTotal es un servicio web de escáneres de malware, virus y URLs online [13]. Fue creada en 2004 por laempresa malagueña Hispasec Sistemas y en 2012 fue comprada por Google Inc. Actualmente es el serviciode análisis de malware referencia con mas de 60 motores de análisis, incluyendo las bases de datos y motoresde busqueda de los principales antivirus del mundo. Su éxito está basado en el servicio colaborativo, cuandoun archivo es detectado como un fichero malicioso se notifica a las compañías suscritas, siendo un mecanismorápido y efectivo. Ofrece una api pública para el envío de ficheros que será utilizada en este trabajo. Parapoder utilizarla es necesario una clave que se obtiene al registrarse en la comunidad de VirusTotal y que estálimitada a 4 peticiones por minuto.

3.5 Herramientas visualización para las pruebas 17

3.4.2 Opswat Metascan

Metascan es un servicio cloud de análisis de malware con varios motores de análisis simultáneamente, entreellos AVG, Kaspersky, Norton o MacAfee [14]. Al igual que VirusTotal, ofrece una api pública para el envíode ficheros, para la que hay que obtener una clave en la web de Opswat. Tiene la restricción de 25 peticionesde ficheros por hora y 1500 peticiones de hash.

3.4.3 Clamscan

Clamscan es una herramienta open source de licencia GPL inicialmente desarrollada para detectar el malwareproveniente de correo electrónico en sistemas UNIX [15]. Proporciona un demonio multiproceso escalablepara el escáner de ficheros y una herramienta para la actualización automática de las bases de datos queregistran los ficheros considerados maliciosos. Los fundadores y desarrolladores más importantes de estatecnología se incorporaron a Sourcefire, que fue comprada por Cisco en 2013.

3.5 Herramientas visualización para las pruebas

3.5.1 MongoDB Compass

MongoDB Compass es una herramienta gráfica de visualización que permite analizar documentos BSON deMongoDB de una manera simple e intuitiva, permitiendo explorar visualmente la base de datos almacenadasin necesidad de conocer el lenguaje de consulta. Para ello permite la realización de queries sencillas demanera gráfica. Es una herramienta corporativa de MongoDB que dispone de una versión de prueba de 30días que ha sido la utilizada en este trabajo. Es una aplicación cliente sólo disponible para Windows y MAC.

3.5.2 Pentaho

Pentaho es un conjunto de herramientas open source orientadas a procesos de Bussines Inteligence [16]que cubre los principales componentes requeridos para implementar soluciones basadas en procesos. Laplataforma consta de los siguientes módulos:

• Reporting: Es una solución basada en el proyecto JFreeReport que nos permite generar informes de unaforma ágil. Permite la exportación de los resultados a los formatos PDF, XLS, CSV, HTML y texto.

Figura 3.9 Ecosistema open source de Pentaho.

• Análisis: Pentaho sumunistra un sistema avanzado de análisis de información, en el que el usuariopuede navegar por los datos, ajustar la visión y los filtros de visualización.

18 Capítulo 3. Herramientas Utilizadas

• Dashboards : Todos los componentes del modulo Pentaho Reporting y Pentaho Análisis puedenformar parte de un Dashboard. Es posible incorporar una gran variedad de tipos de gráficos, tablas yvelocímetros, e integrarlos en la plataforma para poder visualizar informes, gráficos y realizar análisisOLAP.

• Data Mining: Se usa para aprendizaje máquina, aprendizaje automático y minería de datos. Cuenta conalgoritmos de clasificación, de regresión, de reglas de asociación y de clustering, para así apoyar lastareas de análisis predictivo

• Integración de datos: Orientado a las fases de extracción, transformación y carga de datos (ETL) nospermite importar datos de una gran variedad de fuentes de datos distintas, entre ellas MongoDB yHDFS, y generar una salida con un interfaz gráfica intuitiva.

3.6 Lenguaje de programación

El gran grueso de este trabajo consiste en el desarrollo de una aplicación para Apache Spark, que es unatecnología cuyo núcleo está escrito casi integramente en Scala, que ha sido el lenguaje de programacionutilizado.

3.6.1 Scala

Scala es un lenguaje de programación multi-paradigma diseñado y creado por un equipo dirigido por MartinOdersky en 2003 en la universidad EPFL[17]. Posee características de lenguajes orientados a objetos y delenguajes funcionales. Esta diseñado para poder crecer de manera eficiente según la demanda de usuarios.Scala es compilado a Java bytecode e interpretado en la Máquina Virtual de Java, presenta total compatibilidadcon éste y todas sus librerías. Sin embargo presenta numerosas diferencias con Java, como son tipado estáticode tipos, sobrecarga de operadores o lazy evaluation. Además su carácter funcional lo hace muy adecuado parala computación distribuida, siendo un lenguaje maduro en este sentido, frente a otros lenguajes relativamentejóvenes como Julia o Go, creados para este propósito. Scala es un lenguaje de sintaxis breve y concisa queintenta simplificar y reutilizar el código lo máximo posible. En casi todos los casos se consigue una reducciónde número líneas de código respecto a las necesarias en Java [12].

Código 3.1 WordCount implementado en Java.

JavaRDD<String> input = sc.textFile("s3://...")JavaRDD<String> words = rdd.flatMap(new FlatMapFunction<String, String>() {public Iterable<String> call(String x) { return Arrays.asList(x.split(" ")); }});JavaPairRDD<String, Integer> result = words.mapToPair(new PairFunction<String, String, Integer>() {public Tuple2<String, Integer> call(String x) { return new Tuple2(x, 1); }}).reduceByKey(new Function2<Integer, Integer, Integer>() {public Integer call(Integer a, Integer b) { return a + b; }})

Código 3.2 WordCount implementado en Scala.

val input = sc.textFile("s3://...")val words = input.flatMap(x => x.split(" "))val result = words.map(x => (x, 1)).reduceByKey((x, y) => x + y)

4 Implementación del Sistema

There’s no silver bullet solution with cyber security, a layereddefense is the only viable defense

James Scott (Senior Fellow at the Institute for CriticalInfrastructure Technology)

El presente trabajo que se expone en este documento es una mejora de la parte de procesamiento por lotesen Hadoop del producto de redBorder rb-sequence-oozie, que está basada en un proyecto open source

de la empresa Endgame llamado BinaryPig.

En este capítulo primero se introducirá como estado de arte la arquitectura y funcionalidad del proyectoBinaryPig, posteriormente se explicará el diseño del sistema rb-sequence-oozie y finalmente se detallará laarquitectura y desarrollo del proyecto en cuestión, rb-spark.

4.1 Estado de arte: BinaryPig

Figura 4.1 Arquitectura BinaryPig.

BinaryPig fue el primer proyecto open source que trataba de dar solución a los problemas de escalabilidadque existían en el análisis de malware. El número de peticiones a servicios que ofrecen el análisis tradicionalde malware basado en firmas, ha incrememntado exponencialmente en los últimos años, un ejemplo deello es el de virustotal que recibe más de un millón de peticiones diarias. Por ello un equipo de la empresa

19

20 Capítulo 4. Implementación del Sistema

Endgameinc, desarrolló este framework con la capacidad de escalar horizontalmente, integrando una seriede herramientas de análisis de malware con las tecnologías de computación distribuida Apache Hadoop yApache Pig.

4.1.1 Arquitectura BinaryPig

Para la parte de ingesta BinaryPig cuenta con un cargador de ficheros secuenciales, el cual a partir de cientoso miles de ficheros es capaz de crear un único fichero secuencial de Hadoop formado por todos ellos, con unconjunto de pares clave-valor donde la clave es identificada por el md5 del fichero y el campo valor correspondecon el contenido del fichero en formato binario. Esta parte de la aplicación tiene como objetivo aumentar elrendimiento del procesamiento distribuido de los ficheros, que será mucho más eficiente procesando un únicofichero de gran tamaño que con cada fichero por separado, debido a que estas herramientas están diseñadaspara el análisis de grandes volúmenes de datos.

Una vez que es creado el fichero secuencial, éste es cargado en el sistema de ficheros distribuido HDFS yprocesado de manera distribuida, a partir de un conjunto de cargadores malware implementados como trabajosde Hadoop escritos en Java para Apache PIG. Posteriormente los resultados del análisis son almacenados denuevo en HDFS en formatos JSON, información que puede ser explorada por el usuario final a través delmotor de búsqueda ElasticSearch.

4.2 Punto de Partida inicial : rb-sequence-oozie

rb-sequence-oozie es un producto de redBorder el cual se trata de una aplicación distribuida que es laencargada de la parte de procesado por lotes del producto de redBorder rb-Malware.

4.2.1 Arquitectura y Funcionamiento rb-sequence-oozie

Esta aplicación consta de dos partes bien diferenciadas. Por un lado la primera llamada rb-sequence, que seencarga de obtener los ficheros del sistema de almacenamiento de redBorder rb-S3 y escribirlos en Hadoopcomo un fichero secuencial.Y por otro rb-oozie, que ejecuta los trabajos de análisis a través de Apache Oozie.

En ambas de las dos partes existen tres elementos distintos : líder, mánager y peones.

En un clúster donde se ejecute esta aplicación habrá un líder de rb-sequence y un líder de rb-oozie. Habrátantos mánagers como instancias del servicio, que lanzarán peones para crear y procesar los distintos ficherosen HDFS.

En cuanto al funcionamiento del servicio se distinguen dos fases correspondientes a las dos partes delproyecto.

La primera fase comienza con los ficheros llegando a la ruta rb-S3 “s3:// malware/mdata/input”, bienprovenientes del sensor IPS o de la pasarela de correo electrónico.

El líder de rb-sequence está comprobando constantemente las rutas de S3 s3://Malware/mdata/input/ ys3://Malware/mdata/analyzed/ buscando si hay nuevos ficheros para analizar. Si hay ficheros en el directorio/input y se seleccionan para ser utilizados , el líder los pasa al directorio /analyzed. El objetivo de estáoperación es poder volver a analizar antiguos ficheros.

El líder de rb-sequence selecciona también el número de ficheros elegidos en la configuración y escribeuna tarea en zookeper indicando cual de ellos tienen que ser analizado. Esta tarea es asignada a un SequenceManager que lanzará un Sequence Peon. Este peón descarga los fiheros de S3 que seleccionó el líder derb-sequence, los junta en un único fichero secuencial y los almacena en HDFS. El Sequence Manager escribeuna nueva tarea en Zookeper que será recibida por la segunda parte del programa, concretamente por el líderde rb-oozie para empezar con el análisis del fichero secuencial.

En la segunda fase de la aplicación el líder es rb-oozie, que transfiere este tarea a un Oozie Managerapoyándose en ZooKeeper. El Oozie Manager crea un peón Oozie que crea un cliente del servicio Oozie que

4.2 Punto de Partida inicial : rb-sequence-oozie 21

Figu

ra4.

2Arquitecturarb-sequence-oozie.

22 Capítulo 4. Implementación del Sistema

será el encargado de realizar el análisis determinado por el flujo de trabajo. El peón manda dicho trabajo através de un cliente de Oozie. El servidor de Oozie cuando lo recibe va ejecutando las tareas en el manejadorde recursos de Hadoop YARN.

Cuando el análisis es finalizado se libera un semáforo del líder de rb-sequence para que éste vuelva aseleccionar nuevos ficheros y repetir todo el proceso.

4.3 Implementacion de rb-Spark

Para este trabajo se ha desarrollado una nueva aplicación que es una solución alternativa a la parte deprocesamiento por lotes de los cargadores malware de rb-sequence-oozie. Se han migrado algunos de loscargadores definidos en java para Pig en cargadores para Apache Spark escritos en Scala y se ha diseñadouna nueva forma de almacenamiento y visualización de los datos.

4.3.1 Arquitectura y Funcionamineto rb-Spark

IngestaPara la parte de ingesta de la aplicación se ha hecho uso del cargador de ficheros secuenciales de BinaryPig,que es una herramienta gracias a la cual se puede obtener un único fichero secuencial a partir de un númeroelevado de ficheros malware más pequeños. Este fichero secuencial está formado por un conjunto de paresclave-valor dónde la clave es identificada por el md5 del fichero y el campo valor corresponde con el contenidodel fichero en formato binario. Para ello se hace uso del comando dirtosequencefile de BinaryPig indicandoel directorio fuente dónde se encuentran las muestras de fichero malware y el directorio destino de HDFSdónde se va a almacenar el fichero secuencial.

Código 4.1 Uso de la herramienta dirtosequencefile.

./bin/dir_to_sequencefile /malwareSamples/ /malwareAnalysis/Secuencial_File.seq

Una vez que se tiene un fichero secuencial listo para ser analizado, el primer paso es cargar éste en nuestraaplicación. Para ello se llama al método sequenceFile del contexto de Apache Spark, indicándole los tipos deentrada y salida de Hadoop Text y BytesWritable, que previamente hemos importado, y la ruta de HDFS enla cual se encuentra el fichero secuencial. Con esto se obtiene una variable de tipo RDD formada por paresclave-valor que corresponden con el contenido del fichero secuencial.

Código 4.2 Carga del fichero secuencial desde HDFS a la aplicación desarrolada.

import org.apache.hadoop.io.{BytesWritable, Text}

val readme = sc.sequenceFile[Text, BytesWritable]("hdfs:///malwareAnalysis/Secuencial_File.seq")

Diseño Cargadores MalwareCada uno de los cargadores malware desarrollados son objetos Scala que heredan del trait (similar a interfazen Java) común llamada FileProcessor, la cual implementa un método llamado ProcessFile que acepta comoargumentos de entrada una cadena de caracteres que corresponde con el md5 del fichero y un array de bytesque corresponde con el contenido del fichero en formato binario. Este método devuelve una variable de tipomapa de pares cadena de caracteres y Any. Se ha elegido este tipo de mapa por su flexibilidad a la hora deencapsular la información devuelta por cada cargador y por su facilidad de conversión en tipo documentopara su posterior almacenamiento en MongoDB.

VirusTotalPara el desarrollo del cargador de VirusTotal se ha hecho uso del cliente desarrollado por el ingenieroKanishka Dilshan para la API pública de Java de VirusTotal. Este cliente nos ofrece una clase llamada

4.3 Implementacion de rb-Spark 23

VirusTotalConfig mediante la cual se puede proceder a la identificación con el servidor de VirusTotal, pormedio de una clave que se ha obtenido previamente tras registrarse en la comunidad de VirusTotal. Paraello se llama a los métodos de VirusTotalConfig getConfigInstance y setVirusTotalAPIKey, pasándole comoargumento de entrada la clave identificadora.

Código 4.3 Identificación con el servidor de VirusTotal.

import com.kanishka.virustotalv2.{VirusTotalConfig}

val apiKey = "1edc806644f93242a2579a2c09703f4088afbdfd31864f33415058b19af3a727"

VirusTotalConfig.getConfigInstance.setVirusTotalAPIKey(apiKey)

Para la comunicación con el servicio el cliente mencionado nos ofrece la clase VirustotalPublicV2Imp,que implementa los métodos scanFile y getScanReport. Este último acepta como argumento de entrada unacadena de caracteres que utilizaremos para enviar los md5 del fichero, y scanFile acepta como argumento deentrada un array de bytes, que utilizaremos para enviar nuestros ficheros en formato binario para analizarlosen el motor de VirusTotal, en el caso de que el md5 no esté registrado en su base de datos. Estos dos métodosnos devuelven un objeto llamada ScanInfo, que implementa métodos de tipo get para cada uno de los camposinformativos que nos ofrece el servicio VirusTotal sobre el fichero tras realizar el análisis.

Código 4.4 Framento del desarrollo del cargador de VirusTotal que muestra el uso del método getScanReport.

import com.kanishka.virustotal.dto.{FileScanReport, ScanInfo}import com.kanishka.virustotal.exception.{APIKeyNotFoundException}import com.kanishka.virustotalv2.{VirustotalPublicV2Impl}

object VirusTotalLoader extends FileProcessor{

val data = mutable.Map.empty[String, Any]

val virusTotalRef = try {Some(new VirustotalPublicV2Impl())

} catch {case ex: APIKeyNotFoundException =>println("ApiKey no encontrada")None

}

virusTotalRef match {case Some(virusTotal) =>try {val report: FileScanReport = virusTotal.getScanReport(key)

if (report.getTotal != null) {data += ("md5" -> report.getMd5)data += ("sha1" -> report.getSha1)data += ("positives" -> report.getPositives)

}}

}}

24 Capítulo 4. Implementación del Sistema

Figu

ra4.

3Arquitecturarb-spark.

4.3 Implementacion de rb-Spark 25

Metascan

Para el desarrollo del cargador de Metascan se ha implementado un cliente en Scala de servicio web RESTpara la API pública de Java de Metascan.Para ello se ha hecho uso de la libreria para conexiones de red y lalibreria de entrada y salida de Java.

La API de Metascan para Java nos ofrece un recurso URL para la consulta del hash del fichero y otro parael envio del fichero en formato binario.

Código 4.5 Recursos URL para la consulta al servidor de Metascan.

val hashURL = "https://hashlookup.metadefender.com/v2/hash/"val fileURL = "https://scan.metadefender.com/v2/file"

Para comenzar la comunicación primero instanciamos un nuevo objeto de la clase URL, formado porel recurso que identifica a una petición de tipo hash al servidor, acompañado del md5 identificador de losficheros que forman el fichero secuencial. Tras ésto llamamos al método openConnection del objeto URLpara abrir la conexión con el servidor y forzamos la conversión a un objeto de tipo HttpURLConnection.

Código 4.6 Establecimiento de conexión con Metascan.

val objhashURL = new URL(hashURL + key)

val con = objhashURL.openConnection().asInstanceOf[HttpURLConnection]

Una vez que ya se tiene un objeto de tipo HttpURLConnection se llama a los métodos setRequestMethodpara indicarle que se va a realizar una petición de tipo GET, a setRequestProperty para enviar al servidor elcampo apikey, que es una clave identicadora que ha sido previamente obtenida tras el registro en la comunidadde Metascan, y por último al método getResponseCode, que nos devuelve un número que nos indica si laconexión se ha realizado o no con éxito. Si todo ha ido de forma correcta se obtendrá un 200 como respuestay se hace uso de la clase BufferReader para leer la información que nos devuelve sobre el fichero.

Código 4.7 Envio del md5 del fichero a consultar y recepción de las respuesta.

con.setRequestMethod("GET")con.setRequestProperty("apikey", apiKey)

val responsecode = con.getResponseCode

if (responsecode == 400) {System.out.println("CODE 400 Bad Request - Unsupported HTTP method or

ivalid HTTP request (e.g., empty body)")data += ("msg" -> "Unsupported HTTP method or invalid HTTP request")

} else if (responsecode == 401) {..} else if (responsecode == 200) {

val br = new BufferedReader(new InputStreamReader(con.getInputStream))val response = Stream.continually(br.readLine()).takeWhile(_ != null).

mkString("\n")

br.close()con.disconnect()

26 Capítulo 4. Implementación del Sistema

Si la información devuelta por el servicio tras la consulta por el md5 nos indica que ese fichero no seencuentra en su base de datos, procedemos al envio del fichero para su análisis. Para ello volvemos a instanciarun objeto de la clase URL, esta vez con el recurso que identifica al envio de un fichero, llamamos a losmétodos openConnection y forzamos la conversión a un objeto HttpURLConnection. Posteriormente se llamaa los métodos setRequestMethod, esta vez indicando que se a realizar una peticion de tipo POST, pues se va aenviar el fichero a través de la web en el campo body del método POST, y al método setRequestProperty paravolver a indicar la clave identificadora antes del envio. Para la realización del envio se hace uso de la claseDataOutPutStream recorriendo el fichero con un bucle for escribiendo byte a byte en el stream de datos.

Código 4.8 Envio del fichero a Metascan para su análisis en formato binario.

val con = objfileURL.openConnection().asInstanceOf[HttpURLConnection]

con.setRequestMethod("POST")con.setRequestProperty("apikey", apiKey)con.setDoOutput(true)

val destineMeta = new DataOutputStream(con.getOutputStream)

for (b <- value) {destineMeta.writeByte(b)

}

destineMeta.flush()destineMeta.close()

val responsecode = con.getResponseCode

Si la conexión se ha realizado con éxito, con este tipo de petición el servicio nos delvolverá la informaciónsobre el fichero en formato JSON. Se hará uso de la libreria ObjectMapper para parsear el objeto JSON yconvertirlo en un tipo Mapa de pares cadena de caracteres y Any.

Código 4.9 Recepción y parseo del objeto JSON recibido.

}else if (responsecode == 200) {

val br = new BufferedReader(new InputStreamReader(con.getInputStream))val response = Stream.continually(br.readLine()).takeWhile(_ != null).

mkString("\n")

br.close()

val mapper = new ObjectMapper()mapper.registerModule(DefaultScalaModule)val fileJson = mapper.readValue(response, classOf[mutable.Map[String,

Any]])

data ++= fileJson

}

Clamscan

Para el desarrollo del cargador de Clamscan, por ser un servicio de Linux se ha hecho uso de la libreria demanejo de sockets y de la clase DataOutPutStream de la librerí a entrada y salida de Java.

4.3 Implementacion de rb-Spark 27

Para ello el primer paso es la conexión con el servicio mediante el uso de sockets, se ha usado el puerto3310 y la dirección IP de la máquina local, habiendo instalado previamente y en este caso el demonio declamscan en la propia máquina.

Código 4.10 Establecimiento de la conexión con Clamscan a través de sockets de red.

val port: Int = 3310val ip = "127.0.0.1"

def configureSocket() = {val socket = new Socketsocket.connect(new InetSocketAddress(ip, port))socket

}

val socket = configureSocket()

Para proceder al envío del fichero a Clamscan creamos un nuevo objeto de la clase DataOutputStream,pasándole como argumento de entrada el socket que hemos configurado. Debemos enviar en primer lu-gar la cadena de caracteres "zINSTREAM" y un entero con la longitud del fichero que vamos a mandar.Posteriormente se manda el fichero en formato binario y se termina el envío indicando un 0.

Código 4.11 Envio del fichero en formato binario al servicio Clamscan.

val destineClam = new DataOutputStream(socket.getOutputStream)

destineClam.writeBytes("zINSTREAM\0")destineClam.writeInt(value.length)destineClam.write(value)destineClam.writeInt(0)destineClam.flush()

Para recibir la información del fichero sumistrada por clamscan se hace uso de un bucle while funcionaldentro de una nueva instancia del objeto de la clase cadena de caracteres. Este servicio únicamente suministrael nombre del fichero si corresponde con un fichero malware o un OK si el fichero está limpio.

Código 4.12 Recepción información sobre el fichero sumunistrada por CLamscan.

val response = new String(Iterator.continually(fromClam.read).takeWhile(_ != -1).map(_.toByte).toArray)

El código completo de los 3 cargadores malware se encuentra en el ANEXO.

Operaciones de tipo batch

Para cada cargador desarrollado se realiza una operación de tipo map sobre el fichero secuencia. Dentro deésta se llama al método processFile de los 3 objetos correspondientes con los cargadores malware, de maneraque obtenemos un RDD para cada uno con un conjunto de pares clave-valor, en el que la clave sigue siendoel md5 del fichero y el valor una variable de tipo mapa de pares cadena de caracteres y Any, que contiene lainformación devuelta por cada cargador.

28 Capítulo 4. Implementación del Sistema

Código 4.13 Ejemplo Salida Cargador VirusTotal.

val salidaVirusTotal = readme1.map( x => (x._1.toString, VirusTotalLoader.processFile((x._1.toString), x._2.copyBytes()))

Figura 4.4 RDDs correspondientes a cada uno de los cargadores.

Una vez que se tiene un RDD con la información devuelta por cada cargador, se realiza una operación detipo union sobre ellos de manera que los unificamos en un solo RDD, con las claves identificadoras repetidas.Posteriormente con una operación de tipo groupByKey se organizan los datos con claves identificadorasúnicas, y como valor un tipo Iterable de Scala con la información devuelta por los tres cargadores. Por último,se realiza una operación de tipo map para identificar la clave como md5 y convertir el tipo Iterable en un tipoLista formada por los tres mapas con la información de cada cargador.

Código 4.14 Operación de tipo batch general de la aplicación.

val salida = sc.union(salidaVirusTotal,salidaClamScan,salidaMetasScan).groupByKey().map(x => ( ("md5" -> x._1) ,x._2.toList))

Figura 4.5 Operacion union y groupByKey sobre los RDDs.

4.3 Implementacion de rb-Spark 29

Serialización

Una vez que se tiene la información procesada y organizada de una manera adecuada, debemos serializar losdatos a formato JSON de manera que puedan ser almacenados en MongoDB como documentos. Para elloes necesario convertir el RDD de pares clave-valor con el que se ha trabajado, a un RDD de tipo String. Seha utilizado la libreria json4s para este propósito por implementar la serialización de mapas de tipo parescadena de caracteres y Any, frente a la otra alternativa JacksMapper, la cual ofrece un rendimiento del ordende cien veces inferior.Por tratarse json4s de una libreria externa, no se puede utilizar ésta dentro de un operación de tipo map,

pues una operación de este tipo aplica el método que se esté usando a cada elemento del RDD sin importarcomo este distribuido a lo largo del clúster, lo que en una ejecución en un entorno distribuido entre variosnodos provocaria un error de serialización del objeto. Sin embargo con la operación mapPartitions se aplicael método a cada partición del RDD en el clúster por separado, por lo que es la operación adecuada a utilizarpara este objetivo.

Código 4.15 Transformación de los datos en formato JSON con la libreria json4s.

val json = salida.mapPartitions{x =>{implicit val formats = org.json4s.DefaultFormatsx.map(y =>Serialization.write(y)

)}

}

Almacenamiento

Tras la ingesta, procesamiento y conversión de los datos al formato deseado, el siguiente paso el almacenarlosen la base de datos MongoDB para que puedan ser consultados de una manera eficaz. Para ello se hace usodel conector MongoDB-Spark.Primero se debe convertir el RDD de tipo String a tipo documento de MongoDB. Posteriormente em-

bebemos la información de la base de datos en una variable de tipo mapa en la que indicamos que se va aescribir en la base de datos, el nombre de la colección donde se va a hacer y el nombre de la base de datos.Finalmente llamando al método save del contexto MongoSpark pasándole como argumento el documento quequeremos almacenar y la variable con la configuración, se lleva a cabo el almacenamineto de la informaciónen MongoDB.

Código 4.16 Almacenamineto de los datos en MongoDB.

val documento = json.map(x=> Document.parse(x))

val writeConfig = WriteConfig(Map("collection" -> "maware_analysis","writeConcern.w" -> "majority","db" -> "malware_database"), Some(writeConf))

MongoSpark.save(documento, writeConfig)

5 Pruebas

You can have data without infomation, but you cannot have infor-mation without data

Daniel Keys Moran (computer programmer and sciencefiction writer)

En este capítulo se mostrarán las distintas pruebas realizadas para comprobar el correcto funcionamientode la aplicación. Para ello en primer lugar se define el escenario planteado, para luego mostrar los

resultados y su visualización a través de MongoDB Compass y de un report generado con la herramientaPentaho. Por último, se presentará una conclusión en base a los resultados obtenidos.

5.1 Escenario

En esta apartado se describe el entorno de laboratorio desplegado por el equipo de redBorder y que será elutilizado para las pruebas. Se trata de una red conmutada con cinco elementos principales que se definen acontinuación:

Figura 5.1 Escenario del laboratorio para las pruebas.

• Manager : Se trata del elemento central en el cual se recibe, se trata y se visualiza toda la información.Posee un servidor ICAP en el cual recibe las peticiones del proxy web.

• Sensor IPS : Sensor por el que pasa el tráfico de red que se va a analizar. Funcionando como un IDS/IPSes capaz de detectar patrones de tráfico correspondiente a posibles ataques o malware. Es capaz deinterceptar ficheros de los protocolos HTTP, FTP, SMTP y SMB.

31

32 Capítulo 5. Pruebas

• Mail Gateway : Sensor por el que pasa el tráfico de correo SMTP. Su funcionamiento es similar a unMTA (Mail Transfer Agent), es decir cada vez que recibe un e-mail lo reenvía al servidor de correocorrespondiente.

• EndPoints : Formado por varios equipos desde donde se enviarán los mails con malware y donde seaccederá a distintas paginas web que permitan la descarga de fichero malicioso.

• Mail Server : Servidor de correo electrónico utilizado para la recepción del correo electrónico inter-ceptado por el Mail Gateway y autorizado para su reenvío.

5.2 Resultados y visualización

En este apartado se van a mostrar los resultados de las pruebas. Se han escogido 11 ficheros, nueve de ellosmalware y dos archivos que no contienen ningún código malintencionado.

Como se detalló en capítulos anteriores, estos ficheros en forma de fichero secuencial son la entrada de laaplicación desarrollada, y los resultados son almacenados en la base de datos MongoDB. Una vez finalizado elanálisis procedemos a generación de un report mediante el conjunto de herramientas que nos ofrece Pentaho.

Para la creación del report el primer paso en la integración de los datos guardados en MongoDB en laplataforma de Pentaho. Para ello utilizamos la herramienta de integración de datos de Pentaho Spoon. Lospasos a realizar son configurar la conexión con la base de datos y consultar los datos que nos interesan parael report. En este caso simplemente si el fichero es o no malware según el cargador consultado, y en el casode clamscan el nombre teórico del fichero considerado malicioso. Ésto es debido a que es el único tipo deinformación que devuelve esta herramienta.

Figura 5.2 Integración de datos con herramienta spoon.

Una vez que los datos son cargados en Pentaho se utiliza la herramienta pentaho-report-designer parageneración del report deseado, en este caso se ha elegido identificar el fichero con su md5 y una plantilla detipo maple. El resultado puede ser exportado como report a varios formatos como HTML, PDF, EXCEL oCSV.

5.2 Resultados y visualización 33

Figura 5.3 Report de resumen de los datos generado por Pentaho.

Por otro lado, para una visualización más completa y detallada de los datos generados se he hecho uso deMongoDB Compass, que nos presenta una vista gráfica de los documentos BSON alamcenados en MongoDB.

Figura 5.4 Pantalla inical MongoDB Compass.

El uso de esta herramienta nos permite explorar el esquema de los documentos BSON dentro de cadacolección, así como entender la frecuencia y tipos de los datos que se encuentran en él.

34 Capítulo 5. Pruebas

Figura 5.5 Vista detallada para un fichero filtrado por su sha1.

5.3 Conclusiones Pruebas

De los nueve ficheros que contenían malware, ocho de ellos han sido detectados por virustotal. Eso nosda un efectividad de 88,88% por parte de virustotal. Por otro lado metascan ha detectado como malwaresiete ficheros, lo que supone una efectividad de 77,77% . Por último clamscan ha detectado tan sólo cuatro ,menos de la mitad, debido a que este antivirus es usado mayoritariamente en servidores de correo electrónicoaccedidos desde Windows, por lo que detecta sobretodo malware para este sistema operativo. De hecho hadetectado el fichero que no fue considerado malware por metascan, que corresponde a un fichero malwarepara Windows comprimido.

No se ha dado ningún caso de falsos positivos en las pruebas realizadas.

5.3 Conclusiones Pruebas 35

Tabl

a5.

1Re

sumen

Pruebas.

MD5

Tipo

deFichero

Tamaño

del

fichero

¿malware?

Viru

sTotal

Metascan

Clam

scan

0af64f3d6f481e9c4169b6be7ab02fc1

mp3

6.4KB

NO

0/55

0/42

-83cb560bb095c5025f00678c07dba2e2

Win32

EXE

308.5KB

SI50/57

30/42

-c667e71be09113850e8f3bd2ca52bff

5HTM

L400bytes

SI0/54

0/42

-5537d2d934bd96ecf0d00b25a3cb9967

Win32

DLL

424.5KB

SI51/58

34/42

-1c4f4d0aba45c4e2b01aa63341f2be09

5OpenO

ffice

41.7KB

NO

0/56

0/42

-5f10f9b39a2190f1204bf5cd5c50d1a6

Win32

EXE

48.0KB

SI55/58

37/42

Win.Trojan.Zb

ot-

24065

fb221f2cbdaf0a96c8b96955b29f40bd

ZIP

38.4KB

SI47/57

0/42

Win.Trojan.Zb

ot-

24065

7c7611beb3a7758462c0426b9438d6a15

Win32

EXE

183.0KB

SI50/58

34/42

Win.Trojan.Ba

nker-

30109

b46c792c8e051bc5c9d4cecab96e4c30

Win32

DLL

104.0KB

SI23/57

10/42

-aac56baff

4be3db02378f11b9844dcb5

Win32

DLL

60.0KB

SI38/56

24/42

-004ea7a275cef2c58fc297185d405fd8

Win32

EXE

513.5KB

SI47/56

27/41

Win.Trojan.Bu

zus-

17110

6 Presupuesto

There are risks and costs to a program of action, but they are farless than the long range cost of comfortable inaction.

John F. Kennedy

En este capítulo se calcula una estimación del precio correspondiente a la realización del proyecto rb-sparkdetallado en este documento.

Tabla 6.1 Presupuesto diseño y desarrollo del proyecto.

Periodo de tiempo Numero de horas Precio/Hora TotalPracticas curriculares en redBoder 220 20 €/hora 4400 €Junio2016-Septiembre2016 500 20 €/hora 10000 €Total 720 14400 €

Tabla 6.2 Presupuesto equipamiento utilizado.

Equipamiento Cantidad Precio TotalEntorno de virtualizacion deservidores

1 4000 € 4000 €

PC para desarrollo del soft-ware

1 700 € 700 €

Total 4700 €

Esto nos da un total de 19100 €.

37

7 Conclusiones

As the world is increasingly interconnected, everyone shares theresponsability of securing cyberspace

Newton Lee (Computer Scientist)

7.1 Conclusión

En este trabajo se ha desarrollado una aplicación escrita en el lenguaje de programación Scala para ApacheSpark, cuyo objetivo es la identificación de ficheros en una red o sistema y clasificarlos en función de

si su contenido es o no malintencionado. Para ello se ha estudiado el producto de redBorder que realiza estafunción, así como el proyecto binaryPig de la empresa Endgame. Se ha aprovechado también la infraestructurade redBorder para la captación de muestras de ficheros maliciosos que han sido entrada del proyecto.

En este memoria se han introducido primero conceptos clave para el desarrollo del proyecto. Luego se handetallado las distintas herramientas usadas, para finalmente explicar el diseño y desarrollo del proyecto conunos resultados finales en base a un conjunto de pruebas realizadas.

7.2 Líneas de desarrollo

Este trabajo se puede desarrollar en diversos frentes, a continuación se explican los tres que considero másevidentes:

El primero de ellos sería añadir más herramientas de análisis de malware, especialmente de análisisdinámico como Cuckoo Sandbox o de detección de ficheros ofuscados como Fuzzy Hash.

Otra mejora podría ser el diseño e implementación de un workflow o flujo de trabajo, en el cual seprogramara el orden de ejecución de cada cargador y se implementara un algoritmo que decidiría si el ficheroes o no peligroso para nuestro sistema. Esto se podría llevar a cabo con el propio gestor de flujos de trabajode Spark, o con Apache Oozie ejecutando Spark sobre el componente YARN de Hadoop.

Por último se podrían aplicar técnicas de machine learning para la detección automática de ficherosmalware. Se podría realizar implimentando algoritmos de clustering para identificar nuevas clases de ficheroscon compartamiento similar o con algoritmos de clasificación para asignar malware desconocido a estasclases [20]. Se podría llevar a cabo con la libreria de machine learning de Spark MLlib.

39

8 ANEXOS

41

Anexo I

8.1 Código Fuente del Proyecto

8.1.1 Cargador VirusTotalLoader

Código 8.1 Implementación Cargador VirusTotal.

package com.pfc.loaders.virustotal

import com.pfc.loaders.FileProcessorimport java.io.File

import com.kanishka.virustotal.dto.{FileScanReport, ScanInfo}import com.kanishka.virustotal.exception.{APIKeyNotFoundException,

QuotaExceededException, UnauthorizedAccessException}import com.kanishka.virustotalv2.{VirusTotalConfig, VirustotalPublicV2Impl}

import scala.collection.mutableimport scala.collection.JavaConverters._

/*** Created by Juanlu on 12/3/2016.*/

object VirusTotalLoader extends FileProcessor{

val data = mutable.Map.empty[String, Any]val apiKey = "1

edc806644f93242a2579a2c09703f4088afbdfd31864f33415058b19af3a727"

VirusTotalConfig.getConfigInstance.setVirusTotalAPIKey(apiKey)

val virusTotalRef = try {Some(new VirustotalPublicV2Impl())

} catch {case ex: APIKeyNotFoundException =>println("ApiKey no encontrada")None

}

42

8.1 Código Fuente del Proyecto 43

override def processFile(key: String, value: Array[Byte]): mutable.Map[String, Any] = {

virusTotalRef match {case Some(virusTotal) =>try {val report: FileScanReport = virusTotal.getScanReport(key)

if (report.getTotal != null) {data += ("md5" -> report.getMd5)data += ("sha1" -> report.getSha1)data += ("vt_link" -> report.getPermalink)data += ("vt_scan_date" -> report.getScanDate)data += ("vt_scan_id" -> report.getScanId)data += ("engines_positive" -> report.getPositives)data += ("engines_total" -> report.getTotal)data += ("msg" -> report.getVerboseMessage)

if (report.getPositives.equals(0)) {// Compara objetosdata.put("malware", "N/A")

}

val score = (report.getPositives * 100 / report.getTotal)data += ("score" -> score)

val scans = report.getScans.asScala // mutable.Map[String,VirusScanInfo]//util.Map[String,VirusScanInfo]

val engines = List(mutable.Map.empty[String, Any])

if (scans != null) {for ((engineName, virusInfo) <- scans) {val engine = mutable.Map.empty[String, Any]val result = if (virusInfo.getResult == null) "N/A" else

virusInfo.getResult

engine += ("engine" -> engineName)engine += ("result" -> result)engine += ("version" -> virusInfo.getVersion)engines ++ engine // Add element to List

}}data.put("engines", engines)

} else {val scanInformation: ScanInfo = virusTotal.scanFile(binaryFile)

data += ("md5" -> scanInformation.getMd5)data += ("sha1" -> scanInformation.getSha1)data += ("vt_link" -> scanInformation.getPermalink)data += ("vt_scan_id" -> scanInformation.getScanId)data += ("msg" -> scanInformation.getVerboseMessage)data += ("malware" -> "N/A")data += ("score" -> -1L)

}

44 Capítulo 8. ANEXOS

} catch {case ex: UnauthorizedAccessException =>data += ("msg" -> "Unuthorized access")data += ("score" -> -1L)data += ("malware" -> "N/A")

case ex: QuotaExceededException =>

if (true) {// LLamada !isAnalized(hash, scoreName)try {val scanInformation = virusTotal.scanFile(binaryFile)

data += ("md5" -> scanInformation.getMd5)data += ("sha1" -> scanInformation.getSha1)data += ("vt_link" -> scanInformation.getPermalink)data += ("vt_scan_id" -> scanInformation.getScanId)data += ("msg" -> scanInformation.getVerboseMessage)data += ("malware" -> "N/A")data += ("score" -> -1L)

} catch {case ex: UnauthorizedAccessException =>data += ("msg" -> "Unauthorized access!")data += ("score" -> -1L)data += ("malware" -> "N/A")

case ex: QuotaExceededException =>data += ("msg" -> "Signature scan limit reached, try again

later")data += ("score" -> -1L)data += ("malware" -> "N/A")

}} else {data += ("msg" -> "Signature scan limit reached, try again later")data += ("score" -> -1L)data += ("malware" -> "N/A")

}}

case None => println("none")}data += ("loader" -> "virustotal")data += ("timestamp" -> System.currentTimeMillis / 1000)

data}

}

8.1.2 Cargador MetascanLoader

Código 8.2 Implementación Cargador Metascan.

import java.io.{BufferedReader, DataOutputStream, File, InputStreamReader}import java.net.{HttpURLConnection, URL}

8.1 Código Fuente del Proyecto 45

import java.security.SecureRandomimport java.security.cert.X509Certificateimport javax.net.ssl._

import com.fasterxml.jackson.databind.ObjectMapperimport com.fasterxml.jackson.module.scala.DefaultScalaModule

import scala.collection.mutable

/*** Created by Juanlu on 19/5/2016.*/

object MetascanLoader extends FileProcessor{

val apiKey = "58e0aff18dce58affce1ee346dfac1b0"val hashURL = "https://hashlookup.metadefender.com/v2/hash/"val fileURL = "https://scan.metadefender.com/v2/file"val malware = "

a7ccc5915baf49a23ecbbabad9c47c2a5fdb5cfaf98942449417f862662065be"

val data = mutable.Map.empty[String, Any]

override def processFile(key: String, value: Array[Byte]): mutable.Map[String, Any] = {

val objhashURL = new URL(hashURL + key)

val con = objhashURL.openConnection().asInstanceOf[HttpURLConnection]con.setRequestMethod("GET")con.setRequestProperty("apikey", apiKey)

val responsecode = con.getResponseCode

if (responsecode == 400) {System.out.println("CODE 400 Bad Request - Unsupported HTTP method or

invalid HTTP request (e.g., empty body)")data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Unsupported HTTP method or invalid HTTP request")

} else if (responsecode == 401) {System.out.println("CODE 401 Invalid API key - Either missing API key or

invalid API is passed.")data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Invalid API key")

} else if (responsecode == 403) {System.out.println("CODE 403 Signature lookup limit reached, try again

later - The hourly hash lookup limit has been reached for this APIkey.")

data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Signature lookup limit reached, try again later")

} else if (responsecode == 200) {

val br = new BufferedReader(new InputStreamReader(con.getInputStream))

46 Capítulo 8. ANEXOS

val response = Stream.continually(br.readLine()).takeWhile(_ != null).mkString("\n")

// val response = Stream.continually(br.readLine()).takeWhile(_ != null).toString().substring(7)

br.close()con.disconnect()

if (response.contains("Not Found")) {data += ("malware" -> "N/A")data += ("socore" -> -1L)

val objfileURL = new URL(fileURL)

// Bypasses both client and server validation.object TrustAll extends X509TrustManager {val getAcceptedIssuers = null

def checkClientTrusted(x509Certificates: Array[X509Certificate], s:String) = {}

def checkServerTrusted(x509Certificates: Array[X509Certificate], s:String) = {}

}

// Verifies all host names by simply returning true.object VerifiesAllHostNames extends HostnameVerifier {def verify(s: String, sslSession: SSLSession) = true

}

val sSLContext = SSLContext.getInstance("SSL")sSLContext.init(null, Array(TrustAll), new SecureRandom())

HttpsURLConnection.setDefaultSSLSocketFactory(sSLContext.getSocketFactory)

HttpsURLConnection.setDefaultHostnameVerifier(VerifiesAllHostNames)

val con = objfileURL.openConnection().asInstanceOf[HttpURLConnection]

con.setRequestMethod("POST")con.setRequestProperty("apikey", apiKey)con.setDoOutput(true) //Send bytes to body in POST

val destineMeta = new DataOutputStream(con.getOutputStream)

for (b <- value) {destineMeta.writeByte(b)

}

destineMeta.flush()destineMeta.close()

val responsecode = con.getResponseCode

if (responsecode == 400) {System.out.println("CODE 400 Bad Request - Unsupported HTTP method or

invalid HTTP request (e.g., empty body)")

8.1 Código Fuente del Proyecto 47

data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Unsupported HTTP method or invalid HTTP request")

} else if (responsecode == 401) {System.out.println("CODE 401 Invalid API key - Either missing API key

or invalid API is passed.")data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Invalid API key")

} else if (responsecode == 403) {System.out.println("CODE 403 Signature lookup limit reached, try again

later - The hourly hash lookup limit has been reached for thisAPI key.")

data += ("malware" -> "N/A")data += ("score" -> -1L)data += ("msg" -> "Signature lookup limit reached, try again later")

} else if (responsecode == 200) {val br = new BufferedReader(new InputStreamReader(con.getInputStream))val response = Stream.continually(br.readLine()).takeWhile(_ != null).

mkString("\n")

br.close()

val mapper = new ObjectMapper()mapper.registerModule(DefaultScalaModule)val fileJson = mapper.readValue(response, classOf[mutable.Map[String,

Any]])

data ++= fileJson

}con.disconnect()

} else {

val mapper = new ObjectMapper()mapper.registerModule(DefaultScalaModule)

val fileJson = mapper.readValue(response, classOf[mutable.Map[String,Any]])

fileJson.get("file_id") match {case None =>case Some(value) =>val devolver = value.asInstanceOf[String]data += ("ms_file_id" -> devolver)

}

data += ("ms_file_id" -> fileJson.get("file_id"))

val fileInfo = fileJson("file_info").asInstanceOf[Map[String, Any]]data ++= fileInfo

val scanResult = fileJson.get("scan_results")

scanResult match {case None => println("None")

48 Capítulo 8. ANEXOS

case Some(value1) =>val mapa_scan_results = value1.asInstanceOf[Map[String, Any]]val status = mapa_scan_results.get("scan_all_result_a").toString.

toLowerCase()val engines_total = mapa_scan_results.get("total_avs")data += ("status" -> status)data += ("engines_total" -> engines_total)

val scans = mapa_scan_results.get("scan_details")

scans match {case None => println("None")case Some(value2) =>val mapa_scan_details = value2.asInstanceOf[Map[String, Any]]val engines = List(mutable.Map.empty[String, Any])val total = if (mapa_scan_details.isEmpty) 1L else

mapa_scan_details.sizevar detected: Long = 0L

for ((engineName, metascanInfo) <- mapa_scan_details) {val engine = mutable.Map.empty[String, Any]//val scan = mapa_scan_details.get(engineName).asInstanceOf[

Map[String, Any]]

val scan = mapa_scan_details.get(engineName)

scan match {case None => println("None")case Some(value3) =>val mapa_scan = value3.asInstanceOf[Map[String, Any]]val result = if (mapa_scan_details.get("threat_found") ==

null) "N/A"else mapa_scan.get("threat_found").toString

if (result != "N/A") {detected += 1

}

engine += ("engine" -> engineName)engine += ("result" -> result)engine += ("version" -> mapa_scan.get("def_time"))engines ++ engine

}}data += ("score" -> detected * 100 / total)data += ("engines" -> engines)

}}

}}data += ("loader" -> "metascan")

data += ("timestamp" -> System.currentTimeMillis() / 1000)data

}}

8.1 Código Fuente del Proyecto 49

8.1.3 Cargador ClamScanDaemonLoader

Código 8.3 Implementación del cargador Clamscan.

package com.pfc.loaders.av

import com.pfc.loaders.FileProcessorimport java.io._import java.net.{InetSocketAddress, Socket}

import scala.collection.mutable

/*** Created by Juanlu on 4/6/2016.*/

object ClamScanDaemonLoader extends FileProcessor{

val data = mutable.Map.empty[String, Any]

override def processFile(key: String, value: Array[Byte]): mutable.Map[String, Any]= {

val port = 3310val ip = "127.0.0.1"

def configureSocket() = {val socket = new Socketsocket.connect(new InetSocketAddress(ip, port))socket

}

val socket = configureSocket()

try {val destineClam = new DataOutputStream(socket.getOutputStream)

val fromClam = socket.getInputStream

destineClam.writeBytes("zINSTREAM\0")destineClam.writeInt(value.length)destineClam.write(value)destineClam.writeInt(0)destineClam.flush()

val response = new String(Iterator.continually(fromClam.read).takeWhile(_ != -1).map(_.toByte).toArray)

data += ("loader" -> "clamscan")

try {destineClam.close()socket.close()

50 Capítulo 8. ANEXOS

} catch {case ex: IOException => println("Error closing the connection")

}val parseo = response.split(" ") // Parse String returned by clamscan

stream: OKdata +=("clamscan" -> parseo(1))

} catch {case ex: IOException => data += ("clamscan" -> "General Error")

}data

}}

8.1.4 Objeto Main de la aplicación

Código 8.4 Main de la aplicación.

package loaders

import java.io.{File, FileOutputStream}import java.util.UUID

import loaders.virustotal.VirusTotalLoaderimport loaders.av.ClamScanDaemonLoaderimport org.apache.hadoop.fs.FileUtilimport org.apache.hadoop.io.{BytesWritable, Text}import org.apache.spark.{SparkConf, SparkContext}import com.mongodb.spark.{MongoSpark, _}import com.mongodb.spark.config.WriteConfigimport com.mongodb.spark.rdd.MongoRDDimport org.bson.{BSON, Document}

import scala.collection.mutableimport org.json4s.jackson.Serialization

/*** Created by Juanlu on 29/2/2016.*/

object AppSpark extends java.io.Serializable {def main(args: Array[String]) {

val conf = new SparkConf().setAppName("App Spark")val sc = new SparkContext(conf)

val readme = sc.sequenceFile[Text, BytesWritable]("hdfs:///1457606711415-7a1af9a941046bf0e9952a28f3dfa2bd.seq")

val salidaVirusTotal = readme1.map( x => (x._1.toString, VirusTotalLoader.processFile((x._1.toString),x._2.copyBytes()))

8.1 Código Fuente del Proyecto 51

val salidaClamScan = readme1.map( x => (x._1.toString, ClamScanDaemonLoader.processFile((x._1.toString),x._2.copyBytes()))

val salidaMetasScan = readme1.map(x => (x._1.toString, MetascanLoader.processFile(x._1.toString,x._2.copyBytes)))

val salida = sc.union(salidaVirusTotal,salidaMetascan,salidaClamscan).groupByKey().map(x => ( ("hash" -> x._1) ,x._2.toList))

val json = salida.mapPartitions{x =>{implicit val formats = org.json4s.DefaultFormatsx.map(y =>Serialization.write(y)

)}

}

val documento = json.map(x => Document.parse(x))

val writeConf = WriteConfig(sc)

val writeConfig = WriteConfig(Map("collection" -> "maware_analysis","writeConcern.w" -> "majority","db" -> "malware_database"), Some(writeConf))MongoSpark.save(documento, writeConfig)

}}

Anexo II

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder

52

How to improve your Big Data processing using Apache Spark  

  El Big Data y el análisis y procesamiento de grandes volúmenes de datos ya no es un concepto abstracto en el que deberían invertir las empresas a largo plazo. Hoy es una realidad y necesidad de cualquier compañía aprovechar el potencial de las nuevas herramientas que van aparecido para obtener una ventaja competitiva. Apache Hadoop fue el inicio de esta gran revolución, ha sido la tecnología Big Data estrella durante todo este tiempo, pero las necesidades han cambiado y sus limitaciones sobre todo en términos de velocidad son cada vez más evidentes. En este artículo se hablará sobre Apache Spark, una de las tecnologías más punteras de la actualidad, se explicará su origen, funcionalidad y casos de usos, se valorarán las ventajas respecto a Hadoop, se explicarán las importantes mejoras en su segunda versión y por último se comentará el papel que puede tener en los próximos años.       

 

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 53

¿Qué es Apache Spark?  Apache Spark es un motor de procesamiento paralelo en memoria o en disco, distribuido, escalable y  open source, con soporte para procesamiento de datos estructurados, semi estructurados y no estructurados. Incluye librerías específicas para tratar datos estructurados  (Spark SQL),  streaming de datos (Spark Streaming), machine  learning (MLib) y computación sobre grafos (GraphX). Todo ello con APIs  para crear aplicaciones de manera sencilla en los lenguajes de programación Scala, Python, Java y R.   

  

Inicialmente desarrollado como un subproyecto de Apache Hadoop en los laboratorios AMPLab de la Universidad de Berkeley (California) en 2009, fue liberado bajo licencia BSD en 2010 y más tarde en 2013 donado a la comunidad Apache, donde actualmente es uno de los proyectos más relevantes y con mayor proyección de futuro.  

Apache Spark vs Apache Hadoop  Aunque como se mencionó anteriormente Spark comenzó siendo una tecnología complementaria y dependiente de Hadoop, hoy en dia es un proyecto maduro, autónomo y con mejoras considerables de rendimiento respecto al motor de procesamiento MapReduce, concretamente diez veces más rápido en procesamiento paralelo en disco y hasta cien veces en procesamiento en memoria.   

54 Capítulo 8. ANEXOS

Estas considerables mejoras sumadas a las librerías nativas que incorpora (Streaming, Machine Learning, Graph, etc.) junto con la capacidad para trabajar con su propio cluster manager,sobre YARN, MESOS o en la cloud está provocando que cada vez más empresas comiencen a utilizar Spark junto con Hadoop, e incluso en algunos casos prescindiendo por completo de Hadoop.   

    

¿Por qué Spark es tan revolucionario?  Una de las  grandes innovaciones  que  hizo que Spark irrumpiera con tanta fuerza en el mundo Big Data fue el cambio que introdujo en la aplicación del paradigma MapReduce.  Para realizar una operación de computación iterativa con Hadoop, primero se leen los datos del disco (en este caso de HDFS), se ejecuta el trabajo, se escribe el resultado en disco de nuevo, se vuelve a leer y así sucesivamente para cada iteración. Apache Spark, sin embargo presenta un modelo de procesamiento eficiente compartiendo los datos en memoria en cada iteración.      

  Como consecuencia de lo anterior, el rendimiento de Apache Spark en algoritmos de regresión y operaciones de tipo iterativo ampliamente 

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 55

usadas en machine learning es notablemente superior al de Apache Hadoop.  

 El procesamiento de datos en memoria también presenta una gran ventaja a la hora de realizar queries multidimensionales (Cubos OLAP Business Inteligence) respecto al paradigma tradicional MapReduce, de manera que, Spark cachea en memoria el datasets que está procesando eliminando las costosas operaciones en tiempo de I/O en disco así como mejora mejorando considerablemente el rendimiento y la velocidad.  

 La  importante ventaja que supone el procesamiento en memoria no es la única mejora que merece ser destacada, es relevante conocer también la flexibilidad y mayor eficiencia del paradigma de Spark para crear flujos de datos (workflows).  En Hadoop  sólo se puede usar el esquema Map ­> Shuffle ­> Reduce, teniendo que crear nuevos trabajos para esquemas diferentes. Apache Spark propone unos flujos de trabajo basados en grafos acíclicos dirigidos (DAG), que permiten esquemas de flujos dinámicos y reducen los tiempos de ejecución. Además de la gran ventaja anterior, Spark tiene definidas muchas más operaciones distintas a las habituales map 

56 Capítulo 8. ANEXOS

y reduce, que se clasifican en acciones (reduce, countByValue, foreach, etc.) y transformaciones (map, filter, union,...), aportando mucha más versatilidad.   

Apache Spark 2.0: Madurez Tecnológica   Reynold Xin (Co­founder and Chief Architect for Spark at Databricks) en la presentación de esta nueva versión, sintetizó las mejoras en 3 adjetivos “easier, faster and smarter”.  Son varias las mejoras que aporta respecto a las anteriores versiones con más de 2000 parches de más 280 contribuidores.  Easy En el apartado de mayor sencillez para el uso diario de desarrolladores e ingenieros encontramos dos mejoras importantes. Por un lado destaca la mejora de compatibilidad con el estándar SQL, introduciendo un nuevo ANSI SQL parser, soporte para subqueries y compatibilidad completa con el estándar SQL:2003 . Por otro tenemos la unificación de las abstracciones DataFrame y DataSet en una sola, de manera que un DataFrame pasa a ser un DataSets de columnas para las APIs de Java y Scala, que aportará más riqueza semántica y optimización de la API de programación de estos lenguajes. Esto último tendrá especial relevancia (actuando como primer nivel de abstracción) en el concepto de structured streaming que conoceremos más adelante.  Faster  En cuanto al rendimiento esta versión viene incorporada con la segunda fase del proyecto Tungsten: un motor de optimización para el núcleo de Spark cuyo objetivo es mejorar la eficiencia de los accesos a memoria y uso de la CPU. Ésto junto a las mejoras adicionales del Catalyst Optimizer, componente del núcleo de Spark SQL cuyo objetivo es reducir el coste temporal de la realización de queries, da lugar a una reducción del tiempo de la mayoría de los operadores muy importante. Vemos un ejemplo en la siguiente tabla que mide la cantidad de tiempo 

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 57

que se tarda en procesar una columna en un solo core para la misma operación en Spark 1.6 y Spark 2.0.  

   Smart Por último,la que probablemente sea la mejora más relevante debido al nuevo escenario que plantea, cuestionando las arquitecturas Big Data tradicionales, es la nueva API Structured Streaming.  Structured Streaming permite definir queries simultáneas y dinámicas sobre un stream que es tratado como un dataframe infinito, es decir, permite tomar datos del stream, construir una tabla en Spark SQL, exportarla, por ejemplo, a través de JDBC, añadir o cambiar queries sobre ella en tiempo de ejecución y construir y aplicar algoritmos de Machine Learning.  

58 Capítulo 8. ANEXOS

   Ésto supone la unificación del mundo batch y del de streaming, dos partes bien diferenciadas en la arquitectura lambda, la más usada actualmente. Lo que este nuevo modelo plantea es una simplificación de ésta, similar a la arquitectura kappa, de manera que se pueden construir aplicaciones full stack end­to­end simplemente con Apache Kafka para ingestión y Apache Spark para todo lo demás (además de un sistema de almacenamiento distribuido). De este modo se elimina  el problema actual de la gran cantidad de tecnologías diferentes para cualquier proyecto Big Data.  

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 59

    

Papel de Apache Spark en el futuro  Varias son las razones para apostar por Apache Spark a largo plazo.  El primer factor en el que es inevitable pensar­gracias a que se trata de una tecnología open source­ es el número de contribuciones al proyecto por parte de la comunidad que se dobló el año 2015 respecto al 2014: hoy es el proyecto top de Apache, con más de 100 contribuciones por mes.    

60 Capítulo 8. ANEXOS

  Otro factor importante de su crecimiento es la cantidad de empresas que están apostando fuerte por esta tecnología. La más destacada es Databricks, una compañía fundada por los creadores de Spark que da soporte a la tecnología, expide certificaciones oficiales y que ofrece Spark como servicio en la nube. Algunos de los partners oficiales son líderes del sector: Intel, Amazon Web Services o Datastax.   Quizá el partner más relevante por la importancia histórica que ha tenido y su expansión por todos los sectores del mercado es IBM. IBM  se ha comprometido a invertir más de 300 millones de dólares en Spark en los próximos años y a formar a más de un millón de desarrolladores. En la actualidad tiene a más de 3500 desarrolladores e investigadores trabajando con Spark y ha abierto un centro de investigación en San Francisco para colaborar y mejorar el proyecto. Ya ofrece Apache Spark como servicio integrado en su plataforma en la nube IBM Bluemix y ha definido Spark oficialmente como "the most significant open source project of the next decade". 

 Por otro lado compañías cuyo modelo de negocio ha estado basado en la distribución y soporte de Hadoop todos estos años (Cloudera, Hortonworks y MapR), han integrado ya el núcleo de Spark en sus plataformas y cada vez están añadiendo más componentes. 

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 61

 Otras empresas que están utilizando Apache Spark en producción son Amazon, AutoDesk, Baidu, eBay,  NTT DATA, Yahoo e incluso la NASA, entre muchas otras.  

 Conclusión : Apache Spark es la herramienta Big Data definitiva  En este artículo se han argumentado las razones por las que Apache Spark es una tecnología a tener muy en cuenta a corto, medio y largo plazo en el universo Big Data. En un entorno en el que Apache Spark se use, como por ejemplo para el procesamiento por lotes de cargadores de malware de redBorder, se demuestra una mejora considerable. Es por ello que se está estudiando migrar gradualmente trabajos MapReduce de Hadoop escritos en Java a trabajos de Spark escritos en Scala. Además se está valorando empezar a utilizar las librerías de Spark SQL, Machine Learning y Streaming.          

62 Capítulo 8. ANEXOS

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 63

Bibliografia

[1] Tendencias en el mercado de la Ciberseguridad , julio 2016. Autor: INCIBE (Instituto Nacional deCiberseguridad)

[2] Practical Malware Analysis . Autor : Kris Kendall

[3] Análisis de características estáticas de ficheros ejecutables para la clasificación de malware, 2014.Autor: Richard Rivera Guevara

[4] Batch Processing: Definition and Event Log Identification. Autores : Niels Martin, Marijke Swennen,Benoît Depaire, Mieke Jans, An Caris y Koen Vanhoof

[5] Wiki de Apache Hadoop (wiki.apache.org/hadoop/SequenceFile)

[6] Página Oficial de Apache Spark (spark.apache.org/)

[7] Learning Spark, 2015 Autores : Holden Karau, Andy Konwinski , Patrick Wendell y Matei Zaharia

[8] Advanced Analytics with Spark. Autores : Sandy Ryza, Uri Laserson, Sean Owen y Josh Wills

[9] Página Oficial de Apache Hadoop (hadoop.apache.org/)

[10] Field Guide to Hadoop, 2015. Autores: Kevin Sitto y Marshall Presser.

[11] Página Oficial de MongoDB (www.mongodb.com)

[12] MongoDB: The Definitive Guide, 2010. Autor : Kristina Chodorrow

[13] Página oficial de VirusTotal (www.virustotal.com/)

[14] Página oficial de Metascan (www.metascan-online.com/)

[15] Página oficial de ClamAV (www.clamav.net)

[16] Pentaho Kettle Solutions: Building Open Source ETL Solutions with Pentaho Data Integration .Autores : Matt Casters, Roland Bouman y Jos van Dongen.

[17] Learning Scala. Autor : Jason Swartz

[18] Programming in Scala. Autor : Martin Odersky.

[19] BinaryPig: Scalable Static Binary Analysis Over Hadoop. Autores: Zachary Hanif, Telvis, Calhoun yJason Trost

64

8.2 Articulo sobre Apache Spark escrito para el blog de redBorder 65

[20] Automatic Analysis of Malware Behavior using Machine Learning , 2011. Autores : Konrad Rieck,Philipp Trinius, Castern Willems y Thorsten Holz.

[21] BBC News, Dropbox hack affected 68 million users , agosto 2016 (www.bbc.com/news/technology-37232635)

66 Capítulo 8. ANEXOS

Índice de Figuras

1.1 Estimación número de dispositivos conectados a Internet 4

2.1 Ejemplo método identificación de batch processing 82.2 Cabecera de un fichero secuencial 9

3.1 Núcleo y librerias de Apache Spark 113.2 Comparativa rendimiento versiones Apache Spark 1.6 y 2.0 123.3 Arquitectura de HDFS 133.4 Contador de palabras MapReduce 143.5 Arquitectura de YARN 143.6 Ejemplo tecnologias ecosistema Hadoop 153.7 Ejemplo docuemento BSON de MongoDB 153.8 Ejemplo integración de MongoDB y Apache Spark 163.9 Ecosistema open source de Pentaho 17

4.1 Arquitectura BinaryPig 194.2 Arquitectura rb-sequence-oozie 214.3 Arquitectura rb-spark 244.4 RDDs correspondientes a cada uno de los cargadores 284.5 Operacion union y groupByKey sobre los RDDs 28

5.1 Escenario del laboratorio para las pruebas 315.2 Integración de datos con herramienta spoon 325.3 Report de resumen de los datos generado por Pentaho 335.4 Pantalla inical MongoDB Compass 335.5 Vista detallada para un fichero filtrado por su sha1 34

67

Índice de Tablas

5.1 Resumen Pruebas 35

6.1 Presupuesto diseño y desarrollo del proyecto 376.2 Presupuesto equipamiento utilizado 37

69

Índice de Códigos

3.1 WordCount implementado en Java 183.2 WordCount implementado en Scala 18

4.1 Uso de la herramienta dirtosequencefile 224.2 Carga del fichero secuencial desde HDFS a la aplicación desarrolada 224.3 Identificación con el servidor de VirusTotal 234.4 Framento del desarrollo del cargador de VirusTotal que muestra el uso del método getScanReport 234.5 Recursos URL para la consulta al servidor de Metascan 254.6 Establecimiento de conexión con Metascan 254.7 Envio del md5 del fichero a consultar y recepción de las respuesta 254.8 Envio del fichero a Metascan para su análisis en formato binario 264.9 Recepción y parseo del objeto JSON recibido 264.10 Establecimiento de la conexión con Clamscan a través de sockets de red 274.11 Envio del fichero en formato binario al servicio Clamscan 274.12 Recepción información sobre el fichero sumunistrada por CLamscan 274.13 Ejemplo Salida Cargador VirusTotal 274.14 Operación de tipo batch general de la aplicación 284.15 Transformación de los datos en formato JSON con la libreria json4s 294.16 Almacenamineto de los datos en MongoDB 29

8.1 Implementación Cargador VirusTotal 428.2 Implementación Cargador Metascan 448.3 Implementación del cargador Clamscan 498.4 Main de la aplicación 50

71

Índice alfabético 73