Añadir Implementando misp-fixevent-webhook
commit
75d1563966
1 changed files with 464 additions and 0 deletions
464
Implementando misp-fixevent-webhook.-.md
Normal file
464
Implementando misp-fixevent-webhook.-.md
Normal file
|
@ -0,0 +1,464 @@
|
|||
## Descripción
|
||||
|
||||
Este proyecto permite en tiempo real realizar correcciones (limpieza) en los atributos dentro de cada evento en MISP antes de ser publicado en la plataforma. Esto se lleva a cabo a través de la funcionalidad de Workflows que integra MISP.
|
||||
|
||||
Como resultado este proyecto implementa una API en un servidor para recibir los datos de cada evento para ser procesados.
|
||||
|
||||
(Se necesita el servicio gratuito de lookup de IP's, dominios y hashes que ofrece Kaspersky© Threat Intelligence Portal para la limpieza de falsos positivos)
|
||||
|
||||
|
||||
## Características:
|
||||
|
||||
- Limpieza de falsos positivos de cada evento generado en MISP (IP, Domain, SHA256)
|
||||
|
||||
- Normalización de correlación y activación de tag IDS en cada atributo. Solo se activa tag IDS para el tipo de atributo que corresponde, como a su vez solo se activa la correlación para los tipos de atributos que deben ser correlacionados.
|
||||
|
||||
- Normalización de tags para eventos que contengan "tlp: white" ( Se agrega tag tlp:clear en cada caso)
|
||||
|
||||
- Utiliza dentro de Workflows, el trigger "event-publish"
|
||||
|
||||
## Requisitos
|
||||
- Se requiere una cuenta en la plataforma Kaspersky© Threat Intelligence Portal. La cuenta es gratuita. ([https://opentip.kaspersky.com])
|
||||
|
||||
## Requisitos de Hardware recomendados
|
||||
|
||||
- 8/16 GB RAM
|
||||
- 4 vCPU
|
||||
- 100 GB almacenamiento
|
||||
|
||||
## Componentes
|
||||
|
||||
Este proyecto utiliza un BD local (SQLite en modo WALL) y FastAPI.
|
||||
|
||||
## Configuración inicial
|
||||
|
||||
1. En el archivo config.py se debe definir los datos de conexión a MISP, como también la API KEY asociada a Kaspersky TIP:
|
||||
``` python
|
||||
|
||||
MISP_CONFIG = {
|
||||
"misp_url":"URL_MISP",
|
||||
"misp_authkey":"AUTHKEY_MISP"
|
||||
}
|
||||
|
||||
# Se si quiere agregar a exclusión de MISP cada atributo al deshabilitar correlación
|
||||
NO_CORRELATIVOS_EXCLUSION = False
|
||||
|
||||
# Config Lookup KTIP
|
||||
KTIP_CONFIG = {
|
||||
"api_key":"APIKEY_KTIP",
|
||||
"url_base": "https://opentip.kaspersky.com/api/v1/search/"
|
||||
}
|
||||
|
||||
# Rango de dias para verificar si IoC es falso positivo
|
||||
RANGO_DIAS = 7
|
||||
|
||||
# Se debe establecer Manual
|
||||
JWT_TOKEN_GEN = "BEARER_TOKEN"
|
||||
|
||||
# Máximo de atributos a procesar por evento (4000 es el recomendado)
|
||||
MAX_ATTRS = 4000
|
||||
|
||||
# Falsos positivos comunes
|
||||
# FP Comunes
|
||||
FP_COMUNES = ['0.0.0.0','8.8.8.8','google.com','amazon.com','microsoft.com','cloudflare.com']
|
||||
|
||||
# Organizaciones que se puede omitir la revisión de eventos
|
||||
ORG_OMITIR = []
|
||||
|
||||
NO_CORRELATIVOS = [
|
||||
"comment”, # Comentarios descriptivos
|
||||
"email-subject", # Asuntos de correos electrónicos
|
||||
"email-dst", # Emails de destinatarios
|
||||
"email-src", # Emails de remitentes
|
||||
"hostname", # Nombres de host
|
||||
"port", # Puertos
|
||||
"link", # Enlaces
|
||||
"phone-number", # Números de teléfono
|
||||
"user-agent", # Agentes de usuario
|
||||
"size-in-bytes", # Tamaños en bytes
|
||||
"vulnerability", # Vulnerabilidades (CVE)
|
||||
"whois-registrant-email", # Correos de registrantes WHOIS
|
||||
"whois-registrant-name", # Nombres de registrantes WHOIS
|
||||
"regkey", # Claves de registro de Windows
|
||||
"regkey|value", # Claves de registro con valores
|
||||
"text", # Texto libre
|
||||
"datetime", # Fechas y horas
|
||||
"campaign-name", # Nombres de campaña
|
||||
"attachment", # Archivos adjuntos
|
||||
"email" # Emails de remitentes
|
||||
]
|
||||
|
||||
IDS_CORRELATIVOS = [
|
||||
"ip-src", # IP de origen
|
||||
"ip-dst", # IP de destino
|
||||
"domain", # Dominio
|
||||
"domain|ip", # Dominio con IP asociada
|
||||
"url", # URL completas
|
||||
"uri", # URI (fragmentos de rutas)
|
||||
"http-method", # Métodos HTTP (GET, POST, etc.)
|
||||
"email-attachment", # Nombres de archivos adjuntos en correos
|
||||
"filename", # Nombres de archivo
|
||||
"filename|md5", # Nombre de archivo con su hash MD5
|
||||
"filename|sha1", # Nombre de archivo con su hash SHA1
|
||||
"filename|sha256", # Nombre de archivo con su hash SHA256
|
||||
"md5", # Hash MD5
|
||||
"sha1", # Hash SHA1
|
||||
"sha256", # Hash SHA256
|
||||
"authentihash", # Hash Authentihash
|
||||
"impfuzzy", # Hash ImpHash (ejecutable PE)
|
||||
"tlsh", # Hash TLSH
|
||||
"ssdeep", # Hash SSDEEP (fuzzy hash)
|
||||
"mutex", # Nombres de mutex
|
||||
"registry-key", # Claves de registro (si son relevantes)
|
||||
"registry-key|value", # Claves de registro con valores
|
||||
"ip-src|port", # IP de origen con puerto
|
||||
"ip-dst|port", # IP de destino con puerto
|
||||
"asn", # ASN (Autonomous System Number)
|
||||
"cidr", # Rango CIDR (IPs)
|
||||
"mac-address", # Dirección MAC
|
||||
"x509-fingerprint-md5", # Huella de certificados X509 (MD5)
|
||||
"x509-fingerprint-sha1", # Huella de certificados X509 (SHA1)
|
||||
"x509-fingerprint-sha256", # Huella de certificados X509 (SHA256)
|
||||
"ja3-fingerprint-md5", # Huella JA3 (TLS handshake)
|
||||
"btc", # Dirección de Bitcoin
|
||||
"iban", # Número de cuenta bancaria (IBAN)
|
||||
"bank-account-nr", # Número de cuenta bancaria
|
||||
"payment-card-number" # Número de tarjeta de pago
|
||||
]
|
||||
|
||||
```
|
||||
En config.py puedes realizar los ajustes:
|
||||
|
||||
- MISP_CONFIG: Configuración asociada a MISP
|
||||
|
||||
- NO_CORRELATIVOS_EXCLUSION: Si es True, cada atributo que sea corregida su correlación, ósea que se desactive, será agregado valor a la lista de exclusión de correlaciones.
|
||||
|
||||
- KTIP_CONFIG: Configuración de conexión a servicio de Lookup de Kaspersky. Se debe solo configurar "api_key".
|
||||
|
||||
- RANGO_DIAS: Establece según la fecha del atributo (IoC) cuantos días tomar como rango para verificar falso positivo
|
||||
|
||||
- JWT_TOKEN_GEN: Token personal generado.
|
||||
|
||||
- MAX_ATTRS: Cantidad de atributos a procesar por evento. Por defecto el máximo son 4000. No se recomienda aumentar este valor.
|
||||
|
||||
- FP_COMUNES: Falsos positivos conocidos.
|
||||
|
||||
- ORG_OMITIR: Organizaciones que se puede omitir la revisión de eventos.
|
||||
|
||||
- NO_CORRELATIVOS: Lista de tipos de atributos que no deben correlacionarse dentro de MISP.
|
||||
|
||||
- IDS_CORRELATIVOS: Lista de tipos de atributos que deberán tener el flag IDS activado dentro de MISP. Por defecto estos atributos son correlacionados dentro de MISP.
|
||||
|
||||
# Configuración Inicial
|
||||
|
||||
## Instalación en entorno virtual
|
||||
|
||||
1. Se crea entorno virtual de Python
|
||||
``` shell
|
||||
cd /home/user/misp-fixevent-webhook
|
||||
|
||||
python3 -m venv venv
|
||||
|
||||
source venv/bin/activate
|
||||
```
|
||||
2. Instalar bibliotecas de Python:
|
||||
``` shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
3. Se debe crear archivo .sh o editar el archivo existente (start_api.sh) y anexarlo como servicio para que inicie con el sistema operativo:
|
||||
|
||||
``` shell
|
||||
#!/bin/bash
|
||||
|
||||
# Activate
|
||||
source /home/user/misp-fixevent-webhook/venv/bin/activate
|
||||
|
||||
# Enter folder
|
||||
cd /home/user/misp-fixevent-webhook/
|
||||
|
||||
# Actualizar bibliotecas si aplica
|
||||
pip install --upgrade -r requirements.txt > /dev/null 2>&1
|
||||
|
||||
# Si vas a utilizar proxy reverso...
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000
|
||||
|
||||
# Si no vas a utilizar proxy reverso puedes utilizar certificados genéricos
|
||||
uvicorn main:app --host 0.0.0.0 --port 8000 --ssl-keyfile key.pem --ssl-certfile cert.pem
|
||||
|
||||
```
|
||||
Debe activar SSL en proyecto
|
||||
|
||||
## Agregar como servicio
|
||||
|
||||
1. Para agregar como servicio necesita crear dentro del directorio /etc/systemd/system (En caso de Ubuntu) un archivo .service(misp_webhooks.service). Podemos crearlo con nano (sudo) usando el siguiente formato:
|
||||
|
||||
``` shell
|
||||
sudo nano /etc/systemd/system/misp_webhooks.service
|
||||
|
||||
[Unit]
|
||||
Description=MISP WebHooks Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/home/user/misp-fixevent-webhook/start_api.sh
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
2. Se deben entregar permisos de ejecución a archivo .sh:
|
||||
```shell
|
||||
chmod +x /home/user/misp-fixevent-webhook/start_api.sh
|
||||
```
|
||||
|
||||
3. Se recargan servicios:
|
||||
```shell
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
3. Luego registramos este archivo para que se ejecute al iniciar el sistema:
|
||||
``` shell
|
||||
sudo systemctl enable misp_webhooks.sevice
|
||||
|
||||
```
|
||||
|
||||
4. Ahora podemos iniciar, detener, reiniciar servicio...
|
||||
``` shell
|
||||
# Iniciar
|
||||
sudo systemctl start misp_webhooks.sevice
|
||||
|
||||
# Detener
|
||||
sudo systemctl stop misp_webhooks.sevice
|
||||
|
||||
# Reiniciar
|
||||
sudo systemctl restart mmisp_webhooks.sevice
|
||||
|
||||
```
|
||||
|
||||
## Servicios (Endpoints) de API
|
||||
|
||||
- /webhoook/misp_event_fixer/
|
||||
|
||||

|
||||
|
||||
## Documentación
|
||||
|
||||
Debes agregar
|
||||
Puedes acceder a la documentación:
|
||||
|
||||
SwaggerUI
|
||||
```
|
||||
http://URL_PROYECTO:8000/docs
|
||||
```
|
||||
|
||||
Redocly
|
||||
```
|
||||
http://URL_PROYECTO:8000/redoc
|
||||
```
|
||||
|
||||
## Configuración en Servidor MISP
|
||||
|
||||
Desde MISP necesitamos configurar el Workflow para utilizar nuestra API. Debemos verificar si tenemos "misp-modules" instalados. Estos módulos corren en el puerto 6666. Podemos verificar si el puerto esta activo:
|
||||
|
||||
```shell
|
||||
telnet localhost 6666
|
||||
```
|
||||
Si no hay respuesta, necesitamos instalar las siguientes librerías (Ubuntu):
|
||||
|
||||
```shell
|
||||
sudo apt install git python3 python3-pip python3-dev libpq5 libjpeg-dev build-essential libssl-dev libffi-dev zlib1g-dev libmagic-dev libxml2-dev libxslt1-dev libpoppler-cpp-dev libzbar0 tesseract-ocr
|
||||
```
|
||||
Una vez instaladas, podemos instalar misp-modules en nuestro servidor MISP (como root).
|
||||
Desde la versión 2.5, no se incluye misp-modules (Para más información: https://misp.github.io/misp-modules/install/)
|
||||
|
||||
1. Creamos directorio dentro de MISP:
|
||||
``` shell
|
||||
sudo su
|
||||
cd /var/www/MISP
|
||||
mkdir misp-modules
|
||||
cd /misp-modules
|
||||
```
|
||||
2. Creamos entorno virtual y activamos:
|
||||
``` shell
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
3. Instalamos librerías:
|
||||
``` shell
|
||||
pip install \
|
||||
misp-modules \
|
||||
git+https://github.com/cartertemm/ODTReader.git \
|
||||
git+https://github.com/abenassi/Google-Search-API \
|
||||
git+https://github.com/SteveClement/trustar-python.git \
|
||||
git+https://github.com/sebdraven/pydnstrails.git \
|
||||
git+https://github.com/sebdraven/pyonyphe.git
|
||||
|
||||
```
|
||||
4. Creamos un .sh (run.sh) para llamar como servicio cada vez que parta el equipo:
|
||||
``` shell
|
||||
sudo nano run.sh
|
||||
```
|
||||
5. Dentro del archivo definimos las rutas (según sea el caso):
|
||||
```shell
|
||||
#!/bin/bash
|
||||
|
||||
# Activate
|
||||
source /var/www/MISP/misp-modules/venv/bin/activate
|
||||
|
||||
# Enter folder
|
||||
cd /var/www/MISP/misp-modules/venv/bin/
|
||||
|
||||
# Ejecutar misp-modules
|
||||
misp-modules
|
||||
|
||||
```
|
||||
6. Configuramos servicio:
|
||||
```shell
|
||||
sudo nano /etc/systemd/system/misp-modules.service
|
||||
```
|
||||
7. Dentro del archivo definimos las rutas (según sea el caso):
|
||||
```shell
|
||||
[Unit]
|
||||
Description=MISP Modules Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/var/www/MISP/misp-modules/run.sh
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
7. Se deben entregar permisos de ejecución a archivo .sh:
|
||||
```shell
|
||||
chmod +x /var/www/MISP/misp-modules/run.sh
|
||||
```
|
||||
|
||||
8. Se recargan servicios:
|
||||
```shell
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
9. Luego registramos este archivo para que se ejecute al iniciar el sistema y arrancamos app:
|
||||
``` shell
|
||||
sudo systemctl enable misp-modules.sevice
|
||||
sudo systemctl start misp-modules.sevice
|
||||
```
|
||||
|
||||
10. Configuramos carpeta de MISP como owner original "www-data"
|
||||
```shell
|
||||
sudo chown -R www-data:www-data /var/www/MISP
|
||||
```
|
||||
|
||||
## Activando / Configurando Workflow en MISP
|
||||
|
||||
1. Accedemos a MISP y nos dirigimos a "Administration"->"Server Settings & Maintenance"->"Plugin":
|
||||
|
||||

|
||||
|
||||
2. Dentro de Plugin activamos "Enrichment":
|
||||
|
||||

|
||||
|
||||
3. Luego "Action" y "Workflow":
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
4. Para poder llamar a nuestro webhook desde MISP necesitamos modificar una propiedad de MISP desde el MISP CLI desde terminal:
|
||||
|
||||
```shell
|
||||
sudo -u www-data /var/www/MISP/app/Console/cake Admin setSetting Security.rest_client_enable_arbitrary_urls true
|
||||
```
|
||||
|
||||
5. Iniciamos sesión en nuestro MISP y nos dirigimos a "Administration"->"Worflows" de MISP:
|
||||
|
||||

|
||||
|
||||
6. El webhook está diseñado para llamarse en el proceso previo a publicar un evento en MISP, este trigger se llama "event-publish" y debemos activarlo yendo a "List Triggers"->"Event Publish" y presionamos el botón de play:
|
||||
|
||||

|
||||
|
||||
7. Luego en la misma ventana, vamos a la sección de "List Modules" y activamos el módulo de "Webhook":
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
8. Para agregar más control en el flujo (Para el caso de Eventos que no tengan atributos => 0) vamos a activar dentro del "List Modules" en "Logic" el módulo "IF::Count":
|
||||
|
||||

|
||||
|
||||
9. Finalmente desde la misma ventana, en "Blocking" activamos "Stop execution":
|
||||
|
||||

|
||||
|
||||
## Configuración Webhook
|
||||
|
||||
1. Ahora vamos a ir a la configuración de nuestro trigger "event-publish" para configurar los datos para enviar al webhook. Nos dirigimos al símbolo "</>":
|
||||
|
||||

|
||||
|
||||
2. Desde la lista de "Actions", Agregamos "Webhook" al plano de diseño arrastrando:
|
||||
|
||||

|
||||
|
||||
3. Desde la lista de "Logic", Agregamos "IF :: Count" al plano de diseño arrastrando:
|
||||
|
||||

|
||||
|
||||
4. Desde la lista de "Actions", Agregamos "Stop execution" al plano de diseño arrastrando:
|
||||
|
||||

|
||||
|
||||
5. Conectamos "Event Publish" con "IF :: Count":
|
||||
|
||||

|
||||
|
||||
6. En el módulo IF :: Count configuramos "Data selector to count" con el valor "All Attributes", esto quiere decir que contara todos los atributos del evento:
|
||||
|
||||

|
||||
|
||||
7. En el mismo módulo en "Condition" seteamos como "Equals to" y en "Value" queda en 0:
|
||||
|
||||

|
||||
|
||||
8. Si el evento no tiene atributos, se detendrá la ejecución de "publish" en el evento. Debemos conectar en el resultado afirmativo del módulo IF :: Count el módulo "Stop execution":
|
||||
|
||||

|
||||
|
||||
9. En caso contrario, que Evento SI tenga atributos, lo conectamos al módulo "Webhook" para que procese los datos:
|
||||
|
||||

|
||||
|
||||
10. Ahora necesitamos configurar los datos que tenemos que mandar al Webhook. Los datos son los siguientes:
|
||||
|
||||
- URL: https://IP_SERVIDOR_API:8000/webhook/misp_event_fixer/
|
||||
- Payload: {
|
||||
"event_id": "{{ Event.id }}",
|
||||
"event_uuid": "{{ Event.uuid }}",
|
||||
"event_attribute_count": "{{ Event.attribute_count }}"
|
||||
}
|
||||
- Header: Authorization: Bearer <MI_JWT_TOKEN>
|
||||
|
||||
11. Vamos a puntos arriba mano derecha y editamos el módulo para agregar esta información:
|
||||
|
||||

|
||||
|
||||
12. Ingresamos la información mencionada en el punto 10 y para finalizar presionamos el botón "Close":
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
13. Guardamos el Workflow en MISP haciendo clic en "Save":
|
||||
|
||||

|
||||
|
||||
Con estos pasos realizados, desde ahora en adelante dentro de MISP, cada evento generado por la organización local o de instancias remotas, será revisado y corregido por nuestro servicio web.
|
||||
|
||||
Cualquier duda o consulta envíanos un correo a: misp@anci.gob.cl
|
Loading…
Add table
Reference in a new issue