How to Integrate Cortex & MISP with TheHive in your SOC

In Episode 11 of our cyber security virtual lab building series, we are going to integrate Cortex and MISP with TheHive bringing our Security Operations Center (SOC) one step closer to our goal of implementing Security Orchestration, Automation and Response (SOAR) within our SOC.

To recap, TheHive is a security incident response platform (SIRP), and together with Cortex and MISP we will be able to create cases/alerts, analyze observables and tap into a wealth of cybersecurity information allowing us to make well informed decisions, giving us the ability to respond to security incidents as quickly as possible.

In this lab we will revisit our setup defined using docker-compose and make some amendments to these services/containers to allow for this integration to happen.

By the end of this lab our SOC will be ready to trigger observables analysis directly from TheHive as well as allow MISP to feed the latest threat alerts directly to TheHive dashboard and should we wish, create new indicators of compromise (IOC’s) that we can send back to MISP so others have the opportunity to benefit from our discoveries. If you have been enjoying this series so far, please don’t forget to like and subscribe!

The updated docker-compose.yml file I used in this lab:

version: "3.7"
services:
  thehive:
    image: strangebee/thehive:latest
    restart: unless-stopped
    depends_on:
      - cassandra
      - elasticsearch
      - minio
      - cortex
    mem_limit: 1500m
    ports:
      - "0.0.0.0:9000:9000"
    environment:
      - JVM_OPTS="-Xms1024M -Xmx1024M"
    command:
      - --secret
      - "lab123456789"
      - "--cql-hostnames"
      - "cassandra"
      - "--index-backend"
      - "elasticsearch"
      - "--es-hostnames"
      - "elasticsearch"
      - "--s3-endpoint"
      - "http://minio:9002"
      - "--s3-access-key"
      - "minioadmin"
      - "--s3-secret-key"
      - "minioadmin"
      - "--s3-use-path-access-style"
      #- "--no-config-cortex"
      - "--cortex-port"
      - "9001"
      - "--cortex-keys"
      - "vuaNtCWlpewWXzz9JI1L/CD/HsnuWLPC" #remember to change this to your API key
    volumes:
      - ./thehive/conf/application.conf:/etc/thehive/application.conf 
    networks:
      - SOC_NET

  cassandra:
    image: 'cassandra:4'
    restart: unless-stopped
    mem_limit: 1000m
    ports:
      - "0.0.0.0:9042:9042"
    environment:
      - CASSANDRA_CLUSTER_NAME=TheHive
    volumes:
      - cassandradata:/var/lib/cassandra
    networks:
      - SOC_NET

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4
    restart: unless-stopped
    mem_limit: 512m
    ports:
      - "0.0.0.0:9200:9200"
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - cluster.name=hive
      - http.host=0.0.0.0
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
    volumes:
      - elasticsearchdata:/usr/share/elasticsearch/data
    networks:
      - SOC_NET

  minio:
    image: quay.io/minio/minio
    restart: unless-stopped
    command: ["minio", "server", "/data", "--console-address", ":9002"]
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin
    ports:
      - "0.0.0.0:9002:9002"
    volumes:
      - "miniodata:/data"
    networks:
      - SOC_NET

  cortex:
    image: thehiveproject/cortex:latest
    restart: unless-stopped
    environment:
      - job_directory=/opt/cortex/jobs
    volumes:
      - cortexdata:/var/run/docker.sock
      - cortexdata:/opt/cortex/jobs
      - cortexdata:/var/log/cortex
      - cortexdata:/cortex/application.conf
    depends_on:
      - elasticsearch
    ports:
      - "0.0.0.0:9001:9001"
    networks:
      - SOC_NET

  misp:
    image: coolacid/misp-docker:core-latest
    restart: unless-stopped
    depends_on: 
      - misp_mysql
    ports:
      - "0.0.0.0:80:80"
      - "0.0.0.0:443:443"
    volumes:
      - "./server-configs/:/var/www/MISP/app/Config/"
      - "./logs/:/var/www/MISP/app/tmp/logs/"
      - "./files/:/var/www/MISP/app/files"
      - "./ssl/:/etc/nginx/certs"
    environment:
      - MYSQL_HOST=misp_mysql
      - MYSQL_DATABASE=mispdb
      - MYSQL_USER=mispuser
      - MYSQL_PASSWORD=misppass
      - [email protected]
      - MISP_ADMIN_PASSPHRASE=mispadminpass
      - MISP_BASEURL=localhost
      - TIMEZONE=Europe/London
      - "INIT=true"         
      - "CRON_USER_ID=1"   
      - "REDIS_FQDN=redis"
      - "HOSTNAME=https://10.200.200.253"
    networks:
      - SOC_NET

  misp_mysql:
    image: mysql/mysql-server:5.7
    restart: unless-stopped
    volumes:
      - mispsqldata:/var/lib/mysql   
    environment:
      - MYSQL_DATABASE=mispdb
      - MYSQL_USER=mispuser
      - MYSQL_PASSWORD=misppass
      - MYSQL_ROOT_PASSWORD=mispass
    networks:
      - SOC_NET
  redis:
    image: redis:5.0.6
    networks:
      - SOC_NET
  misp-modules:
    image: coolacid/misp-docker:modules-latest
    environment:
      - "REDIS_BACKEND=redis"
    depends_on:
      - redis
      - misp_mysql
    networks:
      - SOC_NET   

volumes:
  miniodata:
  cassandradata:
  elasticsearchdata:
  cortexdata:
  thehivedata:
  mispsqldata:

networks:
    SOC_NET:
          driver: bridge

This is the application.conf configuration file used in this lab to integrate MISP.

play.modules.enabled += org.thp.thehive.connector.misp.MispModule
misp {
  interval: 1 hour
  servers: [
    {
      name = "MISP"
      url = "https://misp"
      auth {
        type = key
        key = "Yl1M7biMolOcb1qk7HCgNih3OjpUyUJqesDXtazB" #your API Key here
      }
      tags = ["tag1", "tag2", "tag3"]
      caseTemplate = "misp"
      includedTheHiveOrganisations = ["Morgan Maxwell"]
    }
  ]
}

Links used in this lab: