Escaneos de Vulnerabilidades a demanda (y Serverless)

Hernan Gabriel Romero
Despegar Ingeniería
6 min readJun 13, 2023

En este post te contamos la estrategia que adoptamos para brindar un servicio a los equipos de desarrollo del Grupo D! para poder ejecutar escaneos de vulnerabilidades de infraestructura a demanda, si si, a demanda!

¿Dónde estábamos?

El punto de partida fué un proceso de gestión de vulnerabilidades bien definido:

Se realiza un escaneo periódico de vulnerabilidades mediante la herramienta Nessus en las instancias (máquinas virtuales) requeridas y se identifican los atributos de cada una de ellas (ambiente, owner, criticidad, etc.). Para finalizar, se abre un ticket en Jira a cada owner en el caso en que deba resolver una vulnerabilidad detectada en una instancia particular.

Si en el próximo escaneo se sigue detectando la vulnerabilidad, se da aviso en el ticket creado anteriormente o se reabre si fue cerrado. Por el contrario, si la vulnerabilidad ya no es detectada por el escáner, el ticket se cierra automáticamente sin intervención del owner de la instancia.

¿Cuál fué la problemática?

Debido a que (paradójicamente) el proceso era completamente automatizado, los owners que resolvían una vulnerabilidad, debían esperar varios días hasta que se ejecutase el próximo escaneo programado para confirmar que el problema esté realmente solucionado. Esto conllevaba a dos grandes problemas:

  • Si la solución aplicada no corregía completamente la vulnerabilidad, el riesgo seguía presente hasta que se vuelve a detectar en el próximo escaneo.
  • El owner podía asumir que el trabajo pendiente fue completado, pero si el escaneo volvía a detectar la vulnerabilidad, el ticket era reabierto y el aging (tiempo desde que se reportó la vulnerabilidad hasta que se cerró el ticket) continuaba aumentando.

¿Hacia dónde fuimos?

La solución requería afrontar diversos desafíos: lograr la automatización de escaneos (con un scope dinámico) en Nessus, darle la posibilidad a los owners de instancias que puedan solicitar escaneos, gestionar todas las solicitudes de la forma más sencilla posible, procesar los resultados de los escaneos y lograr disminuir el esfuerzo de mantenimiento al mínimo posible de la infraestructura requerida.

Automatización de escaneos en Nessus

La automatización de escaneos era un paso crucial para confirmar si la solución era posible o no de implementar.

Nos basamos en un repositorio de Github en el que se implementa la administración completa de Nessus mediante su API, incluyendo no sólo la obtención de la información de los escaneos en progreso, sino también la ejecución y configuración de escaneos nuevos.

Solicitud de escaneos por los owners de instancias

Necesitábamos encontrar la forma para que un owner de instancia pueda solicitar un nuevo escaneo con la menor intervención posible.

Para esto introdujimos algunos cambios en el proyecto original de Jira de gestión de vulnerabilidades:

  • Agregar un nuevo estado en los tickets de proyecto para identificar los que se encuentran pendientes de escaneo.
  • Agregar una nueva transición hacia ese estado. Esta transición será la encargada de “solicitar” el escaneo.
  • Crear un script en Groovy dentro del propio Jira, que será el que desencadenará la solicitud de escaneo.
  • Crear un listener sobre la nueva transición, que será el que ejecute el script mencionado anteriormente.

Gestión de las solicitudes

1: El script creado en Jira realizará un POST en una API publicada en API Gateway con los datos de la instancia y del ticket original (hostname, owner, key del ticket, tags, etc.)

2: La API tendrá como target una función Lambda que se encargará de:

  • Verificar si la solicitud de escaneo es válida de acuerdo a los tags y atributos del ticket. Esto nos sirve, por ejemplo, si solo queremos aceptar escaneos de instancias que estén en un ambiente particular o sean de un owner específico.
  • Si la solicitud no es válida, pasar el ticket original a su estado anterior.
  • Si la solicitud es válida, enviar un mensaje a una cola de mensajes FIFO de SQS que irá recolectando todas las solicitudes de ese día. Luego agregar un comentario en el ticket original indicando que la solicitud fue aceptada.

3: Al finalizar el día se ejecutará una task de Fargate que realizará lo siguiente:

  • Leer todos los mensajes que se encuentren en la cola de mensajes de SQS con las solicitudes pendientes.
  • Agrupar todas las solicitudes para una misma instancia en una única solicitud. Esto se realiza porque pueden llegar varias solicitudes de escaneo desde varios tickets distintos para un mismo hostname.
  • Ejecutar un único escaneo en Nessus utilizando como targets los hostnames de las solicitudes procesadas.
  • Guardar las solicitudes en una tabla de DynamoDB utilizando el ID del escaneo generado.

Procesamiento de los resultados

A lo largo del día se realizarán los siguientes pasos:

1: Se ejecutará periódicamente una función Lambda a modo de listener de escaneos pendientes que realizará lo siguiente:

  • Consultar a Nessus si ya finalizó alguno de los escaneos pendientes según lo que esté registrado en DynamoDB.
  • Si encuentra alguno ya finalizado, ejecuta una task de Fargate para procesar los resultados.

2: La task de Fargate que procesa los resultados realizará lo siguiente:

  • Comparar las solicitudes con el escaneo para revisar las vulnerabilidades corregidas y pendientes.
  • Cerrar automáticamente los tickets de vulnerabilidades solucionadas.
  • Pasar a su estado anterior los tickets de vulnerabilidades aún pendientes.
  • Agregar comentarios necesarios en los tickets.
  • Marcar el escaneo pendiente como finalizado en DynamoDB.

Disminuir esfuerzo de mantenimiento

Con lo explicado anteriormente podemos ver que la solución completa se apoya en las plataformas Serverless más utilizadas de AWS:

  • API Gateway: Nos permite disponibilizar una API sin necesidad de contar con infraestructura subyacente. Es autoescalable según la cantidad de requests recibidos, cuenta con protocolos de autenticación integrados y su costo es marginal de acuerdo al uso requerido en nuestro caso.
  • Lambda: Nos permite ejecutar porciones de código atómico sin necesidad de disponer de infraestructura específica. Es ideal para ser utilizada como triggers junto a API Gateway, SQS o DynamoDB. El costo se calcula de acuerdo al uso (cantidad de invocaciones) y por el tiempo de ejecución.
  • SQS: Permite implementar colas de mensajes de forma completamente autoadministrada y autoescalable. Ideal para comunicar aplicaciones de forma asincrónica o microservicios.
  • DynamoDB: Es la base de datos NoSQL completamente autoadministrada de AWS. Es ideal para hacer un deploy rápido de soluciones simples, es autoescalable y cuenta con un sistema de backup completamente autogestionado.
  • Fargate: Permite deployar contenedores sin necesidad de contar con infraestructura subyacente. Es ideal para procesos simples y puntuales que no justifiquen tener una instancia de EC2 levantada continuamente.

Conclusión

Para aquel que no posee conocimientos de seguridad y/o dependiendo de la naturaleza de la vulnerabilidad, a veces puede ser difícil saber si luego de aplicado un fix, la misma sigue o no presente. Por eso, pensamos en una solución para los equipos de desarrollo, donde puedan ejecutar un escaneo apenas finalizada la mitigación.

Esta solución, además de brindar certeza a los desarrolladores, reduce los tiempos en los que la vulnerabilidad aún puede estar presente, dado que la persona que inicia el escaneo puede avisar que sigue siendo detectada (en lugar de esperar al próximo ciclo del proceso).

--

--