Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions responders/CyberTriage/cybertriage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"name": "CyberTriage",
"version": "1.0",
"author": "David Strassegger",
"url": "https://github.com/TheHive-Project/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Conduct a forensic investigation on the endpoint via a CyberTriage team server instance",
"dataTypeList": ["thehive:case_artifact"],
"command": "CyberTriage/cybertriage.py",
"baseConfig": "CyberTriage",
"config": {
"max_tlp": 3,
"check_tlp": false,
"max_pap": 1,
"check_pap": true
},
"configurationItems": [
{
"name": "ct_server",
"description": "CyberTriage Team Server IP address",
"type": "string",
"multi": false,
"required": true,
"defaultValue": "127.0.0.1"
},
{
"name": "ct_port",
"description": "API port for the CyberTriage API",
"type": "number",
"multi": false,
"required": true,
"defaultValue": 9443
},
{
"name": "ct_api_key",
"description": "API key for CyberTriage server",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "ct_username",
"description": "CyberTriage investigation username (domain\\username)",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "ct_password",
"description": "CyberTriage investivation user password",
"type": "string",
"multi": false,
"required": true,
"defaultValue": ""
},
{
"name": "ct_upload_hash",
"description": "Upload malware hash to cloud service",
"type": "boolean",
"multi": false,
"defaultValue": true,
"required": false
},
{
"name": "ct_upload_file",
"description": "Upload malware file content to cloud service",
"type": "boolean",
"multi": false,
"defaultValue": false,
"required": true
}
]
}
103 changes: 103 additions & 0 deletions responders/CyberTriage/cybertriage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from cortexutils.responder import Responder
from requests.exceptions import RequestException
import requests
import ipaddress
import json

requests.packages.urllib3.disable_warnings()

class CyberTriage(Responder):
def __init__(self):
Responder.__init__(self)
self.ct_server = self.get_param('config.ct_server', '127.0.0.1')
self.ct_port = self.get_param('config.ct_port', '9443')
self.ct_username = self.get_param(
'config.ct_username', None,
'Missing investigation username')
self.ct_password = self.get_param(
'config.ct_password', None,
'Missing investigation user password')
self.ct_upload_hash = self.get_param('config.ct_upload_hash', True)
self.ct_upload_file = self.get_param('config.ct_upload_file', False)
self.__req_headers = {
'Content-Type': 'application/json',
'restApiKey': self.get_param(
'config.ct_api_key', None,
'Missing CyberTriage API Key')
}
self.__verify_server_cert = False
self.ct_sid = None

def check_credentials(self):
try:
_r = requests.get(
'https://{0}:{1}/api/correlation/checkcredentials'.format(
self.ct_server, self.ct_port
),
headers=self.__req_headers,
verify=self.__verify_server_cert
)
if _r.status_code == 200:
return True
else:
self.error("API Request failed: {}".format(_r.text))
except RequestException as e:
self.error("Failed to make requests due to {}".format(e.strerror))

def triage_endpoint(self, endpoint, incident_name):
# Make data dict for rest call
json_data = {
'incidentName': incident_name,
'hostName': endpoint,
'userId': self.ct_username,
'password': self.ct_password,
'scanOptions': ",".join([
'pr', 'nw', 'nc', 'st', 'sc',
'ru', 'co', 'lo', 'ns', 'wb', 'fs'
]),
'malwareScanRequested': self.ct_upload_hash,
'sendContent': self.ct_upload_file,
'sendIpAddress': False
}

try:
_r = requests.post(
'https://{0}:{1}/api/livesessions'.format(
self.ct_server, self.ct_port
),
json=json_data,
headers=self.__req_headers,
verify=self.__verify_server_cert
)
if _r.status_code == 202: # 202 accepted is returned on successful submission
self.ct_sid = _r.json()["SessionId"]
else:
self.error("API Requests failed {}: {}".format(_r.status_code, _r.text))
except RequestException as e:
self.error("Failed to make requests due to {}".format(e.strerror))

def run(self):
Responder.run(self)

if self.get_param("data.dataType") in ["ip"]:
endpoint = self.get_param("data.data")
else:
self.error('Invalid datatype {}'.format(self.get_param("data.dataType")))

caseId = self.get_param("data.case.caseId")

if ipaddress.IPv4Address(endpoint).is_private:
if self.check_credentials():
self.triage_endpoint(endpoint=endpoint, incident_name=caseId)
self.report({'message': 'Endpoint {} under investigation. Incident Name: {}, Session ID: {}'.format(endpoint, caseId, self.ct_sid)})
else:
self.error('IP Address {0} is out of scope'.format(endpoint))

def operations(self, raw):
return [self.build_operation('AddTagToArtifact', tag='CyberTriage:Investigated')]


if __name__ == '__main__':
CyberTriage().run()
3 changes: 3 additions & 0 deletions responders/CyberTriage/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cortexutils
requests
ipaddress