mirror of
https://github.com/valitydev/Cortex-Analyzers.git
synced 2024-11-06 09:05:19 +00:00
New version of the Splunk analyzer for Cortex
This commit is contained in:
parent
b2965c4235
commit
675eb2808b
75
analyzers/Splunk/Splunk_Search_domain_fqdn.json
Normal file
75
analyzers/Splunk/Splunk_Search_domain_fqdn.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Domain_FQDN",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["domain","fqdn"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a domain or a FQDN as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Domain_FQDN"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_file_filename.json
Normal file
75
analyzers/Splunk/Splunk_Search_file_filename.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_File_Filename",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["file","filename"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a file/filename as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_File_Filename"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_hash.json
Normal file
75
analyzers/Splunk/Splunk_Search_hash.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Hash",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["hash"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a hash as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Hash"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_ip.json
Normal file
75
analyzers/Splunk/Splunk_Search_ip.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_IP",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["ip"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with an IP as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_IP"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_mail_email.json
Normal file
75
analyzers/Splunk/Splunk_Search_mail_email.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Mail_Email",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["mail","email"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a mail/email as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Mail_Email"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_mail_subject.json
Normal file
75
analyzers/Splunk/Splunk_Search_mail_subject.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Mail_Subject",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["mail_subject"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a mail subject as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Mail_Subject"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_other.json
Normal file
75
analyzers/Splunk/Splunk_Search_other.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Other",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["other"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with an unidentified data as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Other"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_registry.json
Normal file
75
analyzers/Splunk/Splunk_Search_registry.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_Registry",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["registry"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with a registry data as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_Registry"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
75
analyzers/Splunk/Splunk_Search_url_uri_path.json
Normal file
75
analyzers/Splunk/Splunk_Search_url_uri_path.json
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "Splunk_Search_URL_URI_Path",
|
||||
"version": "3.0",
|
||||
"url": "",
|
||||
"author": "Unit777, LetMeR00t",
|
||||
"license": "AGPL-V3",
|
||||
"dataTypeList": ["url","uri_path"],
|
||||
"description": "Execute a savedsearch on a Splunk instance with an URL or a URI path as argument",
|
||||
"baseConfig": "Splunk",
|
||||
"config": {
|
||||
"check_tlp": false,
|
||||
"max_tlp": 4,
|
||||
"service": "Search_URL_URI_Path"
|
||||
},
|
||||
"configurationItems": [
|
||||
{
|
||||
"name": "host",
|
||||
"description": "Splunk API host or IP",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"description": "Splunk API port",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"description": "User account used for searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"description": "User password of the previous mentionned account",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "application",
|
||||
"description": "Spunk application in which the saved searches are stored",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "owner",
|
||||
"description": "Username that corresponds to the owner of the saved searches",
|
||||
"type": "string",
|
||||
"multi": false,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "saved_searches",
|
||||
"description": "Name of the saved searches to use",
|
||||
"type": "string",
|
||||
"multi": true,
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "max_count",
|
||||
"description": "Maximum number of results to return for a search",
|
||||
"type": "number",
|
||||
"multi": false,
|
||||
"required": false,
|
||||
"defaultValue": 1000
|
||||
}
|
||||
],
|
||||
"command": "Splunk/splunk.py"
|
||||
}
|
1
analyzers/Splunk/requirements.txt
Normal file
1
analyzers/Splunk/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
splunk-sdk
|
214
analyzers/Splunk/splunk.py
Executable file
214
analyzers/Splunk/splunk.py
Executable file
@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
|
||||
import splunklib.client as client
|
||||
from time import sleep
|
||||
from cortexutils.analyzer import Analyzer
|
||||
import splunklib.results as results
|
||||
import urllib
|
||||
import re
|
||||
|
||||
|
||||
class Splunk(Analyzer):
|
||||
|
||||
def __init__(self):
|
||||
Analyzer.__init__(self)
|
||||
self.HOST = self.getParam('config.host', None, 'Host parameter is missing')
|
||||
self.PORT = self.getParam('config.port', None, 'Port parameter is missing')
|
||||
self.USERNAME = self.getParam('config.username', None, 'Username parameter is missing')
|
||||
self.PASSWORD = self.getParam('config.password', None, 'Password parameter is missing')
|
||||
self.OWNER = self.getParam('config.owner', None, 'Owner parameter is missing')
|
||||
self.APP = self.getParam('config.application', None, 'Application parameter is missing')
|
||||
self.SAVEDSEARCHES = self.getParam('config.saved_searches', None, 'At least one Splunk savedsearch name is required')
|
||||
self.MAX_COUNT = self.getParam('config.max_count', 1000)
|
||||
|
||||
# Create a Service instance and log in
|
||||
def SplunkConnect(self):
|
||||
try:
|
||||
self.service = client.connect(
|
||||
host=self.HOST,
|
||||
port=self.PORT,
|
||||
username=self.USERNAME,
|
||||
password=self.PASSWORD,
|
||||
owner=self.OWNER,
|
||||
app=self.APP)
|
||||
except Exception as e:
|
||||
self.unexpectedError(e)
|
||||
|
||||
|
||||
# Execute a saved search
|
||||
def SplunkSearch(self, **kwargs_savedsearch):
|
||||
|
||||
# Get all saved searches
|
||||
saved_searches = self.SAVEDSEARCHES
|
||||
|
||||
jobs = {}
|
||||
for saved_search in saved_searches:
|
||||
# Execute every savedsearch with the needed arguments
|
||||
job = self.service.saved_searches[saved_search].dispatch(**kwargs_savedsearch)
|
||||
jobs[saved_search] = job
|
||||
|
||||
jobs_running = len(jobs)
|
||||
|
||||
# A savedsearch returns the job's SID right away, so we need to poll for completion
|
||||
# Wait for the jobs until they are all done
|
||||
while jobs_running != 0:
|
||||
# Check every 4 seconds
|
||||
sleep(4)
|
||||
jobs_running = len(jobs)
|
||||
for saved_search in jobs:
|
||||
job = jobs[saved_search]
|
||||
if job.is_done():
|
||||
jobs_running -= 1
|
||||
|
||||
# Get the results and display them
|
||||
savedSearchResults = []
|
||||
|
||||
# Process all saved searches
|
||||
# Each result is under the name of the saved search
|
||||
for saved_search in jobs:
|
||||
jobResult = {}
|
||||
dataResults = {}
|
||||
job = jobs[saved_search]
|
||||
index = 0
|
||||
fieldLevelInfo = 0
|
||||
fieldLevelSafe = 0
|
||||
fieldLevelSuspicious = 0
|
||||
fieldLevelMalicious = 0
|
||||
|
||||
for result in results.ResultsReader(job.results(count=self.MAX_COUNT)):
|
||||
dataResults[index] = result
|
||||
# Check if a field "level" exists
|
||||
if "level" in result:
|
||||
# if so, count the values if it's info,safe,suspicious,malicious
|
||||
if result["level"] == "info":
|
||||
fieldLevelInfo += 1
|
||||
if result["level"] == "safe":
|
||||
fieldLevelSafe += 1
|
||||
if result["level"] == "suspicious":
|
||||
fieldLevelSuspicious += 1
|
||||
if result["level"] == "malicious":
|
||||
fieldLevelMalicious += 1
|
||||
|
||||
index += 1
|
||||
if fieldLevelInfo+fieldLevelSafe+fieldLevelSuspicious+fieldLevelMalicious > 0 :
|
||||
jobResult["levels"] = {"info": fieldLevelInfo, "safe": fieldLevelSafe, "suspicious": fieldLevelSuspicious, "malicious": fieldLevelMalicious}
|
||||
jobResult["results"] = dataResults
|
||||
jobResult["length"] = index
|
||||
jobResult["eventCount"] = int(job["eventCount"])
|
||||
jobResult["resultCount"] = int(job["resultCount"])
|
||||
|
||||
if jobResult["resultCount"] > self.MAX_COUNT:
|
||||
jobResult["note"] = "Only the first "+str(self.MAX_COUNT)+" results were recovered over "+job["resultCount"]+" to avoid any trouble on TheHive/Cortex. This parameter (max_count) can be changed in the analyzer configuration."
|
||||
|
||||
jobResult["search"] = job["search"]
|
||||
jobResult["savedsearch"] = saved_search
|
||||
savedSearchResults.append(jobResult)
|
||||
|
||||
finalResult = {"savedsearches": savedSearchResults}
|
||||
|
||||
# Build the report
|
||||
self.report(finalResult)
|
||||
|
||||
|
||||
def SplunkURLSearch(self, data):
|
||||
|
||||
|
||||
if self.data_type == 'url':
|
||||
# Check if it's a valid URL/domain and extract the domain automatically if needed
|
||||
try:
|
||||
regex = re.compile(r"^(?:https?:\/\/)?([^\/|\?|\&|\$|\+|\,|\:|\;|\=|\@|\#]+)(?:\/.*)?$")
|
||||
match = regex.search(data)
|
||||
if match is not None:
|
||||
domain = match.group(1)
|
||||
else:
|
||||
self.error('Malformed URL. Could not extract domain from URL.')
|
||||
|
||||
except Exception as e:
|
||||
self.error('Unexpected error: ' + str(e))
|
||||
|
||||
kwargs_savedsearch = {"args.url": data, "args.domain": domain, "args.type": self.data_type, "output_mode": "xml"}
|
||||
|
||||
self.SplunkSearch(**kwargs_savedsearch)
|
||||
|
||||
|
||||
def SplunkIPSearch(self, data):
|
||||
|
||||
# Check if it's a good IPv4 IP address
|
||||
try:
|
||||
regex = re.compile(r"^((?:([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$")
|
||||
match = regex.search(data)
|
||||
if match is not None:
|
||||
domain = match.group(1)
|
||||
else:
|
||||
self.error('Malformed IPv4')
|
||||
|
||||
except Exception as e:
|
||||
self.error('Unexpected error: ' + str(e))
|
||||
|
||||
kwargs_savedsearch = {"args.ip": data, "args.type": self.data_type, "output_mode": "xml"}
|
||||
|
||||
self.SplunkSearch(**kwargs_savedsearch)
|
||||
|
||||
|
||||
def SplunkOtherSearch(self, data):
|
||||
|
||||
kwargs_savedsearch = {"args."+self.data_type: data, "args.type": self.data_type, "output_mode": "xml"}
|
||||
self.SplunkSearch(**kwargs_savedsearch)
|
||||
|
||||
|
||||
def summary(self, raw):
|
||||
taxonomies = []
|
||||
value = 0
|
||||
namespace = "Splunk"
|
||||
taxonomyResults = {"level": "info", "namespace": namespace, "predicate": "Results", "value": 0}
|
||||
|
||||
# (Optional) These taxonomies will be added only if a field "level" is found
|
||||
taxonomyInfo = {"level": "info", "namespace": namespace, "predicate": "Info", "value": 0}
|
||||
taxonomySafe = {"level": "safe", "namespace": namespace, "predicate": "Safe", "value": 0}
|
||||
taxonomySuspicious = {"level": "suspicious", "namespace": namespace, "predicate": "Suspicious", "value": 0}
|
||||
taxonomyMalicious = {"level": "malicious", "namespace": namespace, "predicate": "Malicious", "value": 0}
|
||||
|
||||
# Process all requests with the given taxonomies
|
||||
for savedsearch in raw["savedsearches"]:
|
||||
taxonomyResults["value"] += savedsearch["resultCount"]
|
||||
|
||||
if "levels" in savedsearch:
|
||||
levels = savedsearch["levels"]
|
||||
taxonomyInfo["value"] += levels["info"]
|
||||
taxonomySafe["value"] += levels["safe"]
|
||||
taxonomySuspicious["value"] += levels["suspicious"]
|
||||
taxonomyMalicious["value"] += levels["malicious"]
|
||||
|
||||
# Add results taxonomy anyway
|
||||
taxonomies.append(self.build_taxonomy(taxonomyResults["level"], taxonomyResults["namespace"], taxonomyResults["predicate"], taxonomyResults["value"]))
|
||||
|
||||
# Only add optional taxonomies if they are not null
|
||||
if taxonomyInfo["value"] > 0:
|
||||
taxonomies.append(self.build_taxonomy(taxonomyInfo["level"], taxonomyInfo["namespace"], taxonomyInfo["predicate"], taxonomyInfo["value"]))
|
||||
if taxonomySafe["value"] > 0:
|
||||
taxonomies.append(self.build_taxonomy(taxonomySafe["level"], taxonomySafe["namespace"], taxonomySafe["predicate"], taxonomySafe["value"]))
|
||||
if taxonomySuspicious["value"] > 0:
|
||||
taxonomies.append(self.build_taxonomy(taxonomySuspicious["level"], taxonomySuspicious["namespace"], taxonomySuspicious["predicate"], taxonomySuspicious["value"]))
|
||||
if taxonomyMalicious["value"] > 0:
|
||||
taxonomies.append(self.build_taxonomy(taxonomyMalicious["level"], taxonomyMalicious["namespace"], taxonomyMalicious["predicate"], taxonomyMalicious["value"]))
|
||||
|
||||
|
||||
return {"taxonomies": taxonomies}
|
||||
|
||||
|
||||
def run(self):
|
||||
Analyzer.run(self)
|
||||
data = self.getParam('data', None, 'Data is missing')
|
||||
self.SplunkConnect()
|
||||
if self.data_type == 'url':
|
||||
self.SplunkURLSearch(data)
|
||||
elif self.data_type == 'ip':
|
||||
self.SplunkIPSearch(data)
|
||||
elif self.data_type in ['user-agent','uri_path','domain','fqdn','hash','file','filename','mail_subject','mail','email','registry','other']:
|
||||
self.SplunkOtherSearch(data)
|
||||
else:
|
||||
self.error('Invalid Datatype')
|
||||
|
||||
if __name__ == '__main__':
|
||||
Splunk().run()
|
53
thehive-templates/Splunk_Search_Domain_FQDN_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Domain_FQDN_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_Hash_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Hash_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
4
thehive-templates/Splunk_Search_Hash_3_0/short.html
Normal file
4
thehive-templates/Splunk_Search_Hash_3_0/short.html
Normal file
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_IP_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_IP_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
4
thehive-templates/Splunk_Search_IP_3_0/short.html
Normal file
4
thehive-templates/Splunk_Search_IP_3_0/short.html
Normal file
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_Mail_Email_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Mail_Email_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_Mail_Subject_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Mail_Subject_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_Other_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Other_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
4
thehive-templates/Splunk_Search_Other_3_0/short.html
Normal file
4
thehive-templates/Splunk_Search_Other_3_0/short.html
Normal file
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_Registry_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_Registry_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
4
thehive-templates/Splunk_Search_Registry_3_0/short.html
Normal file
4
thehive-templates/Splunk_Search_Registry_3_0/short.html
Normal file
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
53
thehive-templates/Splunk_Search_URL_URI_Path_3_0/long.html
Normal file
53
thehive-templates/Splunk_Search_URL_URI_Path_3_0/long.html
Normal file
@ -0,0 +1,53 @@
|
||||
<div class="panel panel-danger" ng-if="!success">
|
||||
<div class="panel-heading">
|
||||
<strong>{{(artifact.data || artifact.attachment.name) | fang}}</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{content.errorMessage}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="success">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
Summary
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<dl class="dl-horizontal" ng-repeat="res in content.savedsearches">
|
||||
<dt>{{res.savedsearch}}</dt>
|
||||
<dd>{{res.length}} results recovered out of a total of {{res.resultCount}} results over {{res.eventCount}} events</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info" ng-repeat="res in content.savedsearches">
|
||||
<div class="panel-heading">
|
||||
Results for "{{res.savedsearch}}"
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length != 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Results : </dt>
|
||||
<dd><div ng-class="{'text-warning': res.length<res.resultCount, 'text-success': res.length==res.resultCount}"><strong>{{res.length}}/{{res.resultCount}}</strong></div><div ng-if="res.note">Note: {{res.note}}</div></dd>
|
||||
<dt>Events : </dt>
|
||||
<dd>{{res.eventCount}}</dd>
|
||||
<dt ng-if="res.levels">Levels :</dt>
|
||||
<dd ng-if="res.levels.info>0" class='text-info'><div class='fa fa-question-circle wrap'> Info: {{res.levels.info}}</div></dd>
|
||||
<dd ng-if="res.levels.safe>0" class='text-success'><div class='fa fa-check-circle wrap'> Safe: {{res.levels.safe}}</div></dd>
|
||||
<dd ng-if="res.levels.suspicious>0" class='text-warning'><div class='fa fa-exclamation-triangle wrap'> Suspicious: {{res.levels.suspicious}}</div></dd>
|
||||
<dd ng-if="res.levels.malicious>0" class='text-danger'><div class='fa fa-bug wrap'> Malicious: {{res.levels.malicious}}</div></dd>
|
||||
</dl>
|
||||
<table class="table table-hover" >
|
||||
<tr>
|
||||
<td ng-repeat="(field,value) in res.results[0]"><strong>{{field}}</strong></td>
|
||||
</tr>
|
||||
<tr ng-repeat="line in res.results">
|
||||
<td ng-repeat="(field,value) in line" class="wrap"><div ng-if="field != 'level'">{{value}}</div><div ng-if="field == 'level'" ng-class="{'text-info fa fa-question-circle': value=='info', 'text-success fa fa-check-circle': value=='safe', 'text-warning fa fa-exclamation-triangle': value=='suspicious', 'text-danger fa fa-bug': value=='malicious'}"> {{value}}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="panel-body" ng-if="res.length == 0">
|
||||
<dl class="dl-horizontal">
|
||||
<dd>No result for this search</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,4 @@
|
||||
<span class="label" ng-repeat="t in content.taxonomies" ng-class="{'info': 'label-info', 'safe': 'label-success', 'suspicious': 'label-warning', 'malicious':'label-danger'}[t.level]">
|
||||
{{t.namespace}}:{{t.predicate}}="{{t.value}}"
|
||||
</span>
|
||||
|
Loading…
Reference in New Issue
Block a user