Files
kube-hunter/kube_hunter/modules/report/plain.py
Yehuda Chikvashvili 0f1739262f Linting Standards (#330)
Fix linting issues with flake8 and black.
Add pre-commit congifuration, update documnetation for it.
Apply linting check in Travis CI.
2020-04-05 05:22:24 +03:00

137 lines
4.8 KiB
Python

from __future__ import print_function
from prettytable import ALL, PrettyTable
from kube_hunter.modules.report.base import BaseReporter
from kube_hunter.modules.report.collector import (
services,
vulnerabilities,
hunters,
services_lock,
vulnerabilities_lock,
)
EVIDENCE_PREVIEW = 40
MAX_TABLE_WIDTH = 20
KB_LINK = "https://github.com/aquasecurity/kube-hunter/tree/master/docs/_kb"
class PlainReporter(BaseReporter):
def get_report(self, *, statistics=None, mapping=None, **kwargs):
"""generates report tables"""
output = ""
with vulnerabilities_lock:
vulnerabilities_len = len(vulnerabilities)
hunters_len = len(hunters.items())
with services_lock:
services_len = len(services)
if services_len:
output += self.nodes_table()
if not mapping:
output += self.services_table()
if vulnerabilities_len:
output += self.vulns_table()
else:
output += "\nNo vulnerabilities were found"
if statistics:
if hunters_len:
output += self.hunters_table()
else:
output += "\nNo hunters were found"
else:
if vulnerabilities_len:
output += self.vulns_table()
output += "\nKube Hunter couldn't find any clusters"
# print("\nKube Hunter couldn't find any clusters. {}".format("Maybe try with --active?" if not config.active else ""))
return output
def nodes_table(self):
nodes_table = PrettyTable(["Type", "Location"], hrules=ALL)
nodes_table.align = "l"
nodes_table.max_width = MAX_TABLE_WIDTH
nodes_table.padding_width = 1
nodes_table.sortby = "Type"
nodes_table.reversesort = True
nodes_table.header_style = "upper"
id_memory = set()
services_lock.acquire()
for service in services:
if service.event_id not in id_memory:
nodes_table.add_row(["Node/Master", service.host])
id_memory.add(service.event_id)
nodes_ret = "\nNodes\n{}\n".format(nodes_table)
services_lock.release()
return nodes_ret
def services_table(self):
services_table = PrettyTable(["Service", "Location", "Description"], hrules=ALL)
services_table.align = "l"
services_table.max_width = MAX_TABLE_WIDTH
services_table.padding_width = 1
services_table.sortby = "Service"
services_table.reversesort = True
services_table.header_style = "upper"
with services_lock:
for service in services:
services_table.add_row(
[service.get_name(), f"{service.host}:{service.port}{service.get_path()}", service.explain()]
)
detected_services_ret = f"\nDetected Services\n{services_table}\n"
return detected_services_ret
def vulns_table(self):
column_names = [
"ID",
"Location",
"Category",
"Vulnerability",
"Description",
"Evidence",
]
vuln_table = PrettyTable(column_names, hrules=ALL)
vuln_table.align = "l"
vuln_table.max_width = MAX_TABLE_WIDTH
vuln_table.sortby = "Category"
vuln_table.reversesort = True
vuln_table.padding_width = 1
vuln_table.header_style = "upper"
with vulnerabilities_lock:
for vuln in vulnerabilities:
evidence = str(vuln.evidence)
if len(evidence) > EVIDENCE_PREVIEW:
evidence = evidence[:EVIDENCE_PREVIEW] + "..."
row = [
vuln.get_vid(),
vuln.location(),
vuln.category.name,
vuln.get_name(),
vuln.explain(),
evidence,
]
vuln_table.add_row(row)
return (
"\nVulnerabilities\n"
"For further information about a vulnerability, search its ID in: \n"
f"{KB_LINK}\n{vuln_table}\n"
)
def hunters_table(self):
column_names = ["Name", "Description", "Vulnerabilities"]
hunters_table = PrettyTable(column_names, hrules=ALL)
hunters_table.align = "l"
hunters_table.max_width = MAX_TABLE_WIDTH
hunters_table.sortby = "Name"
hunters_table.reversesort = True
hunters_table.padding_width = 1
hunters_table.header_style = "upper"
hunter_statistics = self.get_hunter_statistics()
for item in hunter_statistics:
hunters_table.add_row([item.get("name"), item.get("description"), item.get("vulnerabilities")])
return f"\nHunter Statistics\n{hunters_table}\n"