-
Notifications
You must be signed in to change notification settings - Fork 533
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5d3f229
commit 81e4fe7
Showing
49 changed files
with
1,392 additions
and
261 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,58 @@ | ||
sensoroni: | ||
enabled: False | ||
config: | ||
analyze: | ||
enabled: False | ||
timeout_ms: 900000 | ||
parallel_limit: 5 | ||
node_checkin_interval_ms: 10000 | ||
sensoronikey: | ||
soc_host: | ||
analyzers: | ||
emailrep: | ||
base_url: https://emailrep.io/ | ||
api_key: | ||
greynoise: | ||
base_url: https://api.greynoise.io/ | ||
api_key: | ||
api_version: community | ||
localfile: | ||
file_path: [] | ||
otx: | ||
base_url: https://otx.alienvault.com/api/v1/ | ||
api_key: | ||
pulsedive: | ||
base_url: https://pulsedive.com/api/ | ||
api_key: | ||
spamhaus: | ||
lookup_host: zen.spamhaus.org | ||
nameservers: [] | ||
sublime_platform: | ||
base_url: https://api.platform.sublimesecurity.com | ||
api_key: | ||
live_flow: False | ||
mailbox_email_address: | ||
message_source_id: | ||
urlscan: | ||
base_url: https://urlscan.io/api/v1/ | ||
api_key: | ||
enabled: False | ||
visibility: public | ||
timeout: 180 | ||
virustotal: | ||
base_url: https://www.virustotal.com/api/v3/search?query= | ||
api_key: | ||
sensoroni: | ||
enabled: False | ||
config: | ||
analyze: | ||
enabled: False | ||
timeout_ms: 900000 | ||
parallel_limit: 5 | ||
node_checkin_interval_ms: 10000 | ||
sensoronikey: | ||
soc_host: | ||
analyzers: | ||
echotrail: | ||
base_url: https://api.echotrail.io/insights/ | ||
api_key: | ||
elasticsearch: | ||
base_url: | ||
auth_user: | ||
auth_pwd: | ||
num_results: 10 | ||
api_key: | ||
index: _all | ||
time_delta_minutes: 14400 | ||
timestamp_field_name: '@timestamp' | ||
map: {} | ||
cert_path: | ||
emailrep: | ||
base_url: https://emailrep.io/ | ||
api_key: | ||
greynoise: | ||
base_url: https://api.greynoise.io/ | ||
api_key: | ||
api_version: community | ||
localfile: | ||
file_path: [] | ||
otx: | ||
base_url: https://otx.alienvault.com/api/v1/ | ||
api_key: | ||
pulsedive: | ||
base_url: https://pulsedive.com/api/ | ||
api_key: | ||
spamhaus: | ||
lookup_host: zen.spamhaus.org | ||
nameservers: [] | ||
sublime_platform: | ||
base_url: https://api.platform.sublimesecurity.com | ||
api_key: | ||
live_flow: False | ||
mailbox_email_address: | ||
message_source_id: | ||
urlscan: | ||
base_url: https://urlscan.io/api/v1/ | ||
api_key: | ||
enabled: False | ||
visibility: public | ||
timeout: 180 | ||
virustotal: | ||
base_url: https://www.virustotal.com/api/v3/search?query= | ||
api_key: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# EchoTrail | ||
|
||
|
||
## Description | ||
Submit a filename, hash, commandline to EchoTrail for analysis | ||
|
||
## Configuration Requirements | ||
|
||
In SOC, navigate to `Administration`, toggle `Show all configurable settings, including advanced settings.`, and navigate to `sensoroni` -> `analyzers` -> `echotrail`. | ||
|
||
![echotrail](https://github.com/RyHoa/securityonion/assets/129560634/43b55869-1fba-4907-8418-c0745c37237b) | ||
|
||
|
||
The following configuration options are available for: | ||
|
||
``api_key`` - API key used for communication with the Echotrail API (Required) | ||
|
||
This value should be set in the ``sensoroni`` pillar, like so: | ||
|
||
``` | ||
sensoroni: | ||
analyzers: | ||
echotrail: | ||
api_key: $yourapikey | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"name": "Echotrail", | ||
"version": "0.1", | ||
"author": "Security Onion Solutions", | ||
"description": "This analyzer queries Echotrail to see if a related filename, hash, or commandline is considered malicious.", | ||
"supportedTypes" : ["filename","hash","commandline"], | ||
"baseUrl": "https://api.echotrail.io/insights/" | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import json | ||
import os | ||
import sys | ||
import requests | ||
import helpers | ||
import argparse | ||
|
||
# for test usage: | ||
# python3 echotrail.py '{"artifactType":"hash", "value":"438b6ccd84f4dd32d9684ed7d58fd7d1e5a75fe3f3d12ab6c788e6bb0ffad5e7"}' | ||
# You will need to provide an API key in the .yaml file. | ||
|
||
def checkConfigRequirements(conf): | ||
if not conf['api_key']: | ||
sys.exit(126) | ||
else: | ||
return True | ||
|
||
|
||
def sendReq(conf, observ_value): | ||
# send a get requests using a user-provided API key and the API url | ||
url = conf['base_url'] + observ_value | ||
headers = {'x-api-key': conf['api_key']} | ||
response = requests.request('GET', url=url, headers=headers) | ||
return response.json() | ||
|
||
|
||
def prepareResults(raw): | ||
# checking for the 'filenames' key alone does | ||
# not work when querying by filename. | ||
# So, we can account for a hash query, a filename query, | ||
# and anything else with these if statements. | ||
if 'filenames' in raw.keys(): | ||
summary = raw['filenames'][0][0] | ||
elif 'tags' in raw.keys(): | ||
summary = raw['tags'][0][0] | ||
else: | ||
summary = 'inconclusive' | ||
status = 'info' | ||
return {'response': raw, 'summary': summary, 'status': status} | ||
|
||
|
||
def analyze(conf, input): | ||
# put all of our methods together and return a properly formatted output. | ||
checkConfigRequirements(conf) | ||
meta = helpers.loadMetadata(__file__) | ||
data = helpers.parseArtifact(input) | ||
helpers.checkSupportedType(meta, data['artifactType']) | ||
response = sendReq(conf, data['value']) | ||
return prepareResults(response) | ||
|
||
|
||
def main(): | ||
dir = os.path.dirname(os.path.realpath(__file__)) | ||
parser = argparse.ArgumentParser( | ||
description='Search Echotrail for a given artifact') | ||
parser.add_argument( | ||
'artifact', help='the artifact represented in JSON format') | ||
parser.add_argument('-c', '--config', metavar='CONFIG_FILE', default=dir + '/echotrail.yaml', | ||
help='optional config file to use instead of the default config file') | ||
args = parser.parse_args() | ||
if args.artifact: | ||
results = analyze(helpers.loadConfig(args.config), args.artifact) | ||
print(json.dumps(results)) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
base_url: "{{ salt['pillar.get']('sensoroni:analyzers:echotrail:base_url', 'https://api.echotrail.io/insights/') }}" | ||
api_key: "{{ salt['pillar.get']('sensoroni:analyzers:echotrail:api_key', '') }}" | ||
|
61 changes: 61 additions & 0 deletions
61
salt/sensoroni/files/analyzers/echotrail/echotrail_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
from io import StringIO | ||
import sys | ||
from unittest.mock import patch, MagicMock | ||
import unittest | ||
import echotrail | ||
import helpers | ||
|
||
|
||
class TestEchoTrailMethods(unittest.TestCase): | ||
def test_main_success(self): | ||
with patch('sys.stdout', new=StringIO()) as mock_cmd: | ||
with patch('echotrail.analyze', new=MagicMock(return_value={'test': 'val'})) as mock: | ||
sys.argv = ["test", "test"] | ||
echotrail.main() | ||
expected = '{"test": "val"}\n' | ||
self.assertEqual(mock_cmd.getvalue(), expected) | ||
mock.assert_called_once() | ||
|
||
def test_main_missing_input(self): | ||
with patch('sys.exit', new=MagicMock()) as sysmock: | ||
with patch('sys.stderr', new=StringIO()) as mock_stderr: | ||
sys.argv = ["cmd"] | ||
echotrail.main() | ||
self.assertEqual(mock_stderr.getvalue(), "usage: cmd [-h] [-c CONFIG_FILE] artifact\ncmd: error: the following arguments are required: artifact\n") | ||
|
||
def test_checkConfigRequirements(self): | ||
conf = {'base_url': 'https://www.randurl.xyz/', 'api_key':''} | ||
with self.assertRaises(SystemExit) as cm: | ||
echotrail.checkConfigRequirements(conf) | ||
self.assertEqual(cm.exception.code, 126) | ||
|
||
def test_sendReq(self): | ||
with patch('requests.request', new=MagicMock(return_value=MagicMock())) as mock: | ||
response = echotrail.sendReq(conf={'base_url': 'https://www.randurl.xyz/', 'api_key':'randkey'}, observ_value='example_data') | ||
self.assertIsNotNone(response) | ||
|
||
def test_prepareResults_noinput(self): | ||
raw = {} | ||
sim_results = {'response': raw, | ||
'status': 'info', 'summary': 'inconclusive'} | ||
results = echotrail.prepareResults(raw) | ||
self.assertEqual(results, sim_results) | ||
|
||
def test_prepareResults_none(self): | ||
raw = {'query_status': 'no_result'} | ||
sim_results = {'response': raw, | ||
'status': 'info', 'summary': 'inconclusive'} | ||
results = echotrail.prepareResults(raw) | ||
self.assertEqual(results, sim_results) | ||
|
||
def test_analyze(self): | ||
sendReqOutput = {'threat': 'no_result'} | ||
input = '{"artifactType":"hash", "value":"1234"}' | ||
prepareResultOutput = {'response': '', | ||
'summary': 'inconclusive', 'status': 'info'} | ||
conf = {"api_key": "xyz"} | ||
|
||
with patch('echotrail.sendReq', new=MagicMock(return_value=sendReqOutput)) as mock: | ||
with patch('echotrail.prepareResults', new=MagicMock(return_value=prepareResultOutput)) as mock2: | ||
results = echotrail.analyze(conf, input) | ||
self.assertEqual(results["summary"], "inconclusive") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
requests>=2.31.0 | ||
pyyaml>=6.0 |
Binary file added
BIN
+722 KB
...ail/source-packages/PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Binary file not shown.
Binary file added
BIN
+159 KB
salt/sensoroni/files/analyzers/echotrail/source-packages/certifi-2023.11.17-py3-none-any.whl
Binary file not shown.
Binary file added
BIN
+139 KB
...ackages/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Binary file not shown.
Binary file added
BIN
+60.1 KB
salt/sensoroni/files/analyzers/echotrail/source-packages/idna-3.6-py3-none-any.whl
Binary file not shown.
Binary file added
BIN
+61.1 KB
salt/sensoroni/files/analyzers/echotrail/source-packages/requests-2.31.0-py3-none-any.whl
Binary file not shown.
Binary file added
BIN
+102 KB
salt/sensoroni/files/analyzers/echotrail/source-packages/urllib3-2.1.0-py3-none-any.whl
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Elasticsearch | ||
Elasticsearch returns an informational breakdown of the queried observable. | ||
|
||
## Overview | ||
Elasticsearch facilitates queries within the user's database. User can use these observable type: hash, domain, file, filename, fqdn, gimphash, IP, mail, mail_subject, regexp, registry, telfhash, tlsh, uri_path, URL, and user-agent values. | ||
|
||
## Description | ||
Configure and submit the field you want to search for in your database. Ex: domain, hash, IP, or URL | ||
|
||
## Requirement | ||
An API key or User Credentials is necessary for utilizing Elasticsearch. | ||
|
||
## Configuration Requirements | ||
|
||
In SOC, navigate to `Administration`, toggle `Show all configurable settings, including advanced settings.`, and navigate to `sensoroni` -> `analyzers` -> `elasticsearch`. | ||
|
||
![image](https://github.com/RyHoa/securityonion/assets/129560634/31c612d3-39f8-4d9e-881b-210c87a56b50) | ||
|
||
|
||
The following configuration options are available for: | ||
|
||
``api_key`` - API key used for communication with the Elasticsearch API (Optional if auth_user and auth_pwd are used) | ||
|
||
``auth_user`` - Username used for communication with Elasticsearch | ||
|
||
``auth_pwd`` - Password used for communication with Elasticsearch | ||
|
||
``base_url`` - URL that connect to Elasticsearch VM on port 9200. Example format :"https://<your IP address>:9200 | ||
|
||
``index`` - The index of the data in Elasticsearch database. Default value is _all. | ||
|
||
``num_results`` - The max number of results will be displayed. Default value is 10. | ||
|
||
``time_delta_minutes`` - Range of time the users want the data in minutes. The value is in minutes and will be converted to days. Defaults value is is 1440. | ||
|
||
``timestamp_field_name`` - The name of your timestamp field name. Default value is @timestamp. | ||
|
||
``map`` - This is the dictionary of the field name in the user's Elasticsearch database. Example value {"hash":"userhashfieldname"}. This value will map the Security Onion hash field name to user hash field name. | ||
|
||
``cert_path`` - This is the path to the certificate in the host for authentication purpose (Required) | ||
|
||
This value should be set in the ``sensoroni`` pillar, like so: | ||
|
||
``` | ||
sensoroni: | ||
analyzers: | ||
elasticsearch: | ||
base_url:$yourbase_url | ||
api_key: $yourapi_key | ||
numResults:$yournum_results | ||
auth_user:$yourauth_user | ||
auth_pwd:$yourauth_pwd | ||
index:$yourindex | ||
timeDeltaMinutes:$yourtime_delta_minutes | ||
timestampFieldName:$yourtimestamp_field_name | ||
cert_path:$yourcert_path | ||
map:$yourmap | ||
``` |
9 changes: 9 additions & 0 deletions
9
salt/sensoroni/files/analyzers/elasticsearch/elasticsearch.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "Elastic Search", | ||
"version": "0.1", | ||
"author": "Security Onion Solutions", | ||
"description": "Queries an ElasticSearch instance for specified field values.", | ||
"supportedTypes": ["hash", "ip", "domain"] | ||
} | ||
|
||
|
Oops, something went wrong.