Introduction
As we already know, OpenCTI can be a powerful tool in our arsenal to aggregate and link components in our threat landscape.
We can link malware families to threat actors, IOCs to intrusion sets, link CVEs to malware families, you name it!
Given that we don’t want to sit all day and link STIX objects, OpenCTI introduces us with connectors – an amazing way for us to aggregates tones of data easily and automatically over fixed periods of time.
I already wrote a blog about how to add connectors to your OpenCTI platform which is fairly easy, but what if we want to create our own connector? what if we discovered a new source we want to import data from? what if we want to change the ones that are already pretty popular?
In this blog i will show you how to do exactly that!
Use Case – MalwareBazaar Connector
I took as an example the MalwareBazaar connector and changed it. The usual connector has several downsides:
The first is that it downloads the malicious samples to the OpenCTI machine, in case i only want the IOCs from MalwareBazaar, i don’t need the samples which eventually take a lot of space.
In addition, in case a sample has a signature, it doesn’t link it to the relevant malware family that might be in the OpenCTI DB.
This is why i wanted to change some of the operation of this connector so it eventually fix these problems.
Of course this is only my choice but anyone can do their own connectors.
I will share the project in my GitHub repo so feel free to use it.
Setup
Eventually what we are going to need it an environment that includes the src
directory which we are going to write our connector in. Within this library i added the config.yml.sample
file and the requirements.txt
we will need later.
In the main directory of our connector we will also have the docker files we need:
.dockerignore
docker-compose.yml
Dockerfile
entrypoint.sh
It should look like so:
Each file play an important part in the operation of our connector.
Dockerfile
The Dockerfile is very important as it is what help us “dockerize” our connector.
The Dockerfile consists of several commands we will use: FROM
, COPY
, RUN
and ENTRYPOINT
.
- FROM: specifies the base image to use for the build process. The base image is the starting point for the Dockerfile and can be any image available on Docker Hub or a private registry.
- COPY: copies files and directories from the build context (the current directory) into the container’s file system. This is useful for adding files required by the application being run inside the container.
- RUN: executes commands during the build process. This can be used to install packages, run scripts or perform any other actions required to set up the container environment.
- ENTRYPOINT: specifies the command to run when the container starts. This can be a script or an executable file.
This is how my Dockerfile looks like:
Entrypoint
As mentioned, the entry point is basically a script or an executable we want to run once the container starts – In my case, the script looks like so:
As far as our concern, this is the bash script that executing our connector script.
Important note is that you need to navigate into the working directory in the container that we have set up in our Dockerfile using the COPY
command.
Docker-Compose File
A docker-compose
file is a YAML file that defines how Docker containers should be deployed and connected together. It is used to define multi-container applications and is often used in development environments to easily spin up and connect multiple containers with a single command.
In our case, the docker-compose
of the connector is the relevant data for our connector that will eventually will go to the main docker-compose
file of the entire OpenCTI.
Given the fact that i based my connector on the popular MalwareBazaar connector, both docker-compose
files looks fairly similar:
The main differences is that i removed some of the environment variables that are unnecessary in my connector and changed the service name to “malwarebazaar_connector”.
The most important thing in a local connector that we created, is that instead of using the image
parameter that we usually use, we will use the build
variable in which we will specify the path to the Dockerfile
we created in order to run the connector/app we built – This is a very important setting.
.dockerignore
The .dockerignore
file is used to exclude files and directories from being copied into the Docker image during the build process. This can be useful for excluding files that are not needed by the application being run inside the container, such as log files or temporary files. The build process will be faster and the resulting image will be smaller if unnecessary files are excluded.
Running the Connector with OpenCTI
Once all is set, all we need to do is to run the docker-compose up
command, we can add the -d
for it to run in the background and work our way from there.
I hope it was helpful for you all!
Have fun and good luck!