# Update - OpenBAS to OPENAEV. Performing Adversary Emulation

## Installation

Being a die-hard fan of Docker, I suggest you start by cloning the Docker repository of openAEV

```
https://github.com/OpenAEV-Platform/docker
```

### Changes to the env file

OpenAEV has done great job by providing a sample env file.&#x20;

```
cp .env.sample .env
```

The sample file is mostly fine for testing purposes, please do make changes as required if you are doing this in production.&#x20;

Minimal changes that are required to start with testing are&#x20;

{% code title=".env" %}

```
OPENAEV_HOST  ## Make sure you set it to the IP address if you are running it on a different address
OPENAEV_ADMIN_EMAIL ## A valid email address
OPENAEV_ADMIN_PASSWORD ## A complex password
OPENAEV_ADMIN_TOKEN ## Get a valid UUID_v4 from online generators

```

{% endcode %}

Below is the full env file, which I am using for testing

{% code title=".env" %}

```
###########################
# DEPENDENCIES            #
###########################

POSTGRES_USER=ChangeMe
POSTGRES_PASSWORD=ChangeMe
MINIO_ROOT_USER=ChangeMeAccess
MINIO_ROOT_PASSWORD=ChangeMeKey
RABBITMQ_DEFAULT_USER=ChangeMe
RABBITMQ_DEFAULT_PASS=ChangeMe
ELASTIC_MEMORY_SIZE=4G

# Emails
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=ChangeMe@domain.com
SMTP_PASSWORD=ChangeMe
SMTP_AUTH=true
SMTP_SSL_ENABLE=true
SMTP_STARTTLS_ENABLE=false
IMAP_HOST=imap.changeme.com
IMAP_PORT=993
IMAP_USERNAME=ChangeMe@domain.com
IMAP_PASSWORD=ChangeMe
IMAP_AUTH=true
IMAP_SSL_ENABLE=true
IMAP_STARTTLS_ENABLE=false

###########################
# COMMON                  #
###########################

XTM_COMPOSER_ID=8215614c-7139-422e-b825-b20fd2a13a23
COMPOSE_PROJECT_NAME=xtm

###########################
# OPENAEV                 #
###########################

OPENAEV_HOST=192.168.1.27
OPENAEV_PORT=8080
OPENAEV_EXTERNAL_SCHEME=http
OPENAEV_ADMIN_EMAIL= openaev@openaev.com
OPENAEV_ADMIN_PASSWORD= openaev
OPENAEV_ADMIN_TOKEN=5c1a58ef-51d7-4098-820c-bee24948637a # [MANDATORY] Replace with a valid UUIDv4
OPENAEV_HEALTHCHECK_KEY=ChangeMe
OPENAEV_MAIL_IMAP_ENABLED=false

###########################
# OPENAEV COLLECTORS      #
###########################

COLLECTOR_MITRE_ATTACK_ID=3050d2a3-291d-44eb-8038-b4e7dd107436
COLLECTOR_OPENAEV_ID=63544750-19a1-435f-ada4-b44e39cf3cdb
COLLECTOR_ATOMIC_RED_TEAM_ID=c34e3f19-e0b9-45cb-83e0-3b329e4c53d3
COLLECTOR_NVD_NIST_CVE_ID=2caac5d2-31c7-4804-adfd-f92d1b2e7eda
COLLECTOR_NVD_NIST_CVE_API_KEY= #Optionnal but recommended

###########################
# OPENAEV INJECTORS       #
###########################

INJECTOR_NMAP_ID=76f8f4d6-9f6f-4e61-befc-48f735876a4a
INJECTOR_NUCLEI_ID=e1bad898-9804-427d-99e4-dc32c5f2898d

```

{% endcode %}

### Changes to the Docker Compose file

The default Docker file also requires openCTI to be running. It is thus necessary to remove the references to openCTI

{% code title="docker-compose.yml" %}

