diff --git a/log/reporter.py b/log/reporter.py index 2a91168..53c28af 100644 --- a/log/reporter.py +++ b/log/reporter.py @@ -1,5 +1,5 @@ import logging -from prettytable import PrettyTable +from prettytable import PrettyTable, ALL from src.core.events import handler from src.core.events.types import Vulnerability, Information, Service @@ -36,14 +36,19 @@ class OpenServiceReport(object): services.append(self.service) def print_results(active): - services_table = PrettyTable(["Service", "Location", "Description"]) + services_table = PrettyTable(["Service", "Location", "Description"], hrules=ALL) + services_table.align="l" + services_table.max_width=60 for service in services: services_table.add_row([service.get_name(), "{}:{}{}".format(service.host, service.port, service.get_path()), service.explain()]) column_names = ["Location", "Category", "Vulnerability", "Description"] if active: column_names.append("Evidence") - vuln_table = PrettyTable(column_names) + vuln_table = PrettyTable(column_names, hrules=ALL) + vuln_table.align="l" + vuln_table.max_width=70 + vuln_table.sortby="Category" for vuln in vulnerabilities: row = ["{}:{}".format(vuln.host, vuln.port), vuln.component.name, vuln.get_name(), vuln.explain()] if active: diff --git a/src/modules/discovery/hosts.py b/src/modules/discovery/hosts.py index e9712eb..486a7ff 100644 --- a/src/modules/discovery/hosts.py +++ b/src/modules/discovery/hosts.py @@ -10,8 +10,15 @@ from netifaces import AF_INET, ifaddresses, interfaces from __main__ import config from ...core.events import handler -from ...core.events.types import Event, NewHostEvent +from ...core.events.types import Event, NewHostEvent, Vulnerability from ...core.types import Hunter +from ..hunting.aks import Azure + +class AzureMetadataApi(Vulnerability, Event): + def __init__(self, cidr): + Vulnerability.__init__(self, Azure, "Azure Metadata Exposure") + self.cidr = cidr + self.evidence = "cidr: {}".format(cidr) class HostScanEvent(Event): def __init__(self, pod=False, active=False, predefined_hosts=list()): @@ -41,6 +48,7 @@ class HostDiscovery(Hunter): if config.pod: if self.is_azure_cluster(): + self.event.azure_cluster = True self.azure_metadata_discovery() else: self.traceroute_discovery() @@ -55,7 +63,7 @@ class HostDiscovery(Hunter): if requests.get("http://169.254.169.254/metadata/instance?api-version=2017-08-01", headers={"Metadata":"true"}).status_code == 200: return True except Exception as ex: - logging.debug("Not azure cluster " + ex.message) + logging.debug("Not azure cluster " + str(ex.message)) return False # for pod scanning @@ -70,10 +78,12 @@ class HostDiscovery(Hunter): # quering azure's interface metadata api | works only from a pod def azure_metadata_discovery(self): machine_metadata = json.loads(requests.get("http://169.254.169.254/metadata/instance?api-version=2017-08-01", headers={"Metadata":"true"}).text) + address, subnet= "", "" for interface in machine_metadata["network"]["interface"]: address, subnet = interface["ipv4"]["subnet"][0]["address"], interface["ipv4"]["subnet"][0]["prefix"] for ip in self.generate_subnet(address, sn=subnet): self.publish_event(NewHostEvent(host=ip)) + self.publish_event(AzureMetadataApi(cidr="{}/{}".format(address, subnet))) # for normal scanning def scan_interfaces(self): diff --git a/src/modules/hunting/aks.py b/src/modules/hunting/aks.py index d1cbd8f..6f5f89e 100644 --- a/src/modules/hunting/aks.py +++ b/src/modules/hunting/aks.py @@ -8,15 +8,15 @@ from kubelet import ExposedRunHandler from ...core.events import handler from ...core.events.types import Event, Vulnerability, KubernetesCluster from ...core.types import Hunter, ActiveHunter - -class AzureSubscription(KubernetesCluster): - """Azure Metadata containes information about user/machines""" - name = "Azure Metadata" + +class Azure(KubernetesCluster): + """Azure Cluster""" + name = "Azure" class AzureSpnExposure(Vulnerability, Event): """By exposing the SPN, the attacker can gain access to the azure subscription""" def __init__(self, container): - Vulnerability.__init__(self, AzureSubscription, "Azure SPN Exposure") + Vulnerability.__init__(self, Azure, "Azure SPN Exposure") self.container = container @handler.subscribe(ExposedRunHandler) diff --git a/src/modules/hunting/kubelet.py b/src/modules/hunting/kubelet.py index 0990732..d54c46b 100644 --- a/src/modules/hunting/kubelet.py +++ b/src/modules/hunting/kubelet.py @@ -197,19 +197,22 @@ class SecureKubeletPortHunter(Hunter): pod = self.get_self_pod() if config.pod else self.get_random_pod() debug_handlers = self.DebugHandlers(self.path, pod=pod, session=self.session) - if debug_handlers.test_container_logs(): - self.publish_event(ExposedContainerLogsHandler()) - if debug_handlers.test_exec_container(): - self.publish_event(ExposedExecHandler()) - if debug_handlers.test_run_container(): - self.publish_event(ExposedRunHandler()) - if debug_handlers.test_running_pods(): - self.publish_event(ExposedRunningPodsHandler()) - if debug_handlers.test_port_forward(): - self.publish_event(ExposedPortForwardHandler()) # not implemented - if debug_handlers.test_attach_container(): - self.publish_event(ExposedAttachHandler()) - + try: + if debug_handlers.test_container_logs(): + self.publish_event(ExposedContainerLogsHandler()) + if debug_handlers.test_exec_container(): + self.publish_event(ExposedExecHandler()) + if debug_handlers.test_run_container(): + self.publish_event(ExposedRunHandler()) + if debug_handlers.test_running_pods(): + self.publish_event(ExposedRunningPodsHandler()) + if debug_handlers.test_port_forward(): + self.publish_event(ExposedPortForwardHandler()) # not implemented + if debug_handlers.test_attach_container(): + self.publish_event(ExposedAttachHandler()) + except Exception as ex: + logging.debug(str(ex.message)) + def get_self_pod(self): return {"name": "kube-hunter", "namespace": "default",