Skip to content

Commit

Permalink
initial thehive reporting setup (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucamrgs authored Nov 21, 2024
1 parent 4dc73d0 commit c478379
Show file tree
Hide file tree
Showing 11 changed files with 1,110 additions and 38 deletions.
9 changes: 8 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,11 @@ ENABLE_FINS: false
MQTT_BROKER: "localhost"
MQTT_PORT: 1883

HTTP_SKIP_CERT_VALIDATION: false
HTTP_SKIP_CERT_VALIDATION: false

### Integrations

# The Hive
THEHIVE_ACTIVATE: true
THEHIVE_API_TOKEN: your_token
THEHIVE_API_BASE_URL: http://localhost:9000/api/v1/
5 changes: 5 additions & 0 deletions docker/soarca/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ services:
MQTT_BROKER: "mosquitto"
MQTT_PORT: 1883
HTTP_SKIP_CERT_VALIDATION: false
# Integrations:
# The Hive
THEHIVE_ACTIVATE: false
THEHIVE_API_TOKEN: your_token
THEHIVE_API_BASE_URL: http://localhost:9000/api/v1/
networks:
- db-net
- mqtt-net
Expand Down
2 changes: 1 addition & 1 deletion example/http-playbook.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"type": "playbook",
"spec_version": "cacao-2.0",
"id": "playbook--300270f9-0e64-42c8-93cc-0927edbe3ae7",
"name": "Example ssh",
"name": "Example http",
"description": "This playbook is to demonstrate the http functionality",
"playbook_types": [
"notification"
Expand Down
38 changes: 36 additions & 2 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controller

import (
"errors"
"fmt"
"os"
"reflect"
"strconv"
Expand All @@ -22,6 +23,7 @@ import (
"soarca/internal/guid"
"soarca/internal/reporter"
cache "soarca/internal/reporter/downstream_reporter/cache"
"soarca/internal/reporter/downstream_reporter/thehive"
"soarca/logger"
"soarca/utils"
httpUtil "soarca/utils/http"
Expand Down Expand Up @@ -89,11 +91,23 @@ func (controller *Controller) NewDecomposer() decomposer.IDecomposer {

// NOTE: Enrolling mainCache by default as reporter
reporter := reporter.New([]downstreamReporter.IDownStreamReporter{})
downstreamReporters := []downstreamReporter.IDownStreamReporter{&mainCache}
err := reporter.RegisterReporters(downstreamReporters)
cacheReporterAsList := []downstreamReporter.IDownStreamReporter{&mainCache}

// Reporter integrations
theHiveReporterAsList := []downstreamReporter.IDownStreamReporter{}
thehive_reporter := initializeIntegrationTheHiveReporting()
if thehive_reporter != nil {
theHiveReporterAsList = append(theHiveReporterAsList, thehive_reporter)
}

err := reporter.RegisterReporters(cacheReporterAsList)
if err != nil {
log.Error("could not load main Cache as reporter for decomposer and executors")
}
err = reporter.RegisterReporters(theHiveReporterAsList)
if err != nil {
log.Error("could not load The Hive as reporter for decomposer and executors")
}

soarcaTime := new(timeUtil.Time)
actionExecutor := action.New(capabilities, reporter, soarcaTime)
Expand Down Expand Up @@ -229,6 +243,26 @@ func (controller *Controller) setupAndRunMqtt() error {
return nil
}

func initializeIntegrationTheHiveReporting() downstreamReporter.IDownStreamReporter {
initTheHiveReporter, _ := strconv.ParseBool(utils.GetEnv("THEHIVE_ACTIVATE", "false"))
if !initTheHiveReporter {
return nil
}
log.Info("initializing The Hive reporting integration")

thehive_api_token := utils.GetEnv("THEHIVE_API_TOKEN", "")
thehive_api_base_url := utils.GetEnv("THEHIVE_API_BASE_URL", "")
if len(thehive_api_base_url) < 1 || len(thehive_api_token) < 1 {
log.Warning("could not initialize The Hive reporting integration. Check to have configured the env variables correctly.")
return nil
}

log.Info(fmt.Sprintf("creating new The hive connector with API base url at : %s", thehive_api_base_url))
theHiveConnector := thehive.NewConnector(thehive_api_base_url, thehive_api_token)
theHiveReporter := thehive.NewReporter(theHiveConnector)
return theHiveReporter
}

func getMqttDetails() (string, int) {
broker := utils.GetEnv("MQTT_BROKER", "localhost")
port, err := strconv.Atoi(utils.GetEnv("MQTT_PORT", "1883"))
Expand Down
73 changes: 73 additions & 0 deletions internal/reporter/downstream_reporter/thehive/ids_map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package thehive

import (
"fmt"
)

// ############################### Playbook to TheHive ID mappings

type SOARCATheHiveMap struct {
executionsCaseMaps map[string]ExecutionCaseMap
}
type ExecutionCaseMap struct {
caseId string
stepsTasksMap map[string]string
}

// TODO: Change to using observables instead of updating the tasks descriptions

func (soarcaTheHiveMap *SOARCATheHiveMap) checkExecutionCaseExists(executionId string) error {
if _, ok := soarcaTheHiveMap.executionsCaseMaps[executionId]; !ok {
return fmt.Errorf("case not found for execution id %s", executionId)
}
return nil
}
func (soarcaTheHiveMap *SOARCATheHiveMap) checkExecutionStepTaskExists(executionId string, stepId string) error {
if _, ok := soarcaTheHiveMap.executionsCaseMaps[executionId].stepsTasksMap[stepId]; !ok {
return fmt.Errorf("task not found for execution id %s for step id %s", executionId, stepId)
}
return nil
}

func (soarcaTheHiveMap *SOARCATheHiveMap) registerExecutionInCase(executionId string, caseId string) error {
soarcaTheHiveMap.executionsCaseMaps[executionId] = ExecutionCaseMap{
caseId: caseId,
stepsTasksMap: map[string]string{},
}
log.Info(fmt.Sprintf("registering execution: %s, case id: %s", executionId, caseId))

return nil
}
func (soarcaTheHiveMap *SOARCATheHiveMap) registerStepTaskInCase(executionId string, stepId string, taskId string) {
soarcaTheHiveMap.executionsCaseMaps[executionId].stepsTasksMap[stepId] = taskId
}

func (soarcaTheHiveMap *SOARCATheHiveMap) retrieveCaseId(executionId string) (string, error) {
err := soarcaTheHiveMap.checkExecutionCaseExists(executionId)
if err != nil {
return "", err
}
return soarcaTheHiveMap.executionsCaseMaps[executionId].caseId, nil
}

func (soarcaTheHiveMap *SOARCATheHiveMap) retrieveTaskId(executionId string, stepId string) (string, error) {
err := soarcaTheHiveMap.checkExecutionCaseExists(executionId)
if err != nil {
return "", err
}
err = soarcaTheHiveMap.checkExecutionStepTaskExists(executionId, stepId)
if err != nil {
return "", err
}
return soarcaTheHiveMap.executionsCaseMaps[executionId].stepsTasksMap[stepId], nil
}

// func (soarcaTheHiveMap *SOARCATheHiveMap) clearCase(executionId string) error {
// err := soarcaTheHiveMap.checkExecutionCaseExists(executionId)
// if err != nil {
// return err
// }
// return nil
// }

// func (soarcaTheHiveMap *SOARCATheHiveMap) clearMap(executionId string) error
Loading

0 comments on commit c478379

Please sign in to comment.