```
xtm-composer:
    image: filigran/xtm-composer:1.0.1
    platform: linux/amd64
    environment:
      - MANAGER__ID=${XTM_COMPOSER_ID}
      - "MANAGER__NAME=XTM Integrations Manager"
      - MANAGER__CREDENTIALS_KEY_FILEPATH=/keys/private_key.pem
      - OPENAEV__ENABLE=true
      - OPENAEV__URL=http://openaev:8080
      - OPENAEV__TOKEN=${OPENAEV_ADMIN_EMAIL}
      - OPENAEV__DAEMON__SELECTOR=docker
      - OPENAEV__DAEMON__DOCKER__NETWORK_MODE=${COMPOSE_PROJECT_NAME}_default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - rsakeys:/keys:ro # RSA key mounted as read-only
    depends_on:
      rsa-key-generator:
        condition: service_healthy
      # opencti: ## not running opencti 
      #   condition: service_healthy ## not running opencti 
      rabbitmq:
        condition: service_healthy
    restart: always

```

{% endcode %}

Below is the full docker-compose.yml file&#x20;

{% code title="docker-compose.yml" %}

```
services:

  ###########################
  # DEPENDENCIES            #
  ###########################

  # Generate RSA key for xtm-composer (PKCS#8 format)
  rsa-key-generator:
    image: alpine/openssl:3.5.4
    volumes:
      - rsakeys:/keys
    entrypoint: [ "/bin/ash" ]
    command: [ "-c", "if [ ! -f /keys/private_key.pem ]; then openssl genpkey -algorithm RSA -out /keys/private_key.pem -pkeyopt rsa_keygen_bits:4096; fi && tail -f /dev/null" ]
    healthcheck:
      test: [ "CMD", "test", "-f", "/keys/private_key.pem" ]
      interval: 10s
      timeout: 5s
      retries: 3
    restart: always
  pgsql:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: openaev
    volumes:
      - pgsqldata:/var/lib/postgresql/data
    restart: always
    healthcheck:
      test: [ "CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "openaev" ]
      interval: 10s
      timeout: 5s
      retries: 5
  minio:
    image: minio/minio:RELEASE.2025-06-13T11-33-47Z
    volumes:
      - s3data:/data
    ports:
      - "9000:9000"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    command: server /data
    restart: always
    healthcheck:
      test: [ "CMD", "mc", "ready", "local" ]
      interval: 10s
      timeout: 5s
      retries: 5
  rabbitmq:
    image: rabbitmq:4.2-management
    environment:
      - RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
      - RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
      - RABBITMQ_NODENAME=rabbit01@localhost
    volumes:
      - type: bind
        source: ./rabbitmq.conf
        target: /etc/rabbitmq/rabbitmq.conf
      - amqpdata:/var/lib/rabbitmq
    restart: always
    healthcheck:
      test: [ "CMD", "rabbitmq-diagnostics", "-q", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 5
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.19.9
    volumes:
      - esdata:/usr/share/elasticsearch/data
    environment:
      # Comment-out the line below for a cluster of multiple nodes
      - discovery.type=single-node
      # Uncomment the line below below for a cluster of multiple nodes
      # - cluster.name=docker-cluster
      - xpack.ml.enabled=false
      - xpack.security.enabled=false
      - thread_pool.search.queue_size=5000
      - logger.org.elasticsearch.discovery="ERROR"
      # -XX:UseSVE=0 is necessary for Apple M4 architecture
      - "ES_JAVA_OPTS=-Xms${ELASTIC_MEMORY_SIZE} -Xmx${ELASTIC_MEMORY_SIZE} -XX:+IgnoreUnrecognizedVMOptions -XX:UseSVE=0"
      - "CLI_JAVA_OPTS=-XX:+IgnoreUnrecognizedVMOptions -XX:UseSVE=0"
    restart: always
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test: curl -s http://elasticsearch:9200 >/dev/null || exit 1
      interval: 30s
      timeout: 10s
      retries: 50

  ###########################
  # COMMON                  #
  ###########################

  xtm-composer:
    image: filigran/xtm-composer:1.0.1
    platform: linux/amd64
    environment:
      - MANAGER__ID=${XTM_COMPOSER_ID}
      - "MANAGER__NAME=XTM Integrations Manager"
      - MANAGER__CREDENTIALS_KEY_FILEPATH=/keys/private_key.pem
      - OPENAEV__ENABLE=true
      - OPENAEV__URL=http://openaev:8080
      - OPENAEV__TOKEN=${OPENAEV_ADMIN_EMAIL}
      - OPENAEV__DAEMON__SELECTOR=docker
      - OPENAEV__DAEMON__DOCKER__NETWORK_MODE=${COMPOSE_PROJECT_NAME}_default
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - rsakeys:/keys:ro # RSA key mounted as read-only
    depends_on:
      rsa-key-generator:
        condition: service_healthy
      # opencti:
      #   condition: service_healthy
      rabbitmq:
        condition: service_healthy
    restart: always

  ###########################
  # OPENAEV                 #
  ###########################

  openaev:
    image: openaev/platform:2.0.9
    environment:
      - OPENAEV_BASE-URL=${OPENAEV_EXTERNAL_SCHEME}://${OPENAEV_HOST}:${OPENAEV_PORT}
      - OPENAEV_AUTH-LOCAL-ENABLE=true
      - OPENAEV_ADMIN_EMAIL=${OPENAEV_ADMIN_EMAIL}
      - OPENAEV_ADMIN_PASSWORD=${OPENAEV_ADMIN_PASSWORD}
      - OPENAEV_ADMIN_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - OPENAEV_HEALTHCHECK_KEY=${OPENAEV_HEALTHCHECK_KEY:-ChangeMe}
      - OPENAEV_EXTRA-TRUSTED-CERTS-DIR=/opt/openaev/additional_certs
      - SPRING_DATASOURCE_URL=jdbc:postgresql://pgsql:5432/openaev
      - SPRING_DATASOURCE_USERNAME=${POSTGRES_USER}
      - SPRING_DATASOURCE_PASSWORD=${POSTGRES_PASSWORD}
      - MINIO_ENDPOINT=minio
      - MINIO_ACCESS-KEY=${MINIO_ROOT_USER}
      - MINIO_ACCESS-SECRET=${MINIO_ROOT_PASSWORD}
      - OPENAEV_RABBITMQ_HOSTNAME=rabbitmq
      - OPENAEV_RABBITMQ_USER=${RABBITMQ_DEFAULT_USER}
      - OPENAEV_RABBITMQ_PASS=${RABBITMQ_DEFAULT_PASS}
      - ENGINE_URL=http://elasticsearch:9200
      - SPRING_MAIL_HOST=${SMTP_HOST}
      - SPRING_MAIL_PORT=${SMTP_PORT}
      - SPRING_MAIL_USERNAME=${SMTP_USERNAME}
      - SPRING_MAIL_PASSWORD=${SMTP_PASSWORD}
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_AUTH=${SMTP_AUTH}
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_SSL_ENABLE=${SMTP_SSL_ENABLE}
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_SSL_TRUST=*
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE=${SMTP_STARTTLS_ENABLE}
      - OPENAEV_MAIL_IMAP_ENABLED=${OPENAEV_MAIL_IMAP_ENABLED}
      - OPENAEV_MAIL_IMAP_HOST=${IMAP_HOST}
      - OPENAEV_MAIL_IMAP_PORT=${IMAP_PORT}
      - OPENAEV_MAIL_IMAP_USERNAME=${IMAP_USERNAME}
      - OPENAEV_MAIL_IMAP_PASSWORD=${IMAP_PASSWORD}
      - OPENAEV_MAIL_IMAP_AUTH=${IMAP_AUTH}
      - OPENAEV_MAIL_IMAP_SSL_ENABLE=${IMAP_SSL_ENABLE}
      - OPENAEV_MAIL_IMAP_SSL_TRUST=*
      - OPENAEV_MAIL_IMAP_STARTTLS_ENABLE=${IMAP_STARTTLS_ENABLE}
    ports:
      - "${OPENAEV_PORT}:8080"
    depends_on:
      pgsql:
        condition: service_healthy
      minio:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
      elasticsearch:
        condition: service_healthy
    restart: always
    healthcheck:
      test: [ "CMD", "wget", "-qO-", "http://openaev:8080/api/health?health_access_key=${OPENAEV_HEALTHCHECK_KEY}" ]
      interval: 10s
      timeout: 5s
      retries: 20

  ###########################
  # OPENAEV COLLECTORS      #
  ###########################

  collector-mitre-attack:
    image: openaev/collector-mitre-attack:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - COLLECTOR_ID=${COLLECTOR_MITRE_ATTACK_ID} # Valid UUIDv4
      - "COLLECTOR_NAME=MITRE ATT&CK"
      - COLLECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always
  collector-openaev:
    image: openaev/collector-openaev:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - COLLECTOR_ID=${COLLECTOR_OPENAEV_ID} # Valid UUIDv4
      - "COLLECTOR_NAME=OpenAEV Datasets"
      - COLLECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always
  collector-atomic-red-team:
    image: openaev/collector-atomic-red-team:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - COLLECTOR_ID=${COLLECTOR_ATOMIC_RED_TEAM_ID} # Valid UUIDv4
      - "COLLECTOR_NAME=Atomic Red Team"
      - COLLECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always
  collector-nvd-nist-cve:
    image: openaev/collector-nvd-nist-cve:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - COLLECTOR_ID=${COLLECTOR_NVD_NIST_CVE_ID} # Valid UUIDv4
      - NVD_NIST_CVE_API_KEY=${COLLECTOR_NVD_NIST_CVE_API_KEY}
      - "COLLECTOR_NAME=CVE by NVD NIST"
      - COLLECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always

  ###########################
  # OPENAEV INJECTORS       #
  ###########################

  injector-nmap:
    image: openaev/injector-nmap:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - INJECTOR_ID=${INJECTOR_NMAP_ID} # Valid UUIDv4
      - INJECTOR_NAME=Nmap
      - INJECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always
  injector-nuclei:
    image: openaev/injector-nuclei:2.0.9
    environment:
      - OPENAEV_URL=http://openaev:8080
      - OPENAEV_TOKEN=${OPENAEV_ADMIN_TOKEN}
      - INJECTOR_ID=${INJECTOR_NUCLEI_ID} # Valid UUIDv4
      - INJECTOR_NAME=Nuclei
      - INJECTOR_LOG_LEVEL=info
    depends_on:
      openaev:
        condition: service_healthy
    restart: always
volumes:
  pgsqldata:
  s3data:
  amqpdata:
  esdata:
  rsakeys:

```

