Auto-hospedado VirusTotal / OPSWAT MetaDefender aspirante a API para la digitalización de URLs y archivos de múltiples soluciones antivirus.
Introducción (palabras de autor)
Me enfrenté a la necesidad de escanear los archivos cargados por los usuarios en uno de mis proyectos de trabajo de forma automatizada para asegurarme de que no contienen ningún tipo de malware. El uso de VirusTotal no era una opción debido a: a) restricciones legales y limitaciones de residencia de los datos b) el escaneo por hash-sums no sería suficiente porque la mayoría de los archivos son generados/modificados por los usuarios.
Después de buscar en Google, me encontré con un fantástico proyecto maliceio/malice. Desafortunadamente, parece abandonado, y la mayoría de los plugins no funcionan por el momento. Además de eso, tenía la intención de usar .NET stack para alinearme con la infraestructura interna.
https://github.com/maliceio/malice
https://github.com/maliceio/malice/issues/100#issuecomment-529246119
Al final, no es nada más que el conjunto de contenedores Docker que ejecutan el agente. Ese agente descarga el archivo remoto a la carpeta temporal, luego lanza la utilidad de escaneo de la línea de comandos del proveedor con los argumentos adecuados, y analiza la salida con una expresión regular para extraer un nombre de malware detectado.
Instalación y Uso
IMPORTANTE: MalwareMultiScan no está pensado como una API / UI de cara al público. No tiene (intencionadamente) ninguna autorización, autenticación, limitación de velocidad o registro. Por lo tanto, sólo debe utilizarse como una API interna / privada o detrás de la puerta de enlace de la API restrictiva.
Toda la solución puede iniciarse con docker-compose up
ejecutado en la carpeta raíz del repositorio.
También se puede desplegar en el cluster Docker Swarm cluster utilizando el comando:
docker stack deploy malware-multi-scan --compose-file docker-compose.yaml
Después del inicio, la interfaz web de demostración estará disponible en http://localhost:8888.
Consulta el capítulo componentes a continuación y el archivo docker-compose.yaml.
https://github.com/mindcollapse/MalwareMultiScan?fbclid=IwAR0viYLO-8apocAtjAVGCxid1X4cSQkvZXeW25Uc7dH-KRqyOHu5h7po4pE#components
https://github.com/mindcollapse/MalwareMultiScan/blob/master/docker-compose.yaml
Configuración
La configuración de la API y los escáneres se realiza pasando las variables de entorno. A continuación se presentan las descripciones y los valores predeterminados.
MalwareMultiScan.Api
MONGO_ADDRESS=mongodb://localhost:27017
– Cadena de conexión de MongoDB.MONGO_DATABASE=MalwareMultiScan
– nombre de la colección de MongoDB.REDIS_ADDRESS=localhost:6379
– Dirección de Redis para la cola de tareas distribuidas.CONSUL_ADDRESS=http://localhost:8500
– Dirección Consul para el registro del servicio.FILE_SIZE_LIMIT=52428800
– Tamaño máximo de un archivo que puede ser manejado para el escaneo de archivos. El tamaño del contenido de la URL no se verifica. Coloca 0 para desactivar la validación.
MalwareMultiScan.Scanner
BACKEND_ID=dummy
– Id de un backend.REDIS_ADDRESS=localhost:6379
– Dirección de Redis para la cola de tareas distribuidas.CONSUL_ADDRESS=http://localhost:8500
– Dirección del Consul para el registro del servicio.MAX_SCANNING_TIME=60
– Límite de tiempo de exploración. Se utiliza no sólo para el escaneo real, sino también para obtener el archivo.WORKER_COUNT=4
– Número de trabajadores para el escaneo paralelo.
MalwareMultiScan.Ui
API_URL=http://localhost:5000
– URL absoluta incluyendo el número de puerto para la instancia en ejecución deMalwareMultiScan.Api.
Puntos finales de la API
- POST
/api/queue/url
con un parámetrourl
pasado a través de los datos de formulario. Devuelve respuesta201 Accepted
con un ScanResult o error400 Bad Request
. - POST
/api/queue/file
con un parámetrofile
pasado a través de los datos de formulario. Devuelve respuestaAccepted
con un ScanResult o error400 Bad Request
. - GET
/api/results/{result-id}
donde{result-id}
corresponde al valor de id de un ScanResult. Devuelve respuesta200 OK
con un ScanResult o error404 Not Found
.
Callback URL
Tanto/api/queue/url
como /api/queue/file
también aceptan un parámetro opcional callbackUrl
con la URL http(s) en él. Esta URL será solicitada por el método POST con el mensaje ScanResultMessage serializado de JSON en un body en cada actualización de los backends de escaneo. La cadena de consulta contendrá el parámetro id
que corresponde al id del resultado del escaneo y el parámetro backend
con el id del backend que completó el escaneo.
https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Shared/Message/ScanResultMessage.cs
Es decir, cuando definas callbackUrl=http://localhost:1234/scan-results
, la solicitud POST se hará a http://localhost:1234/scan-results?id=123&backend=dummy
con un body.
{
"Status": 1,
"Duration": 5,
"Threats": ["Malware.Dummy.Result"]
}
Motores de escaneo soportados
Nombre | Dockerfile | Habilitado | Comentarios |
---|---|---|---|
ClamAV | Clamav.Dockerfile | ✅ | |
Comodo | Comodo.Dockerfile | ⬜ | |
DrWeb | DrWeb.Dockerfile | ⬜ | Pasa la clave de la licencia al arg DRWEB_KEY. |
Dummy | Dockerfile | ✅ | Escanea el backend hecho para las pruebas. Devuelve la amenaza de malware.Dummy.Result por cada escaneo después de 5 segundos. |
KES | KES.Dockerfile | ⬜ | Pasa la clave de la licencia al arg KES_KEY build. KES 11 no funciona en Docker. |
McAfee | McAfee.Dockerfile | ⬜ | |
Sophos | Sophos.Dockerfile | ⬜ | |
Defender | WindowsDefender.Dockerfile | ✅ |
En el futuro se podrán añadir más backends de escaneo. Algunos de los más populares no tienen la utilidad de escaneo de línea de comandos, versión Linux, o no se inician en el contenedor Docker. Siéntate libre de plantear un tema si conoces alguno además de la lista anterior.
Componentes
Workflow
- Al inicio todos los Scanners (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Scanner) se registran en Consul con un nombre de servicio igual a
scanner
y el campo de metadatosBackendId
igual al valor de la variable de entornoBACKEND_ID
. También registran un chequeo TTL y escuchan el trabajo de fondo de Hangfire en una cola nombrada bajo el campo de metadatosBackendId
. - El cliente de terceros dispara
/api/queue/url
o/api/queue/file
de el MalwareMultiScan.Api. (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api) - MalwareMultiScan.Api (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api) envía una consulta a Consul y recibe la lista de backends de escaneo en vivo con el nombre de servicio
scanner
. - MalwareMultiScan.Api (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api) programa un trabajo de fondo de Hangfire en una cola denominada bajo el campo de metadatos
BackendId
. - Scanners (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Scanner) recoge un trabajo de la cola, inicia el escaneo y envía el resultado a la cola
default
de Hangfire. - MalwareMultiScan.Api (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api) recoge un trabajo de la cola ‘default’ de Hangfire y actualiza el estado del escaneo.
- Si la URL de devolución de llamada (callback URL) fue especificada durante el paso #2, MalwareMultiScan.Api (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api) dispara una petición HTTP POST a la URL especificada. Consulta Callback URL (https://github.com/mindcollapse/MalwareMultiScan?fbclid=IwAR0viYLO-8apocAtjAVGCxid1X4cSQkvZXeW25Uc7dH-KRqyOHu5h7po4pE#callback-url) para más detalles.
Prerequisitos
- MongoDB de la versión 3.x o superior. Se utiliza para almacenar los resultados de los escaneos y los archivos en GridFS. La comunicación se realiza a través del controlador oficial C#/.NET.
- Redis e la versión 5.x o superior. Se utiliza para la cola de tareas. La comunicación está ocurriendo a través de la librería Hangfire.
- Consul de la versión 1.8.x o superior. Usado para el registro de servicio de los backends de escaneo.
- Docker y docker-compose funcionando bajo Windows (en modo contenedores de Linux), Linux, u OSX. Docker Compose sólo se necesita para pruebas / despliegues locales.
- Es opcional: Cluster DockerSwarm / Kubernetes para ampliar las capacidades de escaneo.
Partes
- MalwareMultiScan.Api – Simple ASP.NET Core WebApi para poner en cola archivos y urls para el escaneo y devolver el resultado. También actúa como receptor de los resultados del escaneo de los nodos del backend de escaneo. Ver Dockerfile. (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Api/Dockerfile)
- MalwareMultiScan.Backends (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Backends)- Lógica de escaneo de los backends. Incluye Dockerfiles y clases de implementación para backends de escaneo de terceros.
- MalwareMultiScan.Shared (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Shared)- Componentes compartidos.
- MalwareMultiScan.Scanner (https://github.com/mindcollapse/MalwareMultiScan/blob/master/MalwareMultiScan.Scanner)- El servicio Core Worker de .NET se suscribe a los mensajes correspondientes al id de los backends, luego activa la utilidad de línea de comandos de escaneo y analiza la salida. Ver Dockerfile. La imagen del MalwareMultiScan.Scanner actúa como una imagen base para el resto de los backends de escaneo. Consulta Dockerfiles en la tabla anterior para más detalles.
https://github.com/volodymyrsmirnov/MalwareMultiScan