mirror of
https://github.com/aquasecurity/kube-hunter.git
synced 2026-02-14 18:09:56 +00:00
Fix linting issues with flake8 and black. Add pre-commit congifuration, update documnetation for it. Apply linting check in Travis CI.
137 lines
4.8 KiB
Python
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"
|