{% endcode %}

## Starting Docker

After making the changes, it is quite straightforward.

```
server@local:~/openAEV$ docker compose up -d  
[+] Running 14/14
 ✔ Network xtm_default                        Created         0.2s 
 ✔ Container xtm-rabbitmq-1                   Healthy         14.1s 
 ✔ Container xtm-pgsql-1                      Healthy         11.6s 
 ✔ Container xtm-rsa-key-generator-1          Healthy         11.6s 
 ✔ Container xtm-elasticsearch-1              Healthy         61.6s 
 ✔ Container xtm-minio-1                      Healthy         11.6s 
 ✔ Container xtm-xtm-composer-1               Started         14.5s 
 ✔ Container xtm-openaev-1                    Healthy         134.4s 
 ✔ Container xtm-collector-nvd-nist-cve-1     Started         136.2s 
 ✔ Container xtm-collector-atomic-red-team-1  Started         136.2s 
 ✔ Container xtm-collector-openaev-1          Started         135.8s 
 ✔ Container xtm-injector-nmap-1              Started         135.9s 
 ✔ Container xtm-injector-nuclei-1            Started         135.8s 
 ✔ Container xtm-collector-mitre-attack-1     Started         136.2s
```

Note: The repository comes with Caldera Docker files as well. Since this is a 101 guide, I am not covering how to get started with Caldera at this moment.

And there you have it. The openAEV is now up and running. You can visit the dashboard by going to <http://OPENAEV\\_HOST:OPENAEV\\_PORT> (both variables were set in the .env file)

<figure><img src="/files/ZRychJwJtVmloZxcppQi" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.redteam.cafe/red-team/update-openbas-to-openaev.-performing-adversary-emulation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
