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
69 changes: 69 additions & 0 deletions analyzers/SecurityCenter/SecurityCenter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "SecurityCenter",
"version": "1.0",
"author": "Tommy Bohde",
"url": "https://github.com/InsanesTheName/Cortex-Analyzers",
"license": "AGPL-V3",
"description": "Launch a scan through Tenable SecurityCenter",
"dataTypeList": ["ip", "fqdn"],
"baseConfig": "SecurityCenter",
"command": "SecurityCenter/SecurityCenter.py",
"configurationItems": [
{
"name": "host",
"description": "IP address of the host running the SecurityCenter API",
"type": "string",
"multi": false,
"required": true
},
{
"name": "login",
"description": "Login for SecurityCenter API",
"type": "string",
"multi": false,
"required": true
},
{
"name": "password",
"description": "Password for SecurityCenter API",
"type": "string",
"multi": false,
"required": true
},
{
"name": "policy",
"description": "Scan policy ID",
"type": "number",
"multi": false,
"required": true
},
{
"name": "credential",
"description": "Scan credential ID",
"type": "number",
"multi": false,
"required": true
},
{
"name": "emailOnLaunch",
"description": "Send an email when the scan is launched",
"type": "boolean",
"multi": false,
"required": true
},
{
"name": "emailOnComplete",
"description": "Send an email when the scan is completed",
"type": "boolean",
"multi": false,
"required": true
},
{
"name": "report",
"description": "Report ID to run post-scan",
"type": "number",
"multi": false,
"required": true
}
]
}
103 changes: 103 additions & 0 deletions analyzers/SecurityCenter/SecurityCenter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
# encoding: utf-8

import re
import time
import socket

from cortexutils.analyzer import Analyzer
from tenable.sc import TenableSC

class SCAnalyzer(Analyzer):

def __init__(self):
Analyzer.__init__(self)
base = 'config.'

# using getParam(name, default=None, message=None)
self.ip = self.get_param(
base + 'host', None, 'Missing SecurityCenter IP')
self.login = self.get_param(
base + 'login', None, 'Missing SecurityCenter login')
self.password = self.get_param(
base + 'password', None, 'Missing SecurityCenter password')
self.policyID = self.get_param(
base + 'policy', None, 'Missing policy ID')
self.credentialID = self.get_param(
base + 'credential', None, 'Missing scan credential ID')
self.reportID = self.get_param(
base + 'report', None, 'Missing report ID')
self.email_on_launch = self.get_param(
base + 'emailOnLaunch', False, None)
self.email_on_complete = self.get_param(
base + 'emailOnComplete', False, None)

def run(self):
Analyzer.run(self)

if self.data_type != 'ip' and self.data_type != 'fqdn':
self.error('Invalid data type')

try:
sc = TenableSC(self.ip)
sc.login(self.login, self.password)

results = self._run_scan(sc)

sc.logout()

except Exception as ex:
self.error('Error: %s' % ex)

self.report(results)

def _run_scan(self, sc):
target_hosts = re.split(r'[,\s]+', self.get_param('data'))
name = 'CORTEX | '
for i, h in enumerate(target_hosts):
if (self.data_type == 'ip'):
try:
hostname = socket.gethostbyaddr(h)[0].split('.')[0].upper()
# \u00A0 is   (to make the report look nicer)
name += hostname + '\u00A0(' + h + ')'
except Exception:
name += h
elif (self.data_type == 'fqdn'):
try:
hostname = h.split('.')[0].upper()
name += hostname + '\u00A0(' + socket.gethostbyname(h) + ')'
except Exception:
name += h.split('0')[0].upper()
if (i != len(target_hosts) - 1):
name += ', '

r = sc.scans.create(name = name,
repo = 1,
policy_id = int(self.policyID),
email_launch = self.email_on_launch,
email_complete = self.email_on_complete,
credentials = [{'id': self.credentialID}],
reports = [{'id': self.reportID, 'reportSource': 'individual'}],
schedule = {'type': 'now'},
targets = target_hosts
)

resultID = r['scanResultID']

return self._get_scan_results(sc, resultID)

def _get_scan_results(self, sc, resultID):
results = {}
while True:
results = sc.scan_instances.details(int(resultID))
running = (results['running'].lower() == 'true')
status = results['status'].lower()
if (not running and status == 'completed'):
break
elif (status == 'error'):
self.error("Error: " + results['errorDetails'])
time.sleep(5)
return results

if __name__ == '__main__':
SCAnalyzer().run()
2 changes: 2 additions & 0 deletions analyzers/SecurityCenter/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cortexutils
pytenable