def tenb_connection(): try: database = r"navi.db" conn = new_db_connection(database) with conn: cur = conn.cursor() cur.execute("SELECT * from keys;") rows = cur.fetchall() for row in rows: access_key = row[0] secret_key = row[1] # Check for custom URL try: cur.execute("SELECT * from url;") url_rows = cur.fetchall() url = url_rows[0][1] tio = TenableIO(access_key, secret_key, url=url, vendor='Casey Reid', product='navi', build=navi_version()) return tio except Error: tio = TenableIO(access_key, secret_key, vendor='Casey Reid', product='navi', build=navi_version()) return tio except Error: pass
def GenerateReport(DEBUG, accesskey, secretkey, repo, image, tag): client = TenableIO(accesskey, secretkey) # Gather the list of repositories resp = client.get("container-security/api/v2/reports/" + repo + "/" + image + "/" + tag) respdata = json.loads(resp.text) if DEBUG: print("Response", respdata) print("\n\n") with open("tiocs-report.csv", "w") as csvfile: fieldnames = [ 'cve', 'severity', 'vuln publication date', 'affected packages', 'remediation', 'description' ] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for i in respdata['findings']: packages = "" for j in i['packages']: if packages != "": packages += "\n" if DEBUG: print("Software packages affected", j['name'], j['version']) packages = packages + ' ' + str(j['name']) + ' ' + str( j['version']) if DEBUG: print(i) print("\n\n") print("Package", i['packages']) print("NVD Finding", i['nvdFinding']) print("CVE", i['nvdFinding']['cve']) print("Severity", i['nvdFinding']['cvss_score']) print("Remediation", i['nvdFinding']['remediation']) print("Description", i['nvdFinding']['description']) print("Vulnerability publication date", i['nvdFinding']['published_date']) rowdict = { 'cve': i['nvdFinding']['cve'], 'severity': i['nvdFinding']['cvss_score'], 'vuln publication date': i['nvdFinding']['published_date'], 'remediation': str(i['nvdFinding']['remediation']), 'description': str(i['nvdFinding']['description']), 'affected packages': packages } writer.writerow(rowdict) csvfile.close() return
def cli(tio_access_key, tio_secret_key, batch_size, verbose, observed_since, run_every, threads, service_account_file, source_id): ''' Tenable.io -> Google Cloud Security Command Center Transformer & Ingester ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) # Initiate the Tenable.io API model, the Ingester model, and start the # ingestion and data transformation. tio = TenableIO(tio_access_key, tio_secret_key, ua_identity='Tio2CSCC/{}'.format(__version__)) gcp = SecurityCommandCenter(service_account_file, source_id) ingest = GoogleSCCIngest(tio, gcp) ingest.ingest(observed_since, batch_size, threads) # If we are expected to continually re-run the transformer, then we will # need to track the passage of time and run every X hours, where X is # defined by the user. if run_every and run_every > 0: while True: sleeper = run_every * 3600 last_run = int(time.time()) logging.info( 'Sleeping for {}s before next iteration'.format(sleeper)) time.sleep(sleeper) logging.info( 'Initiating ingest with observed_since={}'.format(last_run)) ingest.ingest(last_run, batch_size, threads)
def cli(output, akey, skey, sevs, last_found, cidr, tags, fields, verbose): ''' Export -> CSV Writer Generates a CSV File from the vulnerability export using the fields specified. ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) # Instantiate the Tenable.io instance & initiate the vulnerability export. tio = TenableIO(akey, skey) vulns = tio.exports.vulns(last_found=last_found, severity=list(sevs), cidr_range=cidr, tags=list(tags)) # Pass everything to the CSV generator. total = export_vulns_to_csv(output, vulns, *fields) click.echo('Processed {} Vulnerabilities'.format(total))
def download_scans(access_key, secret_key, search, path, filters, **kwargs): ''' Attempts to download the latest completed scan from tenable.io and stores the file in the path specified. The exported scan will be filtered based on the filters specified. ''' tio = TenableIO(access_key, secret_key) # Get the list of scans that match the name filter defined. scans = [s for s in tio.scans.list() if search.lower() in s['name'].lower()] for scan in scans: details = tio.scans.results(scan['id']) # get the list of scan histories that are in a completed state. completed = [h for h in details.get('history', list()) if h.get('status') == 'completed'] # download the latest completed scan using the scan name && history id # and store the file in the path specified using the filename format: # {SCAN_NAME}-{HISTORY_ID}.{FORMAT} if len(completed) > 0: history = completed[0] with open(os.path.join(path, '{}-{}.{}'.format( scan['name'].replace(' ', '_'), history['uuid'], kwargs['format'])), 'wb') as report_file: kw = kwargs kw['history_id'] = history['history_id'] kw['fobj'] = report_file click.echo('Scan completed at {} downloading to {}'.format( arrow.get(history['last_modification_date']).isoformat(), report_file.name)) tio.scans.export(scan['id'], *filters, **kw)
def cli(tio_access_key, tio_secret_key, batch_size, verbose, observed_since, run_every, ibm_password_key, ibm_access_key, ibm_car_uri): ''' Tenable.io -> IBM CloudPak for Security Transformer & Ingester ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) # Initiate the Tenable.io API model, the Ingester model, and start the # ingestion and data transformation. tio = TenableIO(tio_access_key, tio_secret_key, vendor='Tenable', product='CloudPak4Security', build=__version__) ibm = CloudPak4Security(ibm_access_key, ibm_password_key, url=ibm_car_uri) ingest = Tio2CP4S(tio, ibm) ingest.ingest(observed_since, batch_size) # If we are expected to continually re-run the transformer, then we will # need to track the passage of time and run every X hours, where X is # defined by the user. if run_every and run_every > 0: while True: sleeper = run_every * 3600 last_run = int(time.time()) logging.info( 'Sleeping for {}s before next iteration'.format(sleeper)) time.sleep(sleeper) logging.info( 'Initiating ingest with observed_since={}'.format(last_run)) ingest.ingest(last_run, batch_size, threads)
def cli(output, akey, skey, fields, verbose, **kwargs): ''' Export -> CSV Writer Generates a CSV File from the vulnerability export using the fields specified. ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) kwargs['sources'] = list(kwargs['sources']) kwargs['tags'] = list(kwargs['tags']) filters = dict() for key in kwargs.keys(): if kwargs[key]: filters[key] = kwargs[key] # Instantiate the Tenable.io instance & initiate the vulnerability export. tio = TenableIO(akey, skey) assets = tio.exports.assets(**filters) # Pass everything to the CSV generator. total = export_assets_to_csv(output, assets, *fields) click.echo('Processed {} Assets'.format(total))
def initialize(self): # Load the state in initialize, use it to store data # that needs to be accessed across actions self._state = self.load_state() # get the asset config config = self.get_config() """ # Access values in asset config by the name # Required values can be accessed directly required_config_name = config["required_config_name"] # Optional values should use the .get() function optional_config_name = config.get("optional_config_name") """ self._tio = TenableIO( config["access_key"], config["secret_key"], ssl_verify=config.get("verify_server_cert", True), vendor="Splunk", product="Phantom", ) return phantom.APP_SUCCESS
def test_init_unexpected_value_error(): ''' test to raise the exception when no api keys are provided ''' with pytest.warns(AuthenticationWarning): TenableIO()
def ConnectIO(DEBUG,accesskey,secretkey,host,port): #Create the connection to Tenable.io try: tio=TenableIO(accesskey, secretkey) except: print("Error connecting to Tenable.io") return(False) return(tio)
def sechub(): return SecurityHubIngester( region=os.getenv('AWS_REGION'), account_id=os.getenv('AWS_ACCOUNT_ID'), tio=TenableIO(os.getenv('TIO_TEST_ACCESS_KEY'), os.getenv('TIO_TEST_SECRET_KEY')), aws_access_id=os.getenv('AWS_ACCESS_ID'), aws_secret_key=os.getenv('AWS_SECRET_KEY'), )
def GenerateVulnCSV(DEBUG, accesskey, secretkey, host, port, filename): #Create the connection to Tenable.io if DEBUG: print("Connecting to Tenable.io") tio = TenableIO(accesskey, secretkey) #Gather the list of assets if DEBUG: print("Making request to Tenable.io for vulnerability export") vulns = tio.exports.vulns() #Open the file that will become a CSV with open(filename, "w") as csvfile: #Create the header of the CSV file #The field names should be the same as what comes from the API. For fields nested inside other fields (i.e. {'plugin': {'id': 19506}}) # then separate the field names with a dot (.) (i.e. "plugin.id") fieldnames = [ 'severity', 'plugin.cvss3_base_score', 'plugin.id', 'plugin.cve', 'plugin.name', 'first_found', 'last_found', 'plugin.publication_date', 'plugin.patch_publication_date', 'plugin.vpr.score', 'asset.ipv4', 'asset.agent_uuid', 'asset.hostname' ] #Create a CSV writer and associate with the file handle writer = csv.DictWriter(csvfile, fieldnames=fieldnames) #Write the CSV headers writer.writeheader() #Loop through all the downloaded assets and write them into the CSV file for i in vulns: if DEBUG: print("vuln:", i) rowdict = {} for j in fieldnames: if DEBUG: print("fieldname:", j) try: y = i for x in re.split(r'\.', j): if DEBUG: print("key:", x) y = y[x] if DEBUG: print("y=:", y) if DEBUG: print("final y=", y) rowdict[j] = y except: rowdict[j] = None writer.writerow(rowdict) #Close the file csvfile.close() return (True)
def test_io_compile(api): ''' test to raise the exception when value for api keys is not passed correctly ''' try: TenableIO() AccessGroupsIterator(api) AccessGroupsAPI(api) AccessGroupsIteratorV2(api) AccessGroupsV2API(api) AgentConfigAPI(api) AgentExclusionsAPI(api) AgentGroupsAPI(api) AgentsAPI(api) AgentsIterator(api) AssetsAPI(api) AuditLogAPI(api) TIOIterator(api) TIOEndpoint(api) CredentialsAPI(api) CredentialsIterator(api) EditorAPI(api) ExclusionsAPI(api) ExportsAPI(api) ExportsIterator(api) FileAPI(api) FiltersAPI(api) FoldersAPI(api) GroupsAPI(api) NetworksAPI(api) NetworksIterator(api) PermissionsAPI(api) PluginsAPI(api) PluginIterator(api) PoliciesAPI(api) ScannerGroupsAPI(api) ScannersAPI(api) ScansAPI(api) ScanHistoryIterator(api) ServerAPI(api) SessionAPI(api) TagsAPI(api) TagsIterator(api) TargetGroupsAPI(api) UsersAPI(api) WorkbenchesAPI(api) except NameError as error: print('\n The following name error exists: {}'.format(error)) pytest.raises(NameError) assert True except UnexpectedValueError as error: print('\n The following value error exists: {}'.format(error)) pytest.raises(UnexpectedValueError) assert True
def connect(self): if self.host is not None and self.port is not None: if self.tio_access_key is not None and self.tio_secret_key is not None: self.tenable_connection = TenableIO(self.tio_access_key, self.tio_secret_key) return self.tenable_connection elif self.tsc_username is not None and self.tsc_password is not None: self.tenable_connection = TenableSC(self.host, port=self.port) self.tenable_connection.login(self.tsc_username, self.tsc_password) return self.tenable_connection return False
def test_io_login(access_key, secret_key): print('\n\r testing login...\n\r') io = TenableIO(access_key, secret_key) try: sesson_details = io.session.details() print(' login success\n\r') return (io) except tenable.errors.PermissionError as e: print() print(' Login to ' + endpoint_address + ' failed, please try again..' + "\n") raise ValueError
def ingest(table_name, options): token = options['token'] secret = options['secret'] global TIO, GET TIO = TenableIO(token, secret) def GET(resource, key=None, limit=100, offset=0): if key is None: key = resource log.debug(f'GET {resource} limit={limit} offset={offset}') response = requests.get( url=f'https://cloud.tenable.com/{resource}', params={ 'limit': limit, 'offset': offset }, headers={"X-ApiKeys": f"accessKey={token}; secretKey={secret}"}, ) if response.status_code != 200: log.info( f'response status {response.status_code}: {response.text}') return result = response.json() elements = result.get(key) if elements is None: log.error(f'no {key} in :', result) return yield from elements pages = result.get('pagination', {}) total = pages.get('total', 0) limit = pages.get('limit', 0) offset = pages.get('offset', 0) if total > limit + offset: yield from GET(resource, key, limit, offset + limit) if table_name.endswith('_USER_CONNECTION'): return ingest_users(table_name) elif table_name.endswith('_AGENT_CONNECTION'): return ingest_agents(table_name, options) elif table_name.endswith('_VULN_CONNECTION'): return ingest_vulns(table_name)
def list_creds(access_key, secret_key): tio = TenableIO(access_key, secret_key) print('[+] Fetching credentials list') print( f'{"Name ".ljust(30)} {"UUID ".ljust(36)} {"Category ".ljust(30)} {"Type ".ljust(30)}' ) print( f'{"".ljust(30, "=")} {"".ljust(36, "=")} {"".ljust(30, "=")} {"".ljust(30, "=")}' ) for cred in tio.credentials.list(): print( f'{cred["name"].ljust(30)} {cred["uuid"].ljust(36)} {cred["category"]["name"].ljust(30)} {cred["type"]["name"].ljust(30)}' )
def __init__(self, access_key, secret_key): """Capture access and secret key for Tenable.IO API args: access_key (str): Access key for Tenable.IO. secret_key (str): Secret key for Tenable.IO. Return: None """ self.access_key = access_key self.secret_key = secret_key self.tio = TenableIO(self.access_key, self.secret_key) logging.info("Authenticated successfully with Tenable")
def cli(ctx, verbose, tio_access_key, tio_secret_key, tsc_host, tsc_port, tsc_username, tsc_password, tsc_access_key, tsc_secret_key): ''' Tenable Command-Line Interface (Tenable-CLI) ''' # Setup the logging verbosity. log_fmt = '%(asctime)-15s %(message)s' if verbose == 0: logging.basicConfig(level=logging.WARNING, format=log_fmt) if verbose == 1: logging.basicConfig(level=logging.INFO, format=log_fmt) if verbose > 1: logging.basicConfig(level=logging.DEBUG, format=log_fmt) # Setup the context object ctx.ensure_object(dict) ctx.obj['tio'] = None ctx.obj['tsc'] = None # If the Tenable.io Secret Keys and Access Keys are passed, we will then # instantiate the TenableIO object if tio_access_key and tio_secret_key: ctx.obj['tio'] = TenableIO(access_key=tio_access_key, secret_key=tio_secret_key, vendor='Tenable', product='TenableCLI', build=__version__) # If the Tenable.sc parameters are specified with User Auth, then we will # instantiate the TenableSC object and login using user-auth. if tsc_host and tsc_port and tsc_username and tsc_password: ctx.obj['tsc'] = TenableSC(address=tsc_host, port=tsc_port, vendor='Tenable', product='TenableCLI', build=__version__) ctx.obj['tsc'].login(tsc_username, tsc_password) # if the Tenable.sc parameters are specified with API keys, then we will # instantiate the TenableSC object and use the API keys for keyed auth. elif tsc_host and tsc_port and tsc_access_key and tsc_secret_key: ctx.obj['tsc'] = TenableSC(address=tsc_host, port=tsc_port, access_key=tsc_access_key, secret_key=tsc_secret_key, vendor='Tenable', product='TenableCLI', build=__version__)
def tenb_connection(): database = r"navi.db" conn = new_db_connection(database) with conn: cur = conn.cursor() cur.execute("SELECT * from keys;") rows = cur.fetchall() for row in rows: access_key = row[0] secret_key = row[1] tio = TenableIO(access_key, secret_key, vendor='Casey Reid', product='navi', build=navi_version()) return tio
def ingest(table_name, options): token = options['token'] secret = options['secret'] global TIO, GET TIO = TenableIO(token, secret) def GET(resource, name, limit=100, offset=0): response = requests.get( url=f'https://cloud.tenable.com/scanners/1/{resource}', params={ 'limit': limit, 'offset': offset, }, headers={"X-ApiKeys": f"accessKey={token}; secretKey={secret}"}, ) result = response.json() elements = result.get(name) if elements is None: log.error(f'no {name} in :', result) return yield from elements pages = result.get('pagination', {}) total = pages.get('total', 0) limit = pages.get('limit', 0) offset = pages.get('offset', 0) if total > limit + offset: yield from GET(resource, name, limit, offset + limit) if table_name.endswith('USER_CONNECTION'): ingest_users(table_name) elif table_name.endswith('AGENT_CONNECTION'): ingest_agents(table_name, options) elif table_name.endswith('VULN_CONNECTION'): ingest_vulns(table_name)
def cli(tio_access_key, tio_secret_key, batch_size, verbose, run_every, auth_uri, azure_uri, azure_app_id, azure_tenant_id, azure_app_secret, subscription): ''' Tenable.io -> Azure Security Center Transformer & Ingester ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) # Initiate the Tenable.io API model, the Ingester model, and start the # ingestion and data transformation. tio = TenableIO(tio_access_key, tio_secret_key, vendor='Tenable', product='Azure Security Center', build=__version__) asc = AzureSecurityCenter(azure_tenant_id, azure_app_id, azure_app_secret, auth_url=auth_uri, url=azure_uri) ingest = Tio2ASC(tio, asc, allowed_subs=subscription) ingest.ingest(batch_size) # If we are expected to continually re-run the transformer, then we will # need to track the passage of time and run every X hours, where X is # defined by the user. if run_every and run_every > 0: while True: sleeper = run_every * 3600 last_run = int(time.time()) logging.info( 'Sleeping for {}s before next iteration'.format(sleeper)) time.sleep(sleeper) logging.info( 'Initiating ingest with observed_since={}'.format(last_run)) ingest.ingest(last_run, batch_size, threads)
def scan(access_key, secret_key, scanner, name, targets, template, audit_files, credentials, delete=False): tio = TenableIO(access_key, secret_key) compliance = upload_audits(tio, audit_files) credentials = get_creds(tio, credentials) print('[+] Creating scan') scan = tio.scans.create(name=name, template=template, targets=targets, scanner=scanner, credentials=credentials, compliance=compliance) print(json.dumps(scan, indent=2)) print('[+] Launching scan') tio.scans.launch(scan['id']) if wait_for_scan(tio, scan['id']) == 'completed': print(f'[+] Exporting scan') with open(f'{name}.nessus', 'wb') as reportobj: tio.scans.export(scan['id'], fobj=reportobj) print(f' saved to {name}.nessus') print_results(f'{name}.nessus') else: print('[!] ERROR: scan not completed. Exiting') exit(-1) if delete: print('[+] Deleting scan') tio.scans.delete(scan['id'])
def main(req: func.HttpRequest) -> func.HttpResponse: logging.info('Azure Function was triggered by HTTP request.') # Initiate the Tenable.io API model, the Ingester model, and start the # ingestion and data transformation. tio = TenableIO( tio_access_key, tio_secret_key, vendor='Tenable', product='Azure Security Center', build=__version__) asc = AzureSecurityCenter( azure_tenant_id, azure_app_id, azure_app_secret, auth_url=auth_uri, url=azure_uri ) ingest = Tio2ASC(tio, asc, allowed_subs=subscription) ingest.ingest(batch_size=1000) return func.HttpResponse( "This HTTP triggered function executed successfully.", status_code=200 )
def cli(tio_access_key, tio_secret_key, verbose, observed_since, run_every, threads, destination, port, severity): ''' Tenable.io -> CEF Transformer & Ingester ''' # Setup the logging verbosity. if verbose == 0: logging.basicConfig(level=logging.WARNING) if verbose == 1: logging.basicConfig(level=logging.INFO) if verbose > 1: logging.basicConfig(level=logging.DEBUG) # Initiate the Tenable.io API model, the Ingester model, and start the # ingestion and data transformation. tio = TenableIO(access_key=tio_access_key, secret_key=tio_secret_key, vendor='Tenable', product='CEFTransform', build=__version__) cef = CEFSender(destination, port) ingest = TioTransform(tio, cef) ingest.ingest(observed_since, threads, list(severity)) # If we are expected to continually re-run the transformer, then we will # need to track the passage of time and run every X hours, where X is # defined by the user. if run_every and run_every > 0: while True: sleeper = run_every * 3600 last_run = int(time.time()) logging.info( 'Sleeping for {}s before next iteration'.format(sleeper)) time.sleep(sleeper) logging.info( 'Initiating ingest with observed_since={}'.format(last_run)) ingest.ingest(last_run, batch_size, threads)
CYAN = '\033[1;36;48m' BOLD = '\033[1;37;48m' BLUE = '\033[1;34;48m' GREEN = '\033[1;32;48m' YELLOW = '\033[1;33;48m' RED = '\033[1;31;48m' BLACK = '\033[1;30;48m' UNDERLINE = '\033[4;37;48m' END = '\033[1;37;0m' #Getting values for IP address and VPR from command arguments ip = sys.argv[1] vpr = sys.argv[2] tio = TenableIO('WRITE_ACCESS_KEY_HERE', 'WRITE_SECRET_KEY_HERE') mn = [] cv = [] #List of "bad words" to make the exploit search more efficient words = ["Microsoft", "Windows", "Linux", "Apache"] #Function to search the exploit by CVE in Exploitdb def openlink(cve): cve = cve.replace('CVE-', '') url = "https://www.exploit-db.com/search?cve=" + cve webbrowser.open_new_tab(url) #Function to search the exploit by exploit name in Metasploit
def tio(request, vcr): with vcr.use_cassette('tio_login'): return TenableIO()
def call_tenable_io(config, req_common, tio_ope, **kwargs): """ in:scan_name config: config dict req_common: resilient lib RequestCommon tio_ope: operation types: search: search assets with vulnerabilities by IP *or* by severity scan: ask Tenable.io to initiate a scan (for the IP addresses or default targets when omitted) scan_status: check scan status ip_addr: one ore more comma separated ip address(es) severity: comma separated list of Info, Low, Medium, High, Critical combination asset_age: asset age in days to retrieve scan_name: scan name out: results dict state: Success, Failed content: Tenable.io assets (tio_ope = search only) size: number of assets returned (tio_ope = search only) reason: Failed reason (state = Failed only) scan_status: scan status (tio_ope = scan_status only) scan_name: scan name (tio_ope = scan|scan_status only) scan_uuid: scan uuid (tio_ope = scan only) scan_url: scan url for Tenable.io (tio_ope = scan only) """ try: # Get the function parameters: ip_addr = kwargs.get("ip_addr") # text severity = kwargs.get("severity") # text asset_age = kwargs.get("asset_age") # number scan_name = kwargs.get("scan_name") # text tio = TenableIO(access_key=config.get('access_key'), secret_key=config.get('secret_key'), url="https://"+config.get('host_name'), retries=TIO_RETRIES, backoff=TIO_BACKOFF, proxies=req_common.get_proxies()) if tio_ope.lower() == 'search': filters = [] if ip_addr: filters.append('host.target') filters.append('eq') filters.append(ip_addr) if severity: filters.append('severity') filters.append('eq') filters.append(severity) # pprint(filters) resp = tio.workbenches.vuln_assets(filters, filter_type="and", age=asset_age) return { 'state': 'Success', 'content': reformat_assets(config, resp), 'size': len(resp) } elif tio_ope.lower() == 'scan': scan_name = scan_name if scan_name else config.get('default_scan_name') scan_id = get_scan_id_from_name(tio, scan_name) if scan_id > 0: targets = ip_addr.split(',') if ip_addr else None resp = tio.scans.launch(scan_id, targets=targets) # targets is optional return { 'state': 'Success', 'scan_name': scan_name, 'scan_uuid': resp, # uuid 'scan_url': get_tio_scan_url(config, scan_id, resp) } else: return { 'state': 'Failed', 'reason': "Scan id for '{0}' not found".format(scan_name) } elif tio_ope.lower() == 'scan_status': scan_name = scan_name if scan_name else config.get('default_scan_name') scan_id = get_scan_id_from_name(tio, scan_name) if scan_id > 0: resp = tio.scans.status(scan_id) return { 'state': 'Success', 'scan_name': scan_name, 'scan_status': resp } else: return { 'state': 'Failed', 'reason': "Scan id for '{0}' not found".format(scan_name) } else: return { 'state': 'Failed', 'reason': "No operation '{0}' found".format(tio_ope) } except Exception as e: return { 'state': 'Failed', 'reason': e }
#!/usr/bin/env python3 #Disclaimer: This is NOT supported By Tenable! #This script reaches out to Tenable IO and pulls down all of the current IPs of any Agent #Then pushes those IPs into a Static IP address list in Security Center. from tenable.sc import TenableSC from tenable.io import TenableIO sc = TenableSC("") sc.login("", "") tio = TenableIO(access_key='', secret_key='') #Get Agent IPs from Tenable.io def get_ips(): #great an empty list list = [] for agent in tio.agents.list(): ip = agent['ip'] list.append(ip) return list def get_or_create(): #load all of the current asset lists for parsing asset_lists = sc.asset_lists.list() #grab the latest agent IPs from Tenable.io list = get_ips()
import docker from tenable.io import TenableIO import os from tenable.errors import NotFoundError import re tio_access_key = os.environ['TIO_ACCESS_KEY'] tio_secret_key = os.environ['TIO_SECRET_KEY'] # Gather running containers docker_client = docker.from_env() # Check Tenable.io for a previous assessment, and if one doesn't exist then trigger an assessment tio = TenableIO(tio_access_key, tio_secret_key) for i in docker_client.containers.list(): #print("Docker container name: ", i.name) #print("Docker container ID: ", i.id) #print("Docker short container ID: ", i.short_id) print("Docker image tags: ", i.image.tags) print("Docker image ID: ", i.image.id) print("Docker image short ID: ", i.image.short_id) image_id = re.search("sha256:([0-9a-f]{12}).*", i.image.id) if image_id is not None: print("Image ID:", image_id[1]) querystring = {"image_id": image_id[1]} url = "container-security/api/v1/reports/by_image" try: response = tio.get(url, params=querystring) json_response = response.json() print(f"Image risk score: {json_response['risk_score']}")