def list_vulnerabilities(smartcheck_host, insecure_skip_tls_verify, smartcheck_user, smartcheck_password): """ :param smartcheck_host: URL of Smart Check Web Interface :param insecure_skip_tls_verify: Ignore invalid certificates :param smartcheck_user: Smart Check console username :param smartcheck_password: Smart Check console user password :return: list of all CVEs for all images for all registries configured in DSSC """ skip = " (skip verify TLS)" if insecure_skip_tls_verify else "" print( f'Connect to {smartcheck_host} using username {smartcheck_user}{skip}') with Smartcheck(base=smartcheck_host, verify=not insecure_skip_tls_verify, user=smartcheck_user, password=smartcheck_password) as session: cves = set() for registry in session.list_registries(): #print(f'Registry: {registry}') print( f'Registry: {registry["name"]} ({registry["host"]}): {registry["description"]}' ) for image in session.list_images(registry['id']): print(f'Image: {image["repository"]}:{image["tag"]}') scan = session.last_scan(image) print(f'Scan: {scan["details"]["completed"]}') for package in session.list_vulnerable_packages(scan): for vulnerability in package['vulnerabilities']: if 'fixed' in vulnerability: continue if 'override' in vulnerability: continue cves.add(vulnerability['name']) return cves
def get_analysis(smartcheck_host, smartcheck_user, smartcheck_password, min_severity, image, show_fixed, show_overridden, insecure_skip_tls_verify=True): result = { "malware": { "name": "Malware found in image", "items": [] }, "content_risk": { "name": "Content secret risk found", "items": [] }, "compliance_check_failures": { "name": "Failed Compliance checklist for image", "items": [] }, "compliance_checklist": { "name": "Display Checklist_compliance of Trend Micro", "pci-dss": { "name": "Trend Micro PCI-DSS v3 Docker Compliance", "items": [] }, "nist800190": { "name": "Trend Micro NIST 800-190 Docker Compliance", "items": [] }, "hipaa": { "name": "Trend Micro HIPAA Docker Compliance", "items": [] } }, "vulnerable_package": { "name": "vulnerable_package list table", "items": [] } } if smartcheck_host is None: print('smartcheck-host is required', file=sys.stderr) sys.exit(1) try: notable_list = sev_list(min_severity) except ValueError: print('unrecognized severity') sys.exit(1) with Smartcheck( base=smartcheck_host, verify=(not insecure_skip_tls_verify), user=smartcheck_user, password=smartcheck_password ) as session: # list_scans(image) will return a generator that will give us all of the # scans for that image if we ask for them. We're only going to ask for one # because we only care about the last scan result. for scan in session.list_scans(image, limit=1): # We only want to print out the header if there are notable vulnerabilities, # which we won't know until later. first = True # list_vulnerable_packages(scan) will return a generator that will give # us all of the vulnerable packages. Each package will have a list of # vulnerabilities. for package_malware in session.list_malware(scan): result['malware']['items'].append({ "name": package_malware['icrc']['name'], "infected_file": package_malware['filename'] }) for package_content in session.list_content_findings(scan): result['content_risk']['items'].append({ "severity": package_content['severity'], "severity content found in image": package_content['metadata']['SubCategory1'], "found at": package_content['filename'], }) for package_checklist in session.list_checklist_findings(scan): if package_checklist['profile']['title'] == "Trend Micro PCI-DSS v3 Docker Compliance": result['compliance_checklist']['pci-dss']["items"].append({ "result_title": package_checklist['result']['title'], "result": package_checklist['result']['result']}) for package_checklist in session.list_checklist_findings(scan): if package_checklist['profile']['title'] == "Trend Micro NIST 800-190 Docker Compliance": result['compliance_checklist']['nist800190']['items'].append({ "result_title": package_checklist['result']['title'], "result": package_checklist['result']['result']}) for package_checklist in session.list_checklist_findings(scan): if package_checklist['profile']['title'] == "Trend Micro HIPAA Docker Compliance": result['compliance_checklist']['hipaa']['items'].append({ "result_title": package_checklist['result']['title'], "result": package_checklist['result']['result']}) for package in session.list_vulnerable_packages(scan): name = package.get('name', "-unknown-") # Now let's go through the vulnerabilities. for vulnerability in package['vulnerabilities']: severity = vulnerability['severity'] # Skip low-severity vulnerabilities unless the user wants them if not severity in notable_list: continue # Don't show vulnerabilities that have been fixed if 'fixed' in vulnerability: if not show_fixed: continue # Only show overridden vulnerabilities if the user has asked for them if 'override' in vulnerability: if not show_overridden: continue cve = vulnerability['name'] link = vulnerability['link'] vector = get_vector('AV:', vulnerability) if vector is not None: # Some sources encode the full vector (for example AV:NETWORK), # others use the abbreviation (AV:N). We'll abbreviate for # consistency. vector = vector[:4] else: vector = '?' # We have a notable vulnerability that we want to display, if # it's the first one we'll add a pretty header if first: first = False result['vulnerable_package']['items'].append({ "name": name, "severity": severity, "venerability": cve, "vector": vector, "link": link }) break return result
def main(): """Mainline""" args = parse_args() if args.smartcheck_host is None: print('smartcheck-host is required', file=sys.stderr) sys.exit(1) try: notable_list = sev_list(args.min_severity) except ValueError: print('unrecognized severity') sys.exit(1) with Smartcheck(base=args.smartcheck_host, verify=(not args.insecure_skip_tls_verify), user=args.smartcheck_user, password=args.smartcheck_password) as session: # list_scans(image) will return a generator that will give us all of the # scans for that image if we ask for them. We're only going to ask for one # because we only care about the last scan result. for scan in session.list_scans(args.image, limit=1): # We only want to print out the header if there are notable vulnerabilities, # which we won't know until later. first = True # list_vulnerable_packages(scan) will return a generator that will give # us all of the vulnerable packages. Each package will have a list of # vulnerabilities. for package in session.list_vulnerable_packages(scan): name = package.get('name', "-unknown-") # Now let's go through the vulnerabilities. for vulnerability in package['vulnerabilities']: severity = vulnerability['severity'] # Skip low-severity vulnerabilities unless the user wants them if not severity in notable_list: continue # Don't show vulnerabilities that have been fixed if 'fixed' in vulnerability: if not args.show_fixed: continue # Only show overridden vulnerabilities if the user has asked for them if 'override' in vulnerability: if not args.show_overridden: continue cve = vulnerability['name'] vector = get_vector('AV:', vulnerability) if vector is not None: # Some sources encode the full vector (for example AV:NETWORK), # others use the abbreviation (AV:N). We'll abbreviate for # consistency. vector = vector[:4] else: vector = '?' # We have a notable vulnerability that we want to display, if # it's the first one we'll add a pretty header if first: print( 'package vector severity vulnerability') print( '--------------- ------ ---------- -------------') first = False print(f'{name:{15}} {vector:{6}} {severity:{10}} {cve}') # Only asking for one scan doesn't mean that the iterator won't happily # ask for the next one, so stop the loop here. break