From a7aeefdb11cac9b8207c59810d5ab8cef8a63214 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:53:41 +0800 Subject: [PATCH 1/4] Add TestAnalyzer --- analyzers/TestAnalyzer/TestAnalyzer.json | 53 +++++++++++++++ analyzers/TestAnalyzer/requirements.txt | 1 + analyzers/TestAnalyzer/testing.py | 86 ++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 analyzers/TestAnalyzer/TestAnalyzer.json create mode 100644 analyzers/TestAnalyzer/requirements.txt create mode 100755 analyzers/TestAnalyzer/testing.py diff --git a/analyzers/TestAnalyzer/TestAnalyzer.json b/analyzers/TestAnalyzer/TestAnalyzer.json new file mode 100644 index 000000000..aaebff5c5 --- /dev/null +++ b/analyzers/TestAnalyzer/TestAnalyzer.json @@ -0,0 +1,53 @@ +{ + "name": "TestAnalyzer", + "version": "1.0", + "author": "Fabien Bloume, StrangeBee", + "url": "https://github.com/TheHive-Project/Cortex-Analyzers", + "license": "AGPL-V3", + "description": "Just a simple test analyzer! No real-world use-case covered by this one, for testing, reference, dev and any other purpose only!", + "dataTypeList": ["ip", "domain", "url", "fqdn", "mail", "hash", "filename", "uri_path", "user-agent", "mail-subject"], + "baseConfig": "TestAnalyzer", + "command": "TestAnalyzer/testing.py", + "config": { + "service": "testing" + }, + "configurationItems": [ + { + "name": "some_string", + "description": "placeholder string", + "type": "string", + "multi": false, + "required": false, + "defaultValue": "some string.." + }, + { + "name": "some_list", + "description": "placeholder list", + "type": "string", + "multi": true, + "required": false, + "defaultValue": ["item1", "item2", "item3"] + + }, + { + "name": "some_number", + "description": "placeholder number", + "type": "number", + "multi": false, + "required": false, + "defaultValue": 1 + }, + { + "name": "throw_error", + "description": "throw an error!", + "type": "boolean", + "multi": false, + "required": true, + "defaultValue": false + } + ], + "registration_required": false, + "subscription_required": false, + "free_subscription": false, + "serviceHomepage": "None" +} diff --git a/analyzers/TestAnalyzer/requirements.txt b/analyzers/TestAnalyzer/requirements.txt new file mode 100644 index 000000000..37dfee161 --- /dev/null +++ b/analyzers/TestAnalyzer/requirements.txt @@ -0,0 +1 @@ +cortexutils \ No newline at end of file diff --git a/analyzers/TestAnalyzer/testing.py b/analyzers/TestAnalyzer/testing.py new file mode 100755 index 000000000..a3de1384a --- /dev/null +++ b/analyzers/TestAnalyzer/testing.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# encoding: utf-8 + +from cortexutils.analyzer import Analyzer + +class TestAnalyzer(Analyzer): + def __init__(self): + Analyzer.__init__(self) + self.some_string = self.get_param( + "config.some_string", None, "some_string parameter is missing" + ) + self.some_list = self.get_param( + "config.some_list", ["item1", "item2", "item3"], "some_list parameter is missing" + ) + self.some_number = self.get_param( + "config.some_number", 1, "some_number parameter is missing" + ) + self.throw_error = self.get_param( + "config.throw_error", False, "throw_error parameter is missing" + ) + + def run(self): + if self.throw_error: + error_message = "this is an error string: throw_error boolean is set to True in Cortex" + self.error(error_message) + data = self.get_data() + #data = self.get_param("data", None, "Data is missing") + datatype = self.data_type + + result = {"data": data, "dataType": datatype, "arrayExample": ["A", "B", "C"], "tableExample": {"colA": "row A value", "colB": "row B value", "colC": "row C value",}} + + self.report(result) + + def summary(self, raw): + taxonomies = [] + namespace = "testing" + predicate = self.data_type + value = "None" + + # safe, info, suspicious, malicious + for level in ["info", "safe", "suspicious", "malicious"]: + taxonomies.append( + self.build_taxonomy( + level, namespace, predicate, value) + ) + + return {"taxonomies": taxonomies} + + def operations(self, raw): + operations = [] + operations.append(self.build_operation('AddTagToArtifact', tag="test")) + ## For reference only + # case class AddTagToCase(tag: String) extends ActionOperation + # case class AddTagToArtifact(tag: String) extends ActionOperation + # case class CreateTask(title: String, description: String) extends ActionOperation + # case class AddCustomFields(name: String, tpe: String, value: JsValue) extends ActionOperation + # case class CloseTask() extends ActionOperation + # case class MarkAlertAsRead() extends ActionOperation + # case class AddLogToTask(content: String, owner: Option[String]) extends ActionOperation + # case class AddTagToAlert(tag: String) extends ActionOperation + # case class AddArtifactToCase( + # data: String, + # dataType: String, + # message: String, + # tlp: Option[Int], + # ioc: Option[Boolean], + # sighted: Option[Boolean], + # ignoreSimilarity: Option[Boolean], + # tags: Option[Seq[String]] + # ) extends ActionOperation + # case class AssignCase(owner: String) extends ActionOperation + return operations + + def artifacts(self, raw): + artifacts = [] + data_type = "ip" + value = "8.8.8.8" + extra_args = { + "tags": ["test"] + } + artifacts.append(self.build_artifact(data_type, value, **extra_args)) + return artifacts + + +if __name__ == "__main__": + TestAnalyzer().run() From ac75ce09f58bc50df94c5a1dc26b5253be7fbaa7 Mon Sep 17 00:00:00 2001 From: nusantara-self <15647296+nusantara-self@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:53:59 +0800 Subject: [PATCH 2/4] Add TestAnalyzer long report --- thehive-templates/TestAnalyzer_1_0/long.html | 156 +++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 thehive-templates/TestAnalyzer_1_0/long.html diff --git a/thehive-templates/TestAnalyzer_1_0/long.html b/thehive-templates/TestAnalyzer_1_0/long.html new file mode 100644 index 000000000..e58e65c71 --- /dev/null +++ b/thehive-templates/TestAnalyzer_1_0/long.html @@ -0,0 +1,156 @@ + +
Data Type: {{ content.dataType }}
+Data: {{ content.data }}
+ + +Column A | +Column B | +Column C | +
---|---|---|
{{ content.tableExample.colA }} | +{{ content.tableExample.colB }} | +{{ content.tableExample.colC }} | +
Placeholder tab 1 content
+Placeholder tab 2 content
+Placeholder tab 3 content
+Some collapsible details
+Header 1 | +Header 2 | +Header 3 | +
---|---|---|
{{ content.tableExample.colA }} | +{{ content.tableExample.colB }} | +{{ content.tableExample.colC }} | +
Content for Tab 1
+Content for Tab 2
+Content for Tab 3
+Additional details: some more details